@sumrco/cli 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/ai/modules/playbook/resources/authoring/folder-structure.rf.md +2 -0
- package/ai/modules/playbook/resources/authoring/frontmatter.rf.md +48 -15
- package/ai/modules/playbook/resources/authoring/lifecycle-hooks.rf.md +110 -0
- package/ai/modules/playbook/resources/authoring/overview.md +25 -2
- package/ai/modules/playbook/resources/team-members/playbook-technical-writer.tm.md +4 -4
- package/index.js +262 -255
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,65 +1,68 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
var
|
|
4
|
-
`)}function
|
|
5
|
-
`),
|
|
6
|
-
`);if(U)
|
|
7
|
-
`){return
|
|
8
|
-
`,"utf8"),
|
|
9
|
-
`)}function
|
|
10
|
-
`):void 0}function
|
|
11
|
-
${$.details}`;return $.details??Q}function
|
|
12
|
-
`),Q,
|
|
13
|
-
`)}function
|
|
14
|
-
`)}function
|
|
15
|
-
`):"export {};";return
|
|
16
|
-
`)}async function $1($){try{return await
|
|
3
|
+
var rW=Object.defineProperty;var oW=($)=>$;function aW($,Q){this[$]=oW.bind(null,Q)}var y2=($,Q)=>{for(var Z in Q)rW($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:aW.bind(Q,Z)})};var v2=($,Q)=>()=>($&&(Q=$($=0)),Q);var B$=import.meta.require;var p0={};y2(p0,{writeSumrYamlTopLevelSection:()=>h1,writeSumrYamlDocument:()=>W0,writeFileAtomically:()=>D5,validateSumrYaml:()=>n_,sumrWarn:()=>_0,sumrTitle:()=>r,sumrText:()=>G0,sumrSuccess:()=>f,sumrStep:()=>f_,sumrSelect:()=>a$,sumrNote:()=>u$,sumrList:()=>d$,sumrIsInteractive:()=>l0,sumrInfo:()=>o$,sumrError:()=>L$,sumrDone:()=>O1,sumrCancel:()=>b8,runModuleCli:()=>m_,renderNamespaceHelp:()=>b5,renderHelp:()=>u1,renderCommandLine:()=>g0,renderCommandHelp:()=>P5,recordActivation:()=>u0,readSumrYamlText:()=>g2,readActivations:()=>N8,parseArgv:()=>h2,mountModule:()=>u2,isActivated:()=>w8,defineModule:()=>K1,defineCommand:()=>T,createSliceValidator:()=>i_,createNamespaceCommand:()=>k5,coreModule:()=>u_,contractCommand:()=>f5,composeSumrYamlSchema:()=>x5,brandText:()=>E,brandSpinnerOptions:()=>V1,brandNoteOptions:()=>P$,brandLogOptions:()=>J$,activationFilePath:()=>R8,SumrYamlEnvelopeSchema:()=>v5,SUMR_YAML_FILENAMES:()=>h0,SUMR_YAML_FILE:()=>H1});import{existsSync as x2,mkdirSync as sW,readFileSync as S5,renameSync as tW,rmSync as eW,writeFileSync as $_}from"fs";import{homedir as Q_}from"os";import{dirname as F5,join as Y0,resolve as Z_}from"path";import{existsSync as I5,readFileSync as X_,renameSync as U_,rmSync as J_,writeFileSync as Y_}from"fs";import{intro as w_,log as d0,note as P8,outro as P_}from"@clack/prompts";import{cancel as l_,isCancel as y5,select as p_,text as c_}from"@clack/prompts";import{z as C5}from"zod";function D5($,Q,Z){let X=`${$}.${process.pid}.${Date.now()}.tmp`;try{Y_(X,Q,Z),U_(X,$)}catch(U){if(I5(X))J_(X,{force:!0});throw U}}function W_($){return $.endsWith(":")?$.slice(0,-1):$}function __($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function G_($){return/^[A-Za-z][A-Za-z0-9_-]*:\s*(?:.*)$/.test($)}function A5($){let Q=[...$];while(Q.at(-1)?.trim()===g1)Q.pop();return Q}function z_($){let Q=[...$];while(Q[0]?.trim()===g1)Q.shift();return Q}function M5($,Q){return $[Q]??g1}function H_($,Q,Z){let X=W_(Q),U=new RegExp(`^${__(X)}:\\s*(?:#.*)?$`),J=$.findIndex((_)=>U.test(_));if(J===-1)return;let Y=Z&&$[J-1]?.trim()===Z?J-1:J,W=$.length;for(let _=J+1;_<$.length;_+=1)if(G_(M5($,_))){W=_;break}while(W>J+1){let _=M5($,W-1).trim();if(_!==g1&&!_.startsWith("#"))break;W-=1}return{start:Y,end:W}}function j5($,Q,Z){let X=[...$];if(X.length>0)X.push(g1);if(X.push(...Q),Z.length>0)X.push(g1,...Z);return X.push(g1),X.join(`
|
|
4
|
+
`)}function V_($,Q,Z,X={}){let U=$.endsWith(`
|
|
5
|
+
`),J=$.split(`
|
|
6
|
+
`);if(U)J.pop();let Y=H_(J,Q,X.sectionComment);if(!Y)return j5(A5(J),Z,[]);return j5(A5(J.slice(0,Y.start)),Z,z_(J.slice(Y.end)))}function g2($,Q=`version: 1
|
|
7
|
+
`){return I5($)?X_($,"utf8"):Q}function W0($,Q){D5($,Q,"utf8")}function h1($,Q,Z,X={}){let U=g2($,X.fallbackContent);W0($,V_(U,Q,Z,X))}function D8($){let Q=Z_($);for(;;){for(let X of h0)if(x2(Y0(Q,X)))return Q;let Z=F5(Q);if(Z===Q)return;Q=Z}}function R8($={}){let Q=$.cwd??process.cwd(),Z=$.home??Q_(),X=D8(Q),U=X?Y0(X,R5):Y0(Z,O_);return Y0(U,K_)}function q_(){return{version:N5,activated:{}}}function B_($){if(typeof $!=="object"||$===null)return!1;let Q=$;return typeof Q.activated==="object"&&Q.activated!==null}function N8($={}){let Q=R8($);return L_(Q)??q_()}function L_($){if(!x2($))return;try{let Q=JSON.parse(S5($,"utf8"));if(!B_(Q))return;return{version:N5,activated:{...Q.activated}}}catch{return}}function A_($,Q={}){let Z=Q.cwd??process.cwd(),X=D8(Z)??Z;return x2(Y0(X,R5,$))}function M_($,Q={}){let Z=Q.cwd??process.cwd(),X=D8(Z);if(!X)return!1;let U=new RegExp(`^${T_($)}\\s*:`,"m");for(let J of h0){let Y=Y0(X,J);if(!x2(Y))continue;try{if(U.test(S5(Y,"utf8")))return!0}catch{return!1}}return!1}function w8($,Q={}){if(N8(Q).activated[$])return!0;return M_($,Q)||A_($,Q)}function u0($,Q={}){let Z=R8(Q),X=N8(Q);return X.activated[$]={at:new Date().toISOString()},j_(Z,X),X}function j_($,Q){let Z=`${$}.sumr-tmp-${Date.now()}`;sW(F5($),{recursive:!0});try{$_(Z,`${JSON.stringify(Q,null,2)}
|
|
8
|
+
`,"utf8"),tW(Z,$)}finally{eW(Z,{force:!0})}}function T_($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function E_($,Q){let Z=$.find((J)=>J.startsWith(`${Q}=`));if(Z)return Z.slice(Q.length+1);let X=$.indexOf(Q);if(X===-1)return;let U=$[X+1];if(!U||U.startsWith("--"))return;return U}function F_($){let Q={};for(let Z=0;Z<$.length;Z+=1){let X=$[Z];if(!X?.startsWith("--"))continue;if(C_.has(X)||S_.has(X))continue;let U=X.indexOf("=");if(U!==-1){let W=X.slice(2,U),_=X.slice(U+1);Q[W]=_;continue}let J=$[Z+1],Y=X.slice(2);if(J&&!J.startsWith("--"))Q[Y]=J,Z+=1;else Q[Y]=!0}return Q}function h2($){let[Q,...Z]=$,X=[];for(let U=0;U<Z.length;U+=1){let J=Z[U];if(!J)continue;if(J.startsWith("--")){if(J==="--profile")U+=1;continue}X.push(J)}return{command:Q,positionals:X,flags:{help:Z.includes("--help")||Z.includes("-h")||Q==="--help",profile:E_(Z,"--profile")},extras:F_(Z)}}function D_($=process.stdout){if(process.env.NO_COLOR)return!1;if(process.env.FORCE_COLOR)return process.env.FORCE_COLOR!=="0";return Boolean($?.isTTY&&process.env.TERM!=="dumb")}function E($,Q,Z=process.stdout){if(!D_(Z))return $;return`${(Array.isArray(Q)?Q:[Q]).map((J)=>T5[J]).join("")}${$}${T5.reset}`}function J$($,Q=process.stdout){let Z=I_[$];return{symbol:E(Z.symbol,Z.tone,Q)}}function P$($="mauve",Q=process.stdout){return{format:(Z)=>E(Z,$,Q)}}function V1($="purple",Q=process.stdout){return{styleFrame:(Z)=>E(Z,$,Q)}}function g0($){return $.trim().split(/\s+/).map((Z,X)=>{if(X===0&&Z==="sumr")return E(Z,R_);if((X===1||X===2)&&!Z.startsWith("-")&&!Z.startsWith("[")&&!Z.startsWith("<"))return E(Z,w5);return Z}).join(" ")}function P5($){let Q=[`${E($.name,[w5,"bold"])} ${E("\xB7","dim")} ${E($.description,"dim")}`,"","Usage:"];for(let Z of $.usage)Q.push(` ${g0(Z)}`);if($.options&&$.options.length>0){Q.push("","Options:");for(let Z of $.options)Q.push(` ${E(Z.flag.padEnd(18),N_)} ${E(Z.description,"dim")}`)}if($.examples&&$.examples.length>0){Q.push("","Examples:");for(let Z of $.examples)Q.push(` ${g0(Z)}`)}return Q.push(""),Q.join(`
|
|
9
|
+
`)}function b_($){let Q=$?.filter((Z)=>Z.value!==void 0&&Z.value!==null&&String(Z.value).length>0).map((Z)=>`${E(`${Z.label}:`,["orchid","bold"])} ${String(Z.value)}`);return Q&&Q.length>0?Q.join(`
|
|
10
|
+
`):void 0}function k_($){let Q=b_($.fields);if($.details&&Q)return`${Q}
|
|
11
|
+
${$.details}`;return $.details??Q}function m0($,Q){let Z=k_($);if(!Z)return;P8(Z,$.title??Q,P$("dim"))}function r($){w_($)}function O1($="Done"){P_($)}function o$($,Q={}){d0.info($,J$("info")),m0(Q,"Details")}function f_($,Q={}){d0.step($,J$("step")),m0(Q,"Details")}function f($,Q={}){d0.success($,J$("success")),m0(Q,"Details")}function _0($,Q={}){d0.warn($,J$("warn")),m0(Q,"Details")}function L$($,Q={}){d0.error($,{...J$("error",process.stderr),output:process.stderr}),m0(Q,"Details")}function u$($,Q="Details",Z="dim"){P8($,Q,P$(Z))}function d$($,Q="Items"){if($.length===0){o$("No items found.");return}P8($.join(`
|
|
12
|
+
`),Q,P$("dim"))}function T($){return{name:$.name,description:$.description,group:$.group,visibility:$.visibility,help:$.help,run:async(Q)=>{if(Q.args.flags.help)return r(`sumr ${$.help.name.split(/\s+/)[0]}`),console.log(P5($.help)),0;return $.execute(Q)}}}function x_($,Q){let Z=$.filter((U)=>Q==="private"||U.visibility==="public"),X=new Map;for(let U of Z){let J=X.get(U.group)??[];J.push(U),X.set(U.group,J)}return[...X.entries()].sort((U,J)=>I8[U[0]].order-I8[J[0]].order).map(([U,J])=>[U,J.sort((Y,W)=>Y.name.localeCompare(W.name))])}function u1($,Q){let Z=["","Options:","",` ${E("--help".padEnd(22),"orchid")} ${E("Show help","dim")}`,""];Z.push("Commands:"),Z.push("");for(let[X,U]of x_($,Q)){let J=I8[X];Z.push(`${E(`${J.label}:`,v_)}`);for(let Y of U)Z.push(` ${E(Y.name.padEnd(18),y_)} ${E(Y.description,"dim")}`);Z.push("")}return Z.push(` ${E("<command> --help Show command help.","dim")}`),Z.push(""),Z.join(`
|
|
13
|
+
`)}function b5($){let Q=[`${E($.name,["pink","bold"])} ${E("\xB7","dim")} ${E($.description,"dim")}`,"","Usage:",` ${g0(`sumr ${$.name} <command>`)}`,"","Options:",` ${E("--help, -h".padEnd(22),"orchid")} ${E("Show help","dim")}`,"","Commands:",""];for(let Z of $.commands)Q.push(` ${E(Z.name.padEnd(18),"pink")} ${E(Z.description,"dim")}`);return Q.push(""),Q.push(` ${g0(`sumr ${$.name} <command> --help`)} ${E("Show command help.","dim")}`),Q.push(""),Q.join(`
|
|
14
|
+
`)}function g_($){return{...$,argv:$.argv.slice(1),args:{...$.args,positionals:$.args.positionals.slice(1)}}}function K1($){return $}function k5($){let Q=new Map($.commands.map((X)=>[X.name,X]));function Z(){return b5({name:$.name,description:$.description,commands:$.commands})}return{name:$.name,description:$.description,group:$.group,visibility:$.visibility,run:async(X)=>{let[U]=X.args.positionals;if(!U)return r(`sumr ${$.name}`),console.log(Z()),0;let J=Q.get(U);if(!J)return r(`sumr ${$.name}`),L$(`Unknown ${$.unknownSubcommandLabel??$.name} command: ${U}`),console.log(Z()),1;return J.run(g_(X))}}}function u2($){return k5({name:$.name,description:$.description,group:$.group,visibility:$.visibility,commands:$.commands})}function d_($,Q){let[Z]=$;if(!Z)return[...$];if(Z===Q.name)return[...$];if(Z==="--help"||Z==="-h"||Z==="--version"||Z==="-v")return[...$];if(new Set(Q.commands.map((U)=>U.name)).has(Z))return[Q.name,...$];return[...$]}function E5($,Q,Z){r(`sumr ${$.name}`),console.log(u1(Q,Z))}async function m_($){let Q=$.visibility??$.module.visibility,Z=[u2($.module)],X=d_($.argv,$.module),U=h2(X),J=new Map(Z.map((W)=>[W.name,W]));if(!U.command||U.command==="--help"||U.command==="-h")return E5($.module,Z,Q),0;if(U.command==="--version"||U.command==="-v"){if($.version)console.log($.version);else E5($.module,Z,Q);return 0}let Y=J.get(U.command);if(!Y)return r(`sumr ${$.module.name}`),L$(`Unknown command: ${U.command}`),console.log(u1(Z,Q)),1;try{return await Y.run({argv:X,args:U,visibility:Q})}catch(W){let _=W instanceof Error?W.message:"Unexpected error.";return r(`sumr ${$.module.name}`),L$(_),1}}function l0(){return Boolean(process.stdin.isTTY&&process.stdout.isTTY)}async function a$($){let Q=await p_({message:$.message,options:$.options,initialValue:$.initialValue});if(y5(Q)){b8();return}return Q}async function G0($){let Q=await c_($);if(y5(Q)){b8();return}return Q}function b8($="Cancelled."){l_($)}function x5($){return v5.extend(Object.fromEntries(Object.entries($).map(([Q,Z])=>[Q,Z.optional()]))).passthrough()}function n_($,Q){let X=x5(Q).safeParse($);if(X.success)return{ok:!0,value:X.data};return{ok:!1,issues:X.error.issues.map((J)=>{return`${J.path.length>0?J.path.join("."):"(root)"}: ${J.message}`})}}function i_($){return(Q)=>{let Z=$.safeParse(Q);if(Z.success)return{ok:!0,value:Z.data};return{ok:!1,issues:Z.error.issues.map((U)=>{return`${U.path.length>0?U.path.join("."):"(root)"}: ${U.message}`})}}}var g1="",H1="sumr.yaml",h0,O_=".sumr",R5=".sumr-cache",K_="activations.json",N5=1,C_,S_,T5,I_,R_="purple",w5="pink",N_="orchid",y_="pink",v_="orchid",I8,h_="1.0.0",f5,u_,v5;var D=v2(()=>{h0=["sumr.yaml","sumr.yml"];C_=new Set(["--profile"]),S_=new Set(["--help","-h","--version","-v"]);T5={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",purple:"\x1B[38;2;123;64;149m",pink:"\x1B[38;2;196;91;151m",orchid:"\x1B[38;2;161;100;182m",mauve:"\x1B[38;2;137;104;156m",soft:"\x1B[38;2;96;75;112m",orange:"\x1B[38;2;245;156;88m"},I_={info:{symbol:"\u25C8",tone:"purple"},success:{symbol:"\u25C6",tone:"pink"},warn:{symbol:"\u25B2",tone:"orchid"},error:{symbol:"\u25A0",tone:"pink"},step:{symbol:"\u25CF",tone:"purple"}};I8={auth:{label:"Sign-in",order:1},identity:{label:"Accounts",order:2},system:{label:"Environment",order:3},modules:{label:"Modules",order:4},internal:{label:"Development",order:5}};f5=T({name:"contract",description:"Print the Core contract version",group:"internal",visibility:"private",help:{name:"core contract",description:"Print the Core contract version",usage:["sumr core contract"]},execute:async()=>{return console.log(h_),0}}),u_=K1({name:"core",description:"Shared SUMR CLI command contracts and UX helpers",group:"internal",visibility:"private",commands:[f5]});v5=C5.object({version:C5.number().int().positive()}).passthrough()});var zU={};y2(zU,{kontractModule:()=>JB});import{cpus as C4}from"os";import{Buffer as c4}from"buffer";import{randomUUID as n4}from"crypto";import{access as i4,mkdir as r4,readdir as o4,rename as a4,stat as s4}from"fs/promises";import{join as Q$}from"path";import{mkdtemp as Jz,rm as Yz}from"fs/promises";import{tmpdir as Wz}from"os";import{join as e8}from"path";import{dirname as Oz,isAbsolute as Kz,join as B9,relative as L9,resolve as H6}from"path";import{mkdir as Az,readdir as Mz,stat as jz}from"fs/promises";import{dirname as M9,join as b7,relative as Tz,resolve as T1}from"path";import{access as Pz,readFile as bz}from"fs/promises";import{dirname as E1,join as o7,relative as a7,resolve as O6}from"path";import{log as H0}from"@clack/prompts";import{join as J3}from"path";import{bundle as Y3,loadConfig as W3}from"@redocly/openapi-core";import{stringify as _3}from"yaml";import{basename as S3,join as F3,relative as XX}from"path";import{camelCase as x3,constantCase as g3,kebabCase as S6,pascalCase as Z1}from"change-case";import{jsonSchemaToZod as UH}from"json-schema-to-zod";import{join as a8}from"path";import VH from"@asyncapi/parser/browser";import{log as OH}from"@clack/prompts";import{pascalCase as BX}from"change-case";import{pascalCase as MX}from"change-case";import{pascalCase as nZ}from"change-case";import{pascalCase as q6}from"change-case";import{pascalCase as NX}from"change-case";import{camelCase as eV}from"change-case";import{access as dX,readdir as y9,rm as Y2}from"fs/promises";import{basename as _O,join as Z$}from"path";import GO from"@apidevtools/swagger-parser";import{log as W2}from"@clack/prompts";import{camelCase as f6,constantCase as FO,pascalCase as x9,snakeCase as g9}from"change-case";import{pascalCase as d9}from"change-case";import{pascalCase as n9}from"change-case";import{camelCase as rO,pascalCase as B1}from"change-case";import{basename as JK,join as sX}from"path";import YK from"@apidevtools/swagger-parser";import{log as tX}from"@clack/prompts";import{mkdir as W9,rm as QU}from"fs/promises";import{join as e$,resolve as $7}from"path";import{mkdir as hK,rm as XU,stat as uK}from"fs/promises";import{join as _9,resolve as dK}from"path";import{basename as zq,resolve as Hq}from"path";import Vq from"@apidevtools/swagger-parser";import{log as X6}from"@clack/prompts";import{existsSync as X7,mkdirSync as Iq,readFileSync as Dq,writeFileSync as Rq,writeSync as Nq}from"fs";import{dirname as wq,join as U7}from"path";import{existsSync as kq,readFileSync as fq}from"fs";import{join as yq}from"path";import{parse as vq}from"yaml";function E4($,Q){this[$]=T4.bind(null,Q)}async function d4($,Q,Z,X){try{if(await Q($))X.successCount+=1;else X.failedCount+=1}catch(U){X.failedCount+=1,X.errors.push(U instanceof Error?U:Error(String(U)))}finally{Z.done=!0}}async function t8($,Q,Z){let X=Number.isFinite(Z)&&Z>0?Math.floor(Z):1,U={successCount:0,failedCount:0,errors:[]},J=[];for(let Y of $){let W={done:!1,promise:Promise.resolve()};if(W.promise=d4(Y,Q,W,U),J.push(W),J.length>=X)await Promise.race(J.map((_)=>_.promise)),J=J.filter((_)=>!_.done)}return await Promise.all(J.map((Y)=>Y.promise)),{success:U.successCount,failed:U.failedCount,errors:U.errors}}function m4($){let Q=J6;return J6=$,()=>{J6=Q}}function V9(){return J6}function k($,Q=1){let Z=V9();if(!Z)return;Z.counters.set($,(Z.counters.get($)??0)+Q)}async function H$($,Q){let Z=performance.now();try{return await Q()}finally{l4($,performance.now()-Z)}}function l4($,Q){let Z=V9();if(!Z)return;Z.phaseDurationsMs.set($,(Z.phaseDurationsMs.get($)??0)+Q),Z.phaseCounts.set($,(Z.phaseCounts.get($)??0)+1)}function p4($){let Q=V9();if(!Q)return;Q.subprocesses.push($)}function vZ($){if(typeof $==="bigint")return Number($);return $}function O9($){p4({name:$.name,command:$.command.join(" "),durationMs:$.durationMs,exitCode:$.exitCode,maxRSS:$.resourceUsage?.maxRSS,cpuUserUs:vZ($.resourceUsage?.cpuTime?.user),cpuSystemUs:vZ($.resourceUsage?.cpuTime?.system)})}function t4($,Q){if(!$.endsWith(".ts"))return Q;if(Q.includes(T7))return Q;return`${E7}${Q}`}async function e4($,Q){let Z=Q$($,"..");await r4(Z,{recursive:!0});let X=Q$(Z,`.${n4()}.tmp`);await Bun.write(X,Q),await a4(X,$)}async function W$($,Q){let Z=t4($,Q);try{let X=await s4($),U=c4.byteLength(Z,"utf8");if(X.mtimeMs>0&&X.size===U){let Y=await Bun.file($).text();if(Bun.hash(Y)===Bun.hash(Z))return k("write.skipped"),!1}}catch{}return await e4($,Z),k("write.changed"),!0}async function L0($,Q){let Z=Q.length>0?Q.map((X)=>`export * from '${X}';`).join(`
|
|
15
|
+
`):"export {};";return W$(Q$($,"index.ts"),`${Z}
|
|
16
|
+
`)}async function $1($){try{return await i4($),!0}catch{return!1}}async function $z($){let Q=[],Z=Q$($,"http","index.ts"),X=Q$($,"nats","index.ts");if(await $1(Z))Q.push("export * as HttpSchemas from './http';");if(await $1(X))Q.push("export * as NatsSchemas from './nats';");if(Q.length===0)return!1;return W$(Q$($,"index.ts"),`${Q.join(`
|
|
17
17
|
`)}
|
|
18
|
-
`)}async function
|
|
18
|
+
`)}async function Qz($){let Q=Q$($,j7),Z=Q$(Q,"runtime.ts"),X=Q$(Q,"http","index.ts"),U=Q$(Q,"nats","index.ts"),J=[];if(await $1(X))J.push("export * as HttpSchemas from './http';");if(await $1(U))J.push("export * as NatsSchemas from './nats';");if(await $1(Z))J.push("export * from './runtime';");if(J.length===0)return!1;return W$(Q$(Q,"index.ts"),`${J.join(`
|
|
19
19
|
`)}
|
|
20
|
-
`)}function
|
|
20
|
+
`)}function Zz($,Q){let Z=$.replace(/[^A-Za-z0-9_$]/g,"_");if(Z.length===0)Z="_module";if(/^[0-9]/.test(Z))Z=`_${Z}`;let X=Z,U=2;while(Q.has(X))X=`${Z}_${U}`,U+=1;return Q.add(X),X}async function Xz($){return I7($)}async function Uz($){return await $1(Q$($,"http","index.ts"))||await $1(Q$($,"nats","index.ts"))}async function I7($){if(!await $1($))return!1;if(await Uz($))return!1;let Z=(await o4($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()&&!Y.name.startsWith(".")).map((Y)=>Y.name).sort((Y,W)=>Y.localeCompare(W)),X=new Set,U=[],J=!1;for(let Y of Z){let W=Q$($,Y);J=await I7(W)||J;let _=Q$(W,"index.ts");if(!await $1(_))continue;let G=Zz(Y,X);U.push(`export * as ${G} from './${Y}';`)}if(U.length===0)return J;return await W$(Q$($,"index.ts"),`${U.join(`
|
|
21
21
|
`)}
|
|
22
|
-
`)||
|
|
23
|
-
`)}async function
|
|
24
|
-
`).trim();return
|
|
25
|
-
`),{configPath:Q,cleanup:()=>
|
|
26
|
-
`)}}finally{await Z()}}async function
|
|
27
|
-
`),k("manifest.writes")}async function
|
|
28
|
-
`)}}function
|
|
29
|
-
Use zod >=3.25.76 or >=4.0.0, or disable generator.zod for this target.`}}function
|
|
30
|
-
`).map((
|
|
31
|
-
`):void 0}}function
|
|
32
|
-
`).trim()}async function
|
|
33
|
-
${
|
|
34
|
-
`).trim();return{success:!1,error:Error(`Bundle failed (exit ${$}): ${X}`)}}async function
|
|
35
|
-
`).map((Q)=>Q.trim()).filter((Q)=>Q.length>0)}function
|
|
22
|
+
`)||J}function D7(){return Bun.which(PZ)??e8(process.cwd(),"node_modules",".bin",PZ)}function K9($,Q){return $.length>0?$:`biome format failed with code ${Q}`}function _z($){return $.includes("No files were processed")&&$.includes("provided but ignored")}function Gz($,Q,Z){return[`Could not format generated TypeScript for ${Z}.`,K9($,Q)].join(`
|
|
23
|
+
`)}async function q9($,Q="file.ts"){let Z=[D7(),"format","--stdin-file-path","file.ts"],X=performance.now(),U=Bun.spawn(Z,{stdin:new TextEncoder().encode($),stdout:"pipe",stderr:"pipe",env:{...process.env}}),J=await U.exited,Y=U.resourceUsage(),W=(await new Response(U.stderr).text()).trim();if(O9({name:"biome.formatFile",command:Z,durationMs:performance.now()-X,exitCode:J,resourceUsage:Y}),k("format.fileSubprocesses"),J!==0)throw Error(Gz(W,J,Q));let _=await new Response(U.stdout).text();if(_.length===0)throw Error("biome format returned empty stdout");return _}async function R7($,Q,Z){let X=[D7(),"format","--write",...Q,$],U=performance.now(),J=Bun.spawn(X,{cwd:process.cwd(),stdout:"pipe",stderr:"pipe",env:{...process.env}}),Y=await J.exited,W=J.resourceUsage(),_=(await new Response(J.stdout).text()).trim(),G=(await new Response(J.stderr).text()).trim(),z=[_,G].filter(Boolean).join(`
|
|
24
|
+
`).trim();return O9({name:Z,command:X,durationMs:performance.now()-U,exitCode:Y,resourceUsage:W}),k("format.directorySubprocesses"),{details:z,exitCode:Y}}async function zz(){let $=await Jz(e8(Wz(),"kontract-biome-")),Q=e8($,"biome.json");return await Bun.write(Q,`${JSON.stringify(N7,null,2)}
|
|
25
|
+
`),{configPath:Q,cleanup:()=>Yz($,{recursive:!0,force:!0})}}async function Hz($){let{configPath:Q,cleanup:Z}=await zz();try{k("format.directoryConfigFallbacks");let{details:X,exitCode:U}=await R7($,["--config-path",Q],"biome.formatDirectoryIsolated");if(U!==0)return{success:!1,details:K9(X,U)};return{success:!0,details:["Consumer Biome config ignored the generated directory; formatted with Kontract isolated config.",X].filter((J)=>J.length>0).join(`
|
|
26
|
+
`)}}finally{await Z()}}async function Vz($){let{details:Q,exitCode:Z}=await R7($,["--vcs-enabled=false"],"biome.formatDirectory");if(Z!==0){if(_z(Q))return Hz($);return{success:!1,details:K9(Q,Z)}}return{success:!0,details:Q.length>0?Q:void 0}}function w7($){let Q=L9(process.cwd(),$);if(Q.length===0)return".";if(Q.startsWith(".."))return $;return Q.startsWith(".")?Q:`./${Q}`}function E6($,Q){let Z=L9($,Q);return Z.length===0||!Z.startsWith("..")&&!Kz(Z)}function qz($){let Q=H6($[0]??process.cwd()),Z=$.map((X)=>H6(X));while(!Z.every((X)=>E6(Q,X))){let X=Oz(Q);if(X===Q)return Q;Q=X}return Q}function Bz($){let Q=process.env[S4]?.trim();if(Q)return H6(Q);let Z=H6(process.cwd()),X=$.flatMap((J)=>[J.inputDir,J.outputDir]),U=X.every((J)=>E6(Z,J))?Z:qz(X);return B9(U,G7)}function K0($){let Q=$.replace(/[^A-Za-z0-9._-]/g,"_").replace(/^_+|_+$/g,"");return Q.length>0?Q:"unnamed"}function $9($){return`${K0($)}.${k4}`}function C6($,Q){return B9($,z7,"bundles",K0(Q.sourceName),K0(Q.targetName))}function P7($,Q){return B9($,z7,"bundles",K0(Q),D4)}function Lz($,Q){let Z=L9($,Q).replace(/\\/g,"/").replace(/\.ts$/,"");return Z.startsWith(".")?Z:`./${Z}`}function j9($){return $ instanceof Error&&"code"in $&&$.code==="ENOENT"}function k7($){let Q=new Bun.CryptoHasher("sha256");return Q.update($),`${Nz}${Q.digest("hex")}`}function f7($){return k7($)}function V6($){if($===null||typeof $!=="object")return JSON.stringify($);if(Array.isArray($))return`[${$.map((X)=>V6(X)).join(",")}]`;return`{${Object.entries($).sort(([X],[U])=>X.localeCompare(U)).map(([X,U])=>`${JSON.stringify(X)}:${V6(U)}`).join(",")}}`}async function y7($){try{let Q=await jz($);return Q.isFile()?{size:Q.size}:null}catch(Q){if(!j9(Q))throw Q;return null}}async function T9($,Q){let Z=T1($),X=await y7(Z);if(!X)throw Error(`Cannot hash missing file '${Z}'`);let U=await Bun.file(Z).bytes();return{path:Tz(Q,Z).replace(/\\/g,"/"),hash:k7(U),size:X.size}}function E9($){return f7(V6($))}async function v7($){let Q;try{Q=await Mz($,{withFileTypes:!0})}catch(X){if(j9(X))return[];throw X}let Z=[];for(let X of Q){if(X.name.startsWith("."))continue;let U=b7($,X.name);if(X.isDirectory()){Z.push(...await v7(U));continue}if(X.isFile()&&X.name.endsWith(".ts"))Z.push(U)}return Z.sort((X,U)=>X.localeCompare(U))}function Ez($){let Q=$.map((J)=>T1(J)),[Z]=Q;if(!Z)return process.cwd();let X=Z.split(/[\\/]+/),U=X.length;for(let J of Q.slice(1)){let Y=J.split(/[\\/]+/);U=Math.min(U,Y.length);for(let W=0;W<U;W+=1){if(Y[W]===X[W])continue;U=W;break}}return X.slice(0,Math.max(U,1)).join("/")||"/"}async function Cz($){let Q=[];for(let Z of $)if(await y7(Z))Q.push(T1(Z));return[...new Set(Q)].sort((Z,X)=>Z.localeCompare(X))}function Sz($){let Q=[],Z=null;while(!0){if(Z=c7.exec($),!Z)break;let X=Z[1];if(!X||X.startsWith("#"))continue;Q.push(X.split("#")[0]??X)}return Q}function Fz($){return/\$ref\s*:\s*$/m.test($)||/\$ref\s*:\s*[|>]/.test($)}async function x7($,Q,Z){let X=T1($);if(Q.has(X))return[];Q.add(X);let U=await Bun.file(X).text();if(Fz(U))Z.unsafe=!0;let J=[X];for(let Y of Sz(U)){if(/^[a-z][a-z0-9+.-]*:/i.test(Y)){Z.unsafe=!0;continue}J.push(...await x7(T1(M9(X),Y),Q,Z))}return J}async function g7(){if(s0)return s0;try{let $=await Bun.file(n7).json();s0=typeof $.version==="string"?$.version:kZ}catch{s0=kZ}return s0}async function h7($){return H$("manifest.sourceHash",async()=>{let Q={unsafe:!1},Z=[],X=new Set;for(let W of $)Z.push(...await x7(W,X,Q));let U=await Cz(Z),J=M9(T1($[0]??process.cwd())),Y=await Promise.all(U.map((W)=>T9(W,J)));return{files:Y.sort((W,_)=>W.path.localeCompare(_.path)),hash:E9(Y),safe:!Q.unsafe}})}async function u7($,Q=[]){return H$("manifest.outputHash",async()=>{let Z=[$,...Q].map((G)=>T1(G)),[X]=Z,U=Z.length===1&&X?X:Ez(Z),J=await Promise.all(Z.map((G)=>v7(G))),Y=[...new Set(J.flat())].sort((G,z)=>G.localeCompare(z)),_=(await Promise.all(Y.map((G)=>T9(G,U)))).sort((G,z)=>G.path.localeCompare(z.path));return{files:_,hash:E9(_)}})}function d7($){return f7(V6({channel:$.channel,generator:$.generator,serviceName:$.serviceName,sourceName:$.sourceName,targetName:$.targetName}))}async function m7(){if(Q6)return Q6;let $=[];for(let X of i7){let U=new Bun.Glob(X);for await(let J of U.scan({cwd:process.cwd()}))$.push(T1(process.cwd(),J))}let Q=[...new Set($)].sort((X,U)=>X.localeCompare(U)),Z=await Promise.all(Q.map((X)=>T9(X,process.cwd())));return Q6=E9(Z.sort((X,U)=>X.path.localeCompare(U.path))),Q6}function l7($,Q,Z){let X=Z.split("/").map((U)=>K0(U));return b7($,F4,Q,...X,"manifest.json")}function Iz($){if(typeof $!=="object"||$===null)return!1;let Q=$;return Q.version===H7&&typeof Q.sourceDependencyHash==="string"&&typeof Q.outputTreeHash==="string"&&typeof Q.generatorConfigHash==="string"&&typeof Q.generatorImplementationHash==="string"}async function Dz($){try{return await Bun.file($).text()}catch(Q){if(j9(Q))return null;throw Q}}async function p7($){if(k("manifest.checks"),!$.source.safe)return k("manifest.unsafeSource"),{skipped:!1,reason:"unsafe-source-dependencies",source:$.source};let Q=await Dz($.manifestPath);if(!Q)return{skipped:!1,reason:"missing-manifest",source:$.source};let Z;try{Z=JSON.parse(Q)}catch{return{skipped:!1,reason:"invalid-manifest-json",source:$.source}}if(!Iz(Z))return{skipped:!1,reason:"invalid-manifest-shape",source:$.source};let[X,U,J]=await Promise.all([g7(),m7(),u7($.outputDir,$.additionalOutputDirs)]),Y=d7($);if(!(Z.packageVersion===X&&Z.bunVersion===Bun.version&&Z.sourceDependencyHash===$.source.hash&&Z.outputTreeHash===J.hash&&Z.generatorConfigHash===Y&&Z.generatorImplementationHash===U))return{skipped:!1,reason:"manifest-hash-mismatch",source:$.source};return k("manifest.skips"),{skipped:!0,reason:"manifest-hit",source:$.source}}async function Rz($){if(!$.source.safe)return;let[Q,Z,X]=await Promise.all([g7(),m7(),u7($.outputDir,$.additionalOutputDirs)]),U={version:H7,packageVersion:Q,bunVersion:Bun.version,sourceName:$.sourceName,targetName:$.targetName,serviceName:$.serviceName,channel:$.channel,generatorConfigHash:d7($),generatorImplementationHash:Z,sourceDependencyHash:$.source.hash,outputTreeHash:X.hash,sourceFiles:$.source.files,outputFiles:X.files,generatedAt:new Date().toISOString()};await Az(M9($.manifestPath),{recursive:!0}),await Bun.write($.manifestPath,`${JSON.stringify(U,null,2)}
|
|
27
|
+
`),k("manifest.writes")}async function kz($){let Q=O6($);while(!0){let Z=o7(Q,"package.json");try{return await Pz(Z),Z}catch{}let X=E1(Q);if(X===Q)return null;Q=X}}async function fz($){let Q=[$.outputDir,$.inputDir,$.cwd];for(let Z of Q){let X=await kz(Z);if(X)return{target:await s7(X),workspaceRoot:await mz(E1(X))}}return null}async function s7($){let Q=await bz($,"utf8");return{path:$,shape:xz(JSON.parse(Q),$)}}function t7($){return{dependencies:new Set(Object.keys($.dependencies??{})),devDependencies:new Set(Object.keys($.devDependencies??{})),peerDependencies:new Set(Object.keys($.peerDependencies??{})),dependencyVersions:new Map(Object.entries($.dependencies??{}))}}function K6($){if(!$||typeof $!=="object"||Array.isArray($))return!1;return!0}function yz($){if(!K6($))return!1;return Object.values($).every((Q)=>typeof Q==="string")}function r8($,Q,Z){let X=$[Q];if(X===void 0)return;if(yz(X))return X;throw Error(`${Z}.${Q} must be an object with string version ranges`)}function vz($,Q){let Z=$.workspaces;if(Z===void 0)return;if(Array.isArray(Z)&&Z.every((X)=>typeof X==="string"))return Z;if(K6(Z)&&Z.packages===void 0)return{};if(K6(Z)&&Array.isArray(Z.packages)&&Z.packages.every((X)=>typeof X==="string"))return{packages:Z.packages};throw Error(`${Q}.workspaces must be an array of strings or packages object`)}function xz($,Q){if(!K6($))throw Error(`${Q} must contain a JSON object`);return{name:typeof $.name==="string"?$.name:void 0,dependencies:r8($,"dependencies",Q),devDependencies:r8($,"devDependencies",Q),peerDependencies:r8($,"peerDependencies",Q),workspaces:vz($,Q)}}function c1($,Q){let Z=a7(Q,$);if(!Z||Z.startsWith(".."))return $;return Z.startsWith(".")?Z:`./${Z}`}function gz($,Q){let Z=c1(E1($),Q);return Z==="./"?".":Z}function hz($,Q,Z){let X=[...Z].sort(),U=E1($),J=O6(Q);if(O6(U)===J)return`bun add ${X.join(" ")}`;return`cd ${gz($,Q)} && bun add ${X.join(" ")}`}function e7($){if(Array.isArray($))return $;return $?.packages??[]}function uz($,Q){if($===Q)return!0;if($.endsWith("/*"))return E1(Q)===$.slice(0,-2);return!1}function dz($,Q){if(!$||$.path===Q)return!1;let Z=a7(E1($.path),E1(Q));if(!Z||Z.startsWith(".."))return!1;return e7($.shape.workspaces).some((X)=>uz(X,Z))}async function mz($){let Q=O6($);while(!0){let Z=o7(Q,"package.json");try{let U=await s7(Z);if(e7(U.shape.workspaces).length>0)return U}catch{}let X=E1(Q);if(X===Q)return;Q=X}}function lz($){let Q=new Set;for(let Z of $){if(Z.type===N.TypeScriptNestJs)Q.add("nestjs-zod"),Q.add("zod");if(Z.type===N.AsyncApiNats)Q.add("rxjs"),Q.add("zod");if(Z.type===N.TypeScriptAxios)Q.add("axios");if(Z.type===N.TypeScriptAngular)Q.add("@angular/common"),Q.add("@angular/core"),Q.add("rxjs")}return Q}function pz($){return $.some((Q)=>Q.type===N.TypeScriptNestJs)}function cz($){let Q=$.match(/(\d+)\.(\d+)\.(\d+)/);if(!Q)return!0;let Z=Number(Q[1]),X=Number(Q[2]);if(Z>=4)return!0;if(Z!==3||X!==25)return!1;return Number(Q[3])>=76}function nz($,Q,Z){if(!Z)return[];let X=t7(Z.shape);return $.filter((U)=>!Q.dependencies.has(U)&&(X.dependencies.has(U)||X.devDependencies.has(U)||X.peerDependencies.has(U)))}function iz($,Q,Z,X){if(!Z||!dz(Z,$))return[];let U=[`Checked package: ${c1($,Q.cwd)}`,`Generated output: ${c1(Q.outputDir,Q.cwd)}`,`Workspace root: ${c1(Z.path,Q.cwd)}`];if(X.length>0)U.push(`Root declares ${[...X].sort().join(", ")}, but generated code belongs to this workspace package.`);return U}async function rz($,Q){try{let Z=await fz($);if(Z)return{ok:!0,resolution:Z}}catch(Z){return{ok:!1,warnings:[{title:"Cannot parse package.json for dependency checks.",details:Z instanceof Error?Z.message:String(Z)}]}}return{ok:!1,warnings:[{title:"Cannot verify generated contract runtime dependencies (package.json not found).",details:`Expected runtime deps: ${[...Q].sort().join(", ")}`}]}}function oz($,Q){let Z=[],X=[];for(let U of $){if(Q.dependencies.has(U))continue;if(Q.devDependencies.has(U)||Q.peerDependencies.has(U)){X.push(U);continue}Z.push(U)}return{missing:Z,wrongScope:X}}function az($,Q,Z,X){if(X.length===0)return;let U=Q.target.path,J=nz(X,Z,Q.workspaceRoot),Y=iz(U,$,Q.workspaceRoot,J);return{title:`Missing runtime deps for generated contracts in ${c1(U,$.cwd)}.`,details:[`Missing: ${[...X].sort().join(", ")}`,...Y,`Install: ${hz(U,$.cwd,X)}`].join(`
|
|
28
|
+
`)}}function sz($,Q,Z){if(Z.length===0)return;return{title:`Generated contract deps should be in dependencies in ${c1(Q,$)}.`,details:`Move to dependencies: ${[...Z].sort().join(", ")}`}}function tz($,Q,Z){let X=Z.dependencyVersions.get("zod");if(!pz($.generators)||!Z.dependencies.has("zod")||typeof X!=="string"||cz(X))return;return{title:`Generated OpenAPI Zod schemas require a zod/v4-compatible zod version in ${c1(Q,$.cwd)}.`,details:`Detected zod: ${X}
|
|
29
|
+
Use zod >=3.25.76 or >=4.0.0, or disable generator.zod for this target.`}}function ez($,Q,Z){let X=Q.target.path,U=t7(Q.target.shape),{missing:J,wrongScope:Y}=oz(Z,U);return[az($,Q,U,J),sz($.cwd,X,Y),tz($,X,U)].filter((W)=>W!==void 0)}async function $3($){let Q=lz($.generators);if(Q.size===0)return[];let Z=await rz($,Q);if(!Z.ok)return Z.warnings;return ez($,Z.resolution,Q)}function Z3($,Q){let Z=Q.split(`
|
|
30
|
+
`).map((J)=>J.trim()).filter((J)=>J.length>0),[X="Unexpected error",...U]=Z;return{title:`\u274C ${$}: ${X}`,details:U.length>0?U.join(`
|
|
31
|
+
`):void 0}}function X3($,Q){return{printStep:(Y)=>{if($)return;if(Q){Q.log.step(Y,J$("step"));return}H0.step(Y)},printInfo:(Y)=>{if($)return;if(Q){Q.log.info(Y,J$("info"));return}H0.info(Y)},printWarning:(Y,W)=>{if($)return;if(Q){if(Q.log.warn(Y,J$("warn")),W)Q.note(W,"Details",P$("dim"));return}if(H0.warn(Y),W)H0.warn(W)},printFailure:(Y)=>{if(!$&&Q){if(Q.log.error(Y.title,{...J$("error"),symbol:"\u274C"}),Y.details)Q.note(Y.details,"Details",P$("dim"));return}if(H0.error(Y.title),Y.details)H0.error(Y.details)}}}function G3($){return $.includes("Failed to link")&&$.includes("EEXIST")}function z3($){return new Promise((Q)=>{setTimeout(Q,$)})}async function H3($){let Q=Q9,Z=()=>{};Q9=new Promise((X)=>{Z=X}),await Q;try{return await $()}finally{Z()}}async function V3($,Q){let Z=performance.now(),X=Bun.spawn($,{stdout:"pipe",stderr:"pipe",env:{...process.env}}),U=await X.exited,J=X.resourceUsage(),Y=await new Response(X.stdout).text(),W=await new Response(X.stderr).text();return O9({name:Q,command:$,durationMs:performance.now()-Z,exitCode:U,resourceUsage:J}),k("bundle.subprocesses"),{exitCode:U,stdout:Y,stderr:W}}async function O3($,Q){let Z=$.indexOf("--output");if(Z===-1||Z+1>=$.length)return{success:!1,error:Error("Bundle args must include '--output <path>'")};let X=$[Z+1];if(!X)return{success:!1,error:Error("Bundle output path is missing")};return $X(X,Q)}async function $X($,Q){if(!(await Bun.file($).text()).includes(Q))return{success:!1,error:Error(`Bundle output missing '${Q}' marker`)};return{success:!0,outputPath:$}}function K3(){return gZ??=W3(),gZ}function q3(){return process.env[y4]!=="1"}function B3($){if($ instanceof Error)return $;return Error(String($))}function L3($){return $.map((Q)=>`${Q.severity}: ${Q.message}`).join(`
|
|
32
|
+
`).trim()}async function A3($,Q){try{let Z=await Y3({ref:$,config:await K3()}),X=Z.problems.filter((J)=>J.severity==="error");if(X.length>0)return{success:!1,error:Error(`OpenAPI bundle failed:
|
|
33
|
+
${L3(X)}`)};let U=Z.bundle.parsed;if(U===void 0)return{success:!1,error:Error("OpenAPI bundle produced an empty document")};if(await Bun.write(Q,_3(U)),k("bundle.inProcess"),Z.problems.length>X.length)k("bundle.warnings",Z.problems.length-X.length);return $X(Q,A7)}catch(Z){return{success:!1,error:B3(Z)}}}function M3($,Q,Z){let X=[Q,Z].filter((U)=>U.trim().length>0).join(`
|
|
34
|
+
`).trim();return{success:!1,error:Error(`Bundle failed (exit ${$}): ${X}`)}}async function QX($,Q,Z){let X=$[0]==="bunx";for(let U=0;U<=xZ;U+=1){let J=()=>V3($,Z),{exitCode:Y,stdout:W,stderr:_}=X?await H3(J):await J();if(Y===0)return O3($,Q);if(!(X&&G3(_))||U>=xZ)return M3(Y,W,_);await z3(E3*(U+1))}return{success:!1,error:Error("Bundle failed unexpectedly")}}async function j3($,Q){let Z=Bun.which("redocly");if(Z)return[Z,"bundle",$,"--output",Q];let X=J3(process.cwd(),"node_modules",".bin","redocly");if(await Bun.file(X).exists())return[X,"bundle",$,"--output",Q];return["bunx",f4,"bundle",$,"--output",Q]}async function ZX($,Q){if($.length!==1)return{success:!1,error:Error("OpenAPI bundling expects a single root spec file")};let Z=$[0];if(!Z)return{success:!1,error:Error("OpenAPI root spec file is missing")};if(q3())return A3(Z,Q);return QX(await j3(Z,Q),A7,"bundle.openapi")}async function T3($,Q){return QX(["bunx","@asyncapi/cli","bundle",...$,"--output",Q],g4,"bundle.asyncapi")}async function UX($,Q){let Z=[],X=new Bun.Glob(Q);for await(let U of X.scan({cwd:$}))Z.push(F3($,U));return Z.sort()}function I3($,Q){let X=XX($,Q).split("/"),U=S3(Q);if(!/\.openapi\.ya?ml$/.test(U))return null;if(X.length===1)return{name:U.replace(/\.openapi\.ya?ml$/,""),rootFile:Q};let J=X.map((z)=>z.replace(/\.openapi\.ya?ml$/,"")),Y=J.at(-1),W=J.at(-2);if(!Y)return null;let G=(Y===W?J.slice(0,-1):J).filter(Boolean).join("/");return G.length>0?{name:G,rootFile:Q}:null}function D3($,Q){let Z=new Map;for(let X of Q){let U=I3($,X);if(!U)continue;let J=Z.get(U.name);if(J)throw Error(`Multiple OpenAPI roots found for service '${U.name}': ${J} and ${U.rootFile}`);Z.set(U.name,U.rootFile)}return[...Z.entries()].map(([X,U])=>({name:X,rootFile:U})).sort((X,U)=>X.name.localeCompare(U.name))}function R3($,Q){let Z=new Map;for(let X of Q){let J=XX($,X).split("/"),Y=J[0];if(!Y)continue;let W=J.length===1?Y.replace(/\.asyncapi\.ya?ml$/,""):Y,_=Z.get(W)??[];Z.set(W,[..._,X])}return[...Z.entries()].map(([X,U])=>({name:X,files:U.sort()})).sort((X,U)=>X.name.localeCompare(U.name))}async function JX($){return D3($,await UX($,P4))}async function YX($){return R3($,await UX($,b4))}function V$($){let Q=Z1($);return Q.endsWith("Message")?Q:`${Q}Message`}function F6($){let Q=Z1($);return`${Q.endsWith("Message")?Q.slice(0,-7):Q}MessageInput`}function A0($){return g3($)}function o1($){let Q=Z1($);return Q.endsWith("Dto")?Q:`${Q}Dto`}function zX($){let Q=Z1($);return Q.endsWith("Schema")?Q:`${Q}Schema`}function C9($){return`${S6($)}.dto.ts`}function C1($){return Z1($)}function I6($){return`${S6($)}.ts`}function HX($){return`${S6($)}.contract.ts`}function S9($){return`${S6($)}.enum.ts`}function Q2($){return`${Z1($)}Values`}function D6($){return`${Z1($)}Map`}function VX($){return Z1(String($))}function h3($){return Z1($)}function Z2($){return x3($)}function d3($){return $.trim().replace(/\.+$/,"")}function m3($){return $.trim().replace(/^\.+/,"")}function l3($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function p3($){let Q=$?.trim();if(!Q)throw Error("AsyncAPI channel address is required");return Q}function X1($,Q){if(!$)return"";if(!Q||Q.trim().length===0)return $;let Z=d3(Q),X=m3($);if(!Z)return X;if(!X)return Z;if(X===Z)return X;if(X.startsWith(`${Z}.`))return X;return`${Z}.${X}`}function F9($,Q,Z,X){let U=X1(p3($),X),J=U.match(/\{(.*?)\}/g);if(!J)return U;return J.reduce((Y,W)=>{let _=W.slice(1,-1),G=l3(Z?.properties)?Z.properties:{};if(!Object.hasOwn(G,_))throw Error(`Param '${_}' not found in message schema for address '${U}'`);return Y.replace(W,`\${${Q}.${_}}`)},U)}function c3($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function I9($,Q){if(c3($))return $;throw Error(`${Q} metadata must be a JSON object`)}function OX($,Q){if($===void 0||$===null)return;return I9($,Q)}function hZ($,Q){let Z=$[Q];if(typeof Z!=="string")return;let X=Z.trim();return X.length>0?X:void 0}function l$($){return $.split(`
|
|
35
|
+
`).map((Q)=>Q.trim()).filter((Q)=>Q.length>0)}function n3($){return $.replaceAll("*/","*\\/")}function M$($){let Q=$.map((X)=>X.trim()).filter((X)=>X.length>0);if(Q.length===0)return"";return["/**",Q.map((X)=>` * ${n3(X)}`).join(`
|
|
36
36
|
`)," */"].join(`
|
|
37
|
-
`)}function
|
|
37
|
+
`)}function X2($,Q=2){if(!$)return"";let Z=" ".repeat(Q);return $.split(`
|
|
38
38
|
`).map((X)=>`${Z}${X}`).join(`
|
|
39
|
-
`)}function
|
|
39
|
+
`)}function KX($){return $.replace(/\{[^}]+\}/g,"*")}function F1($){let Q=$.channels().all();if(Q.length!==1)throw Error(`Operation '${$.id()}' must have exactly one channel`);let Z=$.messages().all();if(Z.length!==1)throw Error(`Operation '${$.id()}' must have exactly one message`);let X=Q[0],U=Z[0];if(!X||!U)throw Error(`Operation '${$.id()}' channel/message metadata is incomplete`);let J=$.reply(),Y=J?.messages()??J?.channel()?.messages(),W=Y&&Y.length>0?Y[0]:null,_=$.id();if(!_)throw Error("Operation has no id");let G=X.address();if(!G||G.trim().length===0)throw Error(`Operation '${_}' channel address is required`);let z=U.id();if(!z)throw Error(`Message in operation '${_}' has no id`);let H=I9($.json(),`Operation '${_}'`),V=hZ(H,"summary")??null,O=hZ(H,"description")??null;return{operationId:_,address:G,msgId:z,payloadSchema:OX(U.payload()?.json(),`Message '${z}' payload`),replyMsgId:W?.id()??null,summary:V,description:O}}function i3($,Q){let Z=new Map;for(let X of $.operations().all()){let{address:U,msgId:J,replyMsgId:Y}=F1(X),W=X1(U,Q),_=V$(J),G=X.isSend()?"void":Y?V$(Y):"CommandReturnType",z=Z.get(W);if(!z){Z.set(W,{address:W,requestType:_,responseType:G});continue}let H=z.requestType===_?z.requestType:`${z.requestType} | ${_}`,V=z.responseType===G?z.responseType:`${z.responseType} | ${G}`;Z.set(W,{address:W,requestType:H,responseType:V})}return Z}function r3($){return $.replaceAll("'","\\'")}function uZ($){if(typeof $!=="string")return null;let Q=$.trim().toLowerCase();if(Q==="command"||Q==="cmd")return O$.Command;if(Q==="query"||Q==="qry")return O$.Query;if(Q==="event"||Q==="evt")return O$.Event;return null}function o3($){let Q=$.trim().toLowerCase();if(Q.includes(".cmd.")||Q.includes(".command."))return O$.Command;if(Q.includes(".qry.")||Q.includes(".query."))return O$.Query;if(Q.includes(".evt.")||Q.includes(".event."))return O$.Event;return null}function R6($,Q){let{operationId:Z,address:X}=F1($),U=X1(X,Q),J=I9($.json(),`Operation '${Z}'`),W=$.channels().all()[0],_=OX(W?.json(),`Operation '${Z}' channel`),G=uZ(J["x-sumr-intent"])??uZ(_?.["x-sumr-intent"]);if(G)return G;let z=o3(U);if(z)return z;if($.isSend())return O$.Event;if($.isReceive()&&$.reply())return O$.Query;if($.isReceive())return O$.Command;throw Error(`Cannot infer operation intent for '${Z}'. Add x-sumr-intent or use an address segment like '.cmd.' or '.qry.'.`)}function a3($,Q){let X=$.operations().all().map((Y)=>{let{operationId:W,address:_}=F1(Y),G=X1(_,Q);return{operationId:W,key:A0(W),address:G}}).map((Y)=>[` /** ${Y.operationId} */`,` ${Y.key}: '${Y.address}',`].join(`
|
|
40
40
|
`)).join(`
|
|
41
|
-
`)
|
|
41
|
+
`),U=M$(["NATS subjects for server handlers and client publish/send calls.","Named placeholders (for example {organizationId}) are preserved for client interpolation."]),J=M$(["Semantic aliases for NestJS controller decorators and event publishers."]);return[`${U}
|
|
42
42
|
export const SUBJECTS = {
|
|
43
43
|
${X}
|
|
44
|
-
} as const
|
|
44
|
+
} as const;`,[J,"export const SUBSCRIBE_ROUTES = SUBJECTS;","export const PUBLISH_ADDRESSES = SUBJECTS;"].join(`
|
|
45
|
+
`)].join(`
|
|
46
|
+
|
|
47
|
+
`)}function s3($,Q){let Z=i3($,Q);if(Z.size===0)return"";let X=[...Z.values()].map((J)=>[` '${r3(J.address)}': {`,` request: ${J.requestType};`,` response: ${J.responseType};`," };"].join(`
|
|
45
48
|
`)).join(`
|
|
46
|
-
`);return`${
|
|
49
|
+
`);return`${M$(["Route contracts used to strongly type client proxy send/emit calls."])}
|
|
47
50
|
export interface ClientRouteContracts {
|
|
48
51
|
${X}
|
|
49
|
-
}`}function
|
|
52
|
+
}`}function t3($,Q){let Z=$.operations().all().filter((J)=>J.isReceive()&&R6(J,Q)===O$.Command);if(Z.length===0)return"";let X=Z.map((J)=>{let{operationId:Y,address:W,msgId:_,replyMsgId:G,summary:z,description:H}=F1(J),V=Z2(Y),O=X1(W,Q),K=KX(O),q=G?V$(G):"CommandReturnType",B=[];if(z)B.push(...l$(z));if(H)B.push(...l$(H));B.push(`@subscribeRoute ${K}`),B.push(`@publishAddress ${O}`),B.push(`@param msg ${V$(_)}`),B.push(`@returns Promise<${q}>`);let S=M$(B);return[X2(S),` ${V}(msg: ${V$(_)}, ctx: IMsgContext): Promise<${q}>;`].filter(Boolean).join(`
|
|
50
53
|
`)}).join(`
|
|
51
|
-
`);return`${
|
|
54
|
+
`);return`${M$(["Server contract for command handlers."])}
|
|
52
55
|
export interface ICommandServer {
|
|
53
56
|
${X}
|
|
54
|
-
}`}function
|
|
57
|
+
}`}function e3($,Q){let Z=$.operations().all().filter((J)=>J.isReceive()&&R6(J,Q)===O$.Query);if(Z.length===0)return"";let X=Z.map((J)=>{let{operationId:Y,address:W,msgId:_,replyMsgId:G,summary:z,description:H}=F1(J),V=Z2(Y),O=X1(W,Q),K=KX(O),q=G?V$(G):"unknown",B=[];if(z)B.push(...l$(z));if(H)B.push(...l$(H));B.push(`@subscribeRoute ${K}`),B.push(`@publishAddress ${O}`),B.push(`@param msg ${V$(_)}`),B.push(`@returns Promise<${q}>`);let S=M$(B);return[X2(S),` ${V}(msg: ${V$(_)}, ctx: IMsgContext): Promise<${q}>;`].filter(Boolean).join(`
|
|
55
58
|
`)}).join(`
|
|
56
|
-
`);return`${
|
|
59
|
+
`);return`${M$(["Server contract for query handlers (receive operations with reply)."])}
|
|
57
60
|
export interface IQueryServer {
|
|
58
61
|
${X}
|
|
59
|
-
}`}function
|
|
62
|
+
}`}function $H($,Q){let Z=$.operations().all().filter((J)=>J.isReceive()&&R6(J,Q)===O$.Command);if(Z.length===0)return"";let X=Z.map((J)=>{let{operationId:Y,address:W,msgId:_,payloadSchema:G,replyMsgId:z,summary:H,description:V}=F1(J),O=F9(W,"msg",G,Q),K=F6(_),q=V$(_),B=Z2(Y),S=A0(Y),M=X1(W,Q),R=M.includes("{"),w=R?`\`${O}\``:`SUBJECTS.${S}`,P=z?V$(z):"CommandReturnType",l=R?`this.proxy.send<${P}, ${q}>(${w}, validated, ctx);`:`this.proxy.send(${w}, validated, ctx);`,v=[];if(H)v.push(...l$(H));if(V)v.push(...l$(V));v.push(`@publishAddress ${M}`),v.push(`@param msg ${K}`),v.push(`@returns Observable<${P}>`);let C$=M$(v);return[X2(C$),` ${B}(msg: ${K}, ctx?: IMsgContext): Observable<${P}> {`,` const validated = ${q}.parse(msg);`,` return ${l}`," }"].filter(Boolean).join(`
|
|
60
63
|
`)}).join(`
|
|
61
64
|
|
|
62
|
-
`);return`${
|
|
65
|
+
`);return`${M$(["Client helper for command request/reply interactions."])}
|
|
63
66
|
export class CommandClient {
|
|
64
67
|
private readonly proxy: IClientProxy<ClientRouteContracts>;
|
|
65
68
|
|
|
@@ -68,10 +71,10 @@ export class CommandClient {
|
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
${X}
|
|
71
|
-
}`}function
|
|
74
|
+
}`}function QH($,Q){let Z=$.operations().all().filter((J)=>J.isReceive()&&R6(J,Q)===O$.Query);if(Z.length===0)return"";let X=Z.map((J)=>{let{operationId:Y,address:W,msgId:_,payloadSchema:G,replyMsgId:z,summary:H,description:V}=F1(J),O=F9(W,"msg",G,Q),K=F6(_),q=V$(_),B=Z2(Y),S=z?V$(z):"unknown",M=A0(Y),R=X1(W,Q),w=R.includes("{"),P=w?`\`${O}\``:`SUBJECTS.${M}`,l=w?`this.proxy.send<${S}, ${q}>(${P}, validated, ctx);`:`this.proxy.send(${P}, validated, ctx);`,v=[];if(H)v.push(...l$(H));if(V)v.push(...l$(V));v.push(`@publishAddress ${R}`),v.push(`@param msg ${K}`),v.push(`@returns Observable<${S}>`);let C$=M$(v);return[X2(C$),` ${B}(msg: ${K}, ctx?: IMsgContext): Observable<${S}> {`,` const validated = ${q}.parse(msg);`,` return ${l}`," }"].filter(Boolean).join(`
|
|
72
75
|
`)}).join(`
|
|
73
76
|
|
|
74
|
-
`);return`${
|
|
77
|
+
`);return`${M$(["Client helper for query request/reply interactions."])}
|
|
75
78
|
export class QueryClient {
|
|
76
79
|
private readonly proxy: IClientProxy<ClientRouteContracts>;
|
|
77
80
|
|
|
@@ -80,10 +83,10 @@ export class QueryClient {
|
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
${X}
|
|
83
|
-
}`}function
|
|
86
|
+
}`}function ZH($,Q){let Z=$.operations().all().filter((J)=>J.isSend());if(Z.length===0)return"";let X=Z.map((J)=>{let{operationId:Y,address:W,msgId:_,payloadSchema:G,summary:z,description:H}=F1(J),V=F9(W,"msg",G,Q),O=F6(_),K=V$(_),q=Z2(Y),B=A0(Y),S=X1(W,Q),M=S.includes("{"),R=M?`\`${V}\``:`SUBJECTS.${B}`,w=M?`this.proxy.emit<void, ${K}>(${R}, validated, ctx);`:`this.proxy.emit(${R}, validated, ctx);`,P=[];if(z)P.push(...l$(z));if(H)P.push(...l$(H));P.push(`@publishAddress ${S}`),P.push(`@param msg ${O}`),P.push("@returns Observable<void>");let l=M$(P);return[X2(l),` ${q}(msg: ${O}, ctx?: IMsgContext): Observable<void> {`,` const validated = ${K}.parse(msg);`,` return ${w}`," }"].filter(Boolean).join(`
|
|
84
87
|
`)}).join(`
|
|
85
88
|
|
|
86
|
-
`);return`${
|
|
89
|
+
`);return`${M$(["Client helper for fire-and-forget event publishing."])}
|
|
87
90
|
export class EventClient {
|
|
88
91
|
private readonly proxy: IClientProxy<ClientRouteContracts>;
|
|
89
92
|
|
|
@@ -92,100 +95,100 @@ export class EventClient {
|
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
${X}
|
|
95
|
-
}`}function
|
|
98
|
+
}`}function JH($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function dZ($,Q){if(JH($))return $;throw Error(`${Q} metadata must be a JSON object`)}function YH($,Q){try{return UH(Q,{module:"none"})}catch(Z){let X=Z instanceof Error?Z.message:String(Z);throw Error(`Failed to convert AsyncAPI message '${$}' payload to Zod: ${X}`)}}function o8($,Q){let Z=$[Q];if(typeof Z!=="string")return;let X=Z.trim();return X.length>0?X:void 0}function WH($){return $.replaceAll("*/","*\\/")}function _H($){let Q=$.map((X)=>X.trim()).filter((X)=>X.length>0);if(Q.length===0)return"";return["/**",Q.map((X)=>` * ${WH(X)}`).join(`
|
|
96
99
|
`)," */"].join(`
|
|
97
|
-
`)}function
|
|
98
|
-
`)}function
|
|
100
|
+
`)}function GH($){let Q=$.id();if(!Q)throw Error("AsyncAPI message is missing an id");let Z=$.payload();if(!Z)throw Error(`AsyncAPI message '${Q}' is missing a payload schema`);let X=dZ(Z.json(),`AsyncAPI message '${Q}' payload`),U=YH(Q,X),J=V$(Q),Y=F6(Q),W=dZ($.json(),`AsyncAPI message '${Q}'`),_=o8(W,"summary"),G=o8(W,"description")??o8(X,"description");return[_H([..._?[_]:[],...G?[G]:[],`Runtime schema for ${J}.`]),`export const ${J} = ${U};`,`export type ${J} = z.infer<typeof ${J}>;`,`export type ${Y} = z.input<typeof ${J}>;`].filter(Boolean).join(`
|
|
101
|
+
`)}function zH($){return $.map((Q)=>GH(Q)).filter(Boolean).join(`
|
|
99
102
|
|
|
100
|
-
`)}async function
|
|
103
|
+
`)}async function mZ($,Q,Z){return Z?q9($,Q):$}function q1($){return $.split(`
|
|
101
104
|
`).map((Q)=>Q?` ${Q}`:"").join(`
|
|
102
|
-
`)}function
|
|
103
|
-
`),
|
|
104
|
-
`)Q+="\\n";else if(X==="\u2028")Q+="\\u2028";else if(X==="\u2029")Q+="\\u2029";else Q+=X}return`/${Q}/`}function
|
|
105
|
-
${
|
|
105
|
+
`)}function KH($){return $.endsWith("Schema")?$:`${$}Schema`}function qH($){return $.message}async function BH($,Q,Z,X){let U=$.replace(/\.asyncapi\.ya?ml$/,"").split("/").pop()??$;try{let J=new VH,Y=a8(Q,"nats"),W=a8(Y,h4),_=X?.sharedTypesImportPath??"./shared",G=X?.sharedTypesOutputFile??a8(Y,u4),z=X?.formatFiles!==!1,H=await Bun.file($).text(),{document:V,diagnostics:O}=await J.parse(H);if(!V){let f2=O.map(qH).join(", ");throw Error(`AsyncAPI parse failed: ${f2}`)}let K=h3(V.info().title()),q=KH(K),B=`${A0(K)}_NATS_CLIENT`,S=V.components().messages().all(),R=["import { z } from 'zod';","import { Observable } from 'rxjs';",`import { CommandReturnType, IClientProxy, IMsgContext, IRawClientProxy, createRouteTypedClientProxy } from '${_}';`,"",`export const ${B} = '${B}';`,"",`export namespace ${q} {`,q1(zH(S)),"",q1(a3(V,X?.addressPrefix)),"",q1(s3(V,X?.addressPrefix)),"",q1(t3(V,X?.addressPrefix)),"",q1(e3(V,X?.addressPrefix)),"",q1($H(V,X?.addressPrefix)),"",q1(QH(V,X?.addressPrefix)),"",q1(ZH(V,X?.addressPrefix)),"}"].join(`
|
|
106
|
+
`),w=await mZ(R,W,z),P=await mZ(GX,G,z),l=await W$(W,w),v=await W$(G,P),C$=l||v;if(Z&&C$)OH.step(` \u2713 ${W}`);return{success:!0,service:U,changed:C$}}catch(J){return{success:!1,service:U,error:J instanceof Error?J:Error(String(J))}}}function Z9($){return`'${$.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}'`}function AH($,Q){let Z=0;for(let X=Q-1;X>=0&&$[X]==="\\";X-=1)Z+=1;return Z%2===1}function MH($){let Q="";for(let Z=0;Z<$.length;Z+=1){let X=$[Z];if(X==="/"&&!AH($,Z))Q+="\\/";else if(X==="\r")Q+="\\r";else if(X===`
|
|
107
|
+
`)Q+="\\n";else if(X==="\u2028")Q+="\\u2028";else if(X==="\u2029")Q+="\\u2029";else Q+=X}return`/${Q}/`}function qX($,Q){return Q?`${$}.describe(${Z9(Q)})`:$}function jH($){let Q=$.map((Z)=>typeof Z==="string"?Z9(Z):`z.literal(${Z})`);if($.every((Z)=>typeof Z==="string"))return`z.enum([${$.map((Z)=>Z9(String(Z))).join(", ")}])`;return`z.union([${Q.join(", ")}])`}function TH($){if($.scalar==="boolean")return"z.boolean()";if($.scalar==="integer")return lZ($,!0);if($.scalar==="number")return lZ($,!1);let Q="z.string()";if($.format==="uuid")Q+=".uuid()";if($.format==="email")Q+=".email()";if($.format==="uri"||$.format==="url")Q+=".url()";if($.format==="date-time")Q+=".datetime()";if($.minLength!==void 0)Q+=`.min(${$.minLength})`;if($.maxLength!==void 0)Q+=`.max(${$.maxLength})`;if($.pattern)Q+=`.regex(${MH($.pattern)})`;return Q}function lZ($,Q){let Z=Q?"z.number().int()":"z.number()";if($.minimum!==void 0)Z+=`.min(${$.minimum})`;if($.maximum!==void 0)Z+=`.max(${$.maximum})`;return Z}function l1($,Q){if($.kind==="scalar")return TH($);if($.kind==="enum")return jH($.values);if($.kind==="array")return`z.array(${l1($.items,Q)})`;if($.kind==="unknown")return"z.unknown()";if($.kind==="object"){let J=Object.entries($.properties);if(J.length===0&&$.additionalProperties)return`z.record(z.string(), ${l1($.additionalProperties,Q)})`;if(J.length===0)return"z.record(z.string(), z.unknown())";let W=`z.object({
|
|
108
|
+
${J.map(([_,G])=>{let z=qX(l1(G,Q),G.description);if(!$.required.includes(_))z+=".optional()";return` ${_}: ${z},`}).join(`
|
|
106
109
|
`)}
|
|
107
|
-
})`;return $.additionalProperties?`${
|
|
108
|
-
${$.properties.map((
|
|
110
|
+
})`;return $.additionalProperties?`${W}.catchall(${l1($.additionalProperties,Q)})`:W}let Z=zX($.refName),X=`./${HX($.refName).replace(/\.ts$/,"")}`,U=Q.get(X)??new Set;return U.add(Z),Q.set(X,U),Z}function EH($,Q){let Z=l1($.schema,Q);if($.nullable)Z+=".nullable()";if($.optional)Z+=".optional()";return Z=qX(Z,$.description??$.schema.description),` ${$.name}: ${Z},`}function CH($){let Q=new Map,Z=zX($.schemaName),X=o1($.schemaName),U=C1($.schemaName),J=$.properties.length>0?`z.object({
|
|
111
|
+
${$.properties.map((G)=>EH(G,Q)).join(`
|
|
109
112
|
`)}
|
|
110
|
-
})`:null,
|
|
111
|
-
`),"",`export const ${Z} = ${
|
|
112
|
-
`)}function
|
|
113
|
-
`)}function
|
|
114
|
-
`)}function
|
|
113
|
+
})`:null,Y=$.schema?.kind==="object"?$.schema.additionalProperties:void 0,W=J?Y?`${J}.catchall(${l1(Y,Q)})`:J:l1($.schema??{kind:"object",properties:{},required:[]},Q),_=["import { createZodDto } from 'nestjs-zod';","import { z } from 'zod';"];for(let[G,z]of[...Q.entries()].sort((H,V)=>H[0].localeCompare(V[0])))_.push(`import { ${[...z].sort().join(", ")} } from '${G}';`);return[_.join(`
|
|
114
|
+
`),"",`export const ${Z} = ${W};`,"",`export class ${X} extends createZodDto(${Z}) {}`,`export type ${U} = z.infer<typeof ${Z}>;`,""].join(`
|
|
115
|
+
`)}function N6($){return`'${$.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}'`}function j1($,Q){let Z=[];if($.optional)Q.validatorImports.add("IsOptional"),Z.push("@IsOptional()");else if($.nullable)Q.validatorImports.add("ValidateIf"),Z.push("@ValidateIf((_, value) => value !== null)");return Z}function FH($,Q,Z,X){if($==="uuid")X.validatorImports.add("IsUUID"),Z.push("@IsUUID()");else if($==="email")X.validatorImports.add("IsEmail"),Z.push("@IsEmail()");else if($==="uri"||$==="url")X.validatorImports.add("IsUrl"),Z.push("@IsUrl()");else if($==="date"||$==="date-time")X.validatorImports.add("IsDateString"),Z.push("@IsDateString()");if(typeof Q.minLength==="number")X.validatorImports.add("MinLength"),Z.push(`@MinLength(${Q.minLength})`);if(typeof Q.maxLength==="number")X.validatorImports.add("MaxLength"),Z.push(`@MaxLength(${Q.maxLength})`);if(typeof Q.pattern==="string")X.validatorImports.add("Matches"),Z.push(`@Matches(new RegExp(${N6(Q.pattern)}))`)}function D9($,Q,Z,X={}){let U=X.each?", { each: true }":"";if(typeof $.minimum==="number")Z.validatorImports.add("Min"),Q.push(`@Min(${$.minimum}${U})`);if(typeof $.maximum==="number")Z.validatorImports.add("Max"),Q.push(`@Max(${$.maximum}${U})`);let J=$.exclusiveMinimum,Y=typeof $.minimum==="number"?$.minimum:void 0,W=J===!0&&(Y??0)>=0,_=typeof J==="number"&&J>=0;if(W||_)Z.validatorImports.add("IsPositive"),Q.push(`@IsPositive(${X.each?"{ each: true }":""})`)}function IH($,Q,Z){Z.validatorImports.add("IsString"),Q.push("@IsString()");let X=typeof $.format==="string"?$.format:void 0;FH(X,$,Q,Z)}function DH($,Q,Z,X){if($)X.transformerImports.add("Type"),Z.push("@Type(() => Number)");X.validatorImports.add("IsNumber"),Z.push("@IsNumber()"),D9(Q,Z,X)}function RH($,Q,Z,X){if($)X.transformerImports.add("Type"),Z.push("@Type(() => Number)");X.validatorImports.add("IsInt"),Z.push("@IsInt()"),D9(Q,Z,X)}function NH($,Q,Z){if($)Z.transformerImports.add("Transform"),Q.push("@Transform(({ value }) => value === 'true' ? true : value === 'false' ? false : value)");Z.validatorImports.add("IsBoolean"),Q.push("@IsBoolean()")}function wH($,Q,Z,X){let U=j1($,X),J=$.source==="path"||$.source==="query";if(Q==="string")return IH(Z,U,X),U;if(Q==="number")return DH(J,Z,U,X),U;if(Q==="integer")return RH(J,Z,U,X),U;return NH(J,U,X),U}function PH($,Q,Z,X){let U=[];if(Q.format)U.push(`format: '${Q.format}'`);if(Q.minLength!==void 0)U.push(`minLength: ${Q.minLength}`);if(Q.maxLength!==void 0)U.push(`maxLength: ${Q.maxLength}`);if(Q.minimum!==void 0)U.push(`minimum: ${Q.minimum}`);if(Q.maximum!==void 0)U.push(`maximum: ${Q.maximum}`);if(Q.pattern)U.push(`pattern: ${N6(Q.pattern)}`);if($.nullable)U.push("nullable: true");let J=wH($,Q.scalar,{format:Q.format,minLength:Q.minLength,maxLength:Q.maxLength,minimum:Q.minimum,maximum:Q.maximum,exclusiveMinimum:Q.exclusiveMinimum,exclusiveMaximum:Q.exclusiveMaximum,pattern:Q.pattern},Z);return X(Z,$,U,J,$.optional),{typeName:Q.scalar==="integer"?"number":Q.scalar,decorators:J}}function bH($,Q,Z){if($.format==="uuid"){Z.validatorImports.add("IsUUID"),Q.push("@IsUUID('4', { each: true })");return}if($.format==="email"){Z.validatorImports.add("IsEmail"),Q.push("@IsEmail(undefined, { each: true })");return}if($.format==="uri"||$.format==="url"){Z.validatorImports.add("IsUrl"),Q.push("@IsUrl(undefined, { each: true })");return}if($.format==="date"||$.format==="date-time")Z.validatorImports.add("IsDateString"),Q.push("@IsDateString({}, { each: true })")}function kH($,Q,Z){if($.minLength!==void 0)Z.validatorImports.add("MinLength"),Q.push(`@MinLength(${$.minLength}, { each: true })`);if($.maxLength!==void 0)Z.validatorImports.add("MaxLength"),Q.push(`@MaxLength(${$.maxLength}, { each: true })`);if($.pattern)Z.validatorImports.add("Matches"),Q.push(`@Matches(new RegExp(${N6($.pattern)}), { each: true })`)}function fH($,Q,Z){Z.validatorImports.add("IsString"),Q.push("@IsString({ each: true })"),bH($,Q,Z),kH($,Q,Z)}function yH($,Q,Z){if($.scalar==="integer"){Z.validatorImports.add("IsInt"),Q.push("@IsInt({ each: true })");return}if($.scalar==="number"){Z.validatorImports.add("IsNumber"),Q.push("@IsNumber({}, { each: true })");return}if($.scalar==="boolean")Z.validatorImports.add("IsBoolean"),Q.push("@IsBoolean({ each: true })")}function vH($,Q,Z){if($.scalar==="string")fH($,Q,Z);else yH($,Q,Z);if($.scalar==="number"||$.scalar==="integer")D9({minimum:$.minimum,maximum:$.maximum,exclusiveMinimum:$.exclusiveMinimum,exclusiveMaximum:$.exclusiveMaximum},Q,Z,{each:!0})}function LX($,Q,Z,X,U){if(Z.kind==="scalar")return Z.scalar==="integer"?"number":Z.scalar;if(Z.kind==="enum")return U.addEnumImport(X,Z.enumName),Z.enumName;if(Z.kind==="ref")return U.addDtoImport(X,Z.refName);if(Z.kind==="unknown")return"unknown";if(Z.kind==="object"){if(Object.keys(Z.properties).length===0)return"unknown";let Y=`${$}${BX(Q)}ValueDto`;return U.emitHelperDto(Y,Z,X),Y}return`${LX($,Q,Z.items,X,U)}[]`}function pZ($,Q){let Z=[];if(typeof $.exclusiveMinimum==="number")Z.push(`${Q} > ${$.exclusiveMinimum}`);else if($.minimum!==void 0)Z.push(`${Q} ${$.exclusiveMinimum===!0?">":">="} ${$.minimum}`);else if($.exclusiveMinimum===!0)Z.push(`${Q} > 0`);if(typeof $.exclusiveMaximum==="number")Z.push(`${Q} < ${$.exclusiveMaximum}`);else if($.maximum!==void 0)Z.push(`${Q} ${$.exclusiveMaximum===!0?"<":"<="} ${$.maximum}`);return Z}function xH($,Q){if($.format==="uuid")return[`new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$', 'i').test(${Q})`];if($.format==="email")return[`new RegExp('^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$').test(${Q})`];if($.format==="uri"||$.format==="url")return[`(() => { try { new URL(String(${Q})); return true; } catch { return false; } })()`];if($.format==="date")return[`new RegExp('^\\d{4}-\\d{2}-\\d{2}$').test(${Q})`];if($.format==="date-time")return[`new RegExp('^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$').test(${Q})`];return[]}function gH($,Q){if($.scalar==="boolean")return`typeof ${Q} === 'boolean'`;if($.scalar==="integer")return[`typeof ${Q} === 'number'`,`Number.isInteger(${Q})`,...pZ($,Q)].join(" && ");if($.scalar==="number")return[`typeof ${Q} === 'number'`,...pZ($,Q)].join(" && ");let Z=[`typeof ${Q} === 'string'`];if(Z.push(...xH($,Q)),$.minLength!==void 0)Z.push(`${Q}.length >= ${$.minLength}`);if($.maxLength!==void 0)Z.push(`${Q}.length <= ${$.maxLength}`);if($.pattern)Z.push(`new RegExp(${N6($.pattern)}).test(${Q})`);if($.format==="date"||$.format==="date-time")Z.push(`!Number.isNaN(Date.parse(${Q}))`);return Z.join(" && ")}function hH($,Q,Z,X,U,J){if(Object.keys(Z.properties).length===0)return null;let Y=`${$}${BX(Q)}ValueDto`;return U.emitHelperDto(Y,Z,X),X.validatorImports.add("validateSync"),X.transformerImports.add("plainToInstance"),`isRecordValue(${J}) && validateSync(plainToInstance(${Y}, ${J})).length === 0`}function AX($,Q,Z,X,U,J="value"){if(Z.kind==="scalar")return gH(Z,J);if(Z.kind==="enum")return U.addEnumImport(X,Z.enumName),`(${Q2(Z.enumName)} as readonly unknown[]).includes(${J})`;if(Z.kind==="ref"){let W=U.addDtoImport(X,Z.refName);return X.validatorImports.add("validateSync"),X.transformerImports.add("plainToInstance"),`isRecordValue(${J}) && validateSync(plainToInstance(${W}, ${J})).length === 0`}if(Z.kind==="unknown")return null;if(Z.kind==="object")return hH($,Q,Z,X,U,J);let Y=AX($,Q,Z.items,X,U,"entry");return Y?`Array.isArray(${J}) && ${J}.every((entry) => ${Y})`:`Array.isArray(${J})`}function uH(){return["function isRecordValue(value: unknown): value is Record<string, unknown> {"," return typeof value === 'object' && value !== null && !Array.isArray(value);","}","","function ValidateRecordValues("," validateValue: (value: unknown) => boolean","): PropertyDecorator {"," return (target: object, propertyKey: string | symbol) => {"," registerDecorator({"," name: 'ValidateRecordValues',"," target: target.constructor,"," propertyName: String(propertyKey),"," validator: {"," validate(value: unknown): boolean {"," return isRecordValue(value) && Object.values(value).every(validateValue);"," },"," defaultMessage(): string {"," return 'record values must match the OpenAPI additionalProperties schema';"," },"," },"," });"," };","}"].join(`
|
|
116
|
+
`)}function mH(){return{enumImports:new Map,enumTypeImports:new Map,dtoImports:new Map,validatorImports:new Set,transformerImports:new Set,usesApiPropertyOptional:!1,usesRecordValueValidator:!1,helperClassBlocks:[],seenHelpers:new Set}}function lH($){return $.map((Q)=>` ${Q}`)}function R9($,Q){let Z=`../enums/${S9(Q).replace(/\.ts$/,"")}`,X=$.enumImports.get(Z)??new Set;X.add(D6(Q)),X.add(Q2(Q)),$.enumImports.set(Z,X);let U=$.enumTypeImports.get(Z)??new Set;U.add(Q),$.enumTypeImports.set(Z,U)}function N9($,Q){let Z=o1(Q);return $.dtoImports.set(Z,`./${C9(Q).replace(/\.ts$/,"")}`),Z}function Q1($,Q,Z,X,U=!1){let J=U?"ApiPropertyOptional":"ApiProperty";if(U)$.usesApiPropertyOptional=!0;if(Z.length===0){X.push(`@${J}()`);return}X.push(`@${J}({`);for(let Y of Z)X.push(` ${Y},`);X.push("})")}function pH($,Q,Z){R9(Z,Q.enumName);let X=j1($,Z),U=[`enum: ${Q2(Q.enumName)}`,`enumName: '${Q.enumName}'`];if($.nullable)U.push("nullable: true");return Q1(Z,$,U,X,$.optional),Z.validatorImports.add("IsEnum"),X.push(`@IsEnum(${D6(Q.enumName)})`),{typeName:Q.enumName,decorators:X}}function cH($,Q,Z){let X=N9(Z,Q.refName),U=j1($,Z),J=[`type: () => ${X}`];if($.nullable)J.push("nullable: true");return Q1(Z,$,J,U,$.optional),Z.validatorImports.add("ValidateNested"),U.push("@ValidateNested()"),Z.transformerImports.add("Type"),U.push(`@Type(() => ${X})`),{typeName:X,decorators:U}}function nH($,Q,Z,X){if(Object.keys(Z.properties).length===0&&Z.additionalProperties){let W=LX($,Q.name,Z.additionalProperties,X,X9),_=j1(Q,X);X.validatorImports.add("IsObject"),_.push("@IsObject()");let G=AX($,Q.name,Z.additionalProperties,X,X9);if(G)X.validatorImports.add("registerDecorator"),X.usesRecordValueValidator=!0,_.push(`@ValidateRecordValues((value) => ${G})`);let z=["type: Object","additionalProperties: true"];if(Q.nullable)z.push("nullable: true");return Q1(X,Q,z,_,Q.optional),{typeName:`Record<string, ${W}>`,decorators:_}}if(Object.keys(Z.properties).length===0){let W=j1(Q,X);X.validatorImports.add("IsObject"),W.push("@IsObject()");let _=["type: Object"];if(Q.nullable)_.push("nullable: true");return Q1(X,Q,_,W,Q.optional),{typeName:"Record<string, unknown>",decorators:W}}let U=`${$}${MX(Q.name)}Dto`;w9(U,Z,X);let J=j1(Q,X),Y=[`type: () => ${U}`];if(Q.nullable)Y.push("nullable: true");return Q1(X,Q,Y,J,Q.optional),X.validatorImports.add("ValidateNested"),J.push("@ValidateNested()"),X.transformerImports.add("Type"),J.push(`@Type(() => ${U})`),{typeName:U,decorators:J}}function iH($,Q,Z,X){if(Z.kind==="scalar")return PH(Q,Z,X,Q1);if(Z.kind==="enum")return pH(Q,Z,X);if(Z.kind==="ref")return cH(Q,Z,X);if(Z.kind==="object")return nH($,Q,Z,X);if(Z.kind==="unknown"){let U=j1(Q,X),J=["type: Object"];if(Q.nullable)J.push("nullable: true");return Q1(X,Q,J,U,Q.optional),{typeName:"unknown",decorators:U}}return rH($,Q,Z,X)}function rH($,Q,Z,X){let U=j1(Q,X);if(X.validatorImports.add("IsArray"),U.push("@IsArray()"),Z.minItems!==void 0)X.validatorImports.add("ArrayMinSize"),U.push(`@ArrayMinSize(${Z.minItems})`);if(Z.maxItems!==void 0)X.validatorImports.add("ArrayMaxSize"),U.push(`@ArrayMaxSize(${Z.maxItems})`);let J=["isArray: true"];if(Z.minItems!==void 0)J.push(`minItems: ${Z.minItems}`);if(Z.maxItems!==void 0)J.push(`maxItems: ${Z.maxItems}`);if(Q.nullable)J.push("nullable: true");let Y="unknown";if(Z.items.kind==="enum")R9(X,Z.items.enumName),Y=Z.items.enumName,X.validatorImports.add("IsEnum"),U.push(`@IsEnum(${D6(Z.items.enumName)}, { each: true })`),J.push(`enum: ${Q2(Z.items.enumName)}`),J.push(`enumName: '${Z.items.enumName}'`);else if(Z.items.kind==="ref")Y=N9(X,Z.items.refName),X.validatorImports.add("ValidateNested"),U.push("@ValidateNested({ each: true })"),X.transformerImports.add("Type"),U.push(`@Type(() => ${Y})`),J.push(`type: () => ${Y}`);else if(Z.items.kind==="scalar")Y=Z.items.scalar==="integer"?"number":Z.items.scalar,vH(Z.items,U,X),J.push(`type: '${Y}'`);else if(Z.items.kind==="object"){if(Object.keys(Z.items.properties).length===0)return Y="Record<string, unknown>",X.validatorImports.add("IsObject"),U.push("@IsObject({ each: true })"),J.push("type: Object"),Q1(X,Q,J,U,Q.optional),{typeName:`${Y}[]`,decorators:U};let W=`${$}${MX(Q.name)}ItemDto`;w9(W,Z.items,X),Y=W,X.validatorImports.add("ValidateNested"),U.push("@ValidateNested({ each: true })"),X.transformerImports.add("Type"),U.push(`@Type(() => ${W})`),J.push(`type: () => ${W}`)}else throw Error(`Unsupported array item kind '${Z.items.kind}' for property '${Q.name}'`);return Q1(X,Q,J,U,Q.optional),{typeName:`${Y}[]`,decorators:U}}function oH($,Q,Z){let{decorators:X,typeName:U}=iH($,Q,Q.schema,Z),J=`${Q.name}${Q.optional?"?":"!"}`,Y=!Q.optional&&Q.nullable?" | null":"";return Z.transformerImports.add("Expose"),[...X,"@Expose()",`${J}: ${U}${Y};`]}function jX($,Q,Z,X,U){let J=[];if(Q)J.push(`/** ${Q.replace(/\*\//g,"*\\/")} */`);J.push(`export class ${$} {`);let Y=Object.entries(Z.properties);for(let[W,_]of Y){let G=U?.get(W),z={name:W,schema:_,optional:G?.optional??!Z.required.includes(W),nullable:G?.nullable??!1,description:G?.description,source:G?.source},H=oH($,z,X);J.push(...lH(H),"")}if(Y.length===0)J.push(" // empty schema");if(J[J.length-1]==="")J.pop();return J.push("}"),J.join(`
|
|
117
|
+
`)}function w9($,Q,Z){if(Z.seenHelpers.has($))return;Z.seenHelpers.add($),Z.helperClassBlocks.push(jX($,Q.description,Q,Z))}function aH($){let Q=mH(),Z=new Map($.properties.map((V)=>[V.name,V])),X={kind:"object",properties:Object.fromEntries($.properties.map((V)=>[V.name,V.schema])),required:$.properties.filter((V)=>!V.optional).map((V)=>V.name),description:$.description},U=jX($.dtoName,$.description,X,Q,Z),J=[],Y=["ApiProperty"];if(Q.usesApiPropertyOptional)Y.push("ApiPropertyOptional");J.push(`import { ${Y.join(", ")} } from '@nestjs/swagger';`);let W=[...Q.validatorImports].sort();if(W.length>0)J.push(`import { ${W.join(", ")} } from 'class-validator';`);let _=[...Q.transformerImports].sort();if(_.length>0)J.push(`import { ${_.join(", ")} } from 'class-transformer';`);for(let[V,O]of[...Q.enumImports.entries()].sort((K,q)=>K[0].localeCompare(q[0])))J.push(`import { ${[...O].sort().join(", ")} } from '${V}';`);for(let[V,O]of[...Q.enumTypeImports.entries()].sort((K,q)=>K[0].localeCompare(q[0])))J.push(`import type { ${[...O].sort().join(", ")} } from '${V}';`);let G=$.dtoName,z=[...Q.dtoImports.entries()].filter(([V])=>V!==G).sort(([V,O],[K,q])=>O.localeCompare(q)||V.localeCompare(K));for(let[V,O]of z)J.push(`import { ${V} } from '${O}';`);let H=[...Q.usesRecordValueValidator?[uH()]:[],...Q.helperClassBlocks,U].join(`
|
|
115
118
|
|
|
116
|
-
`);return`${
|
|
119
|
+
`);return`${J.join(`
|
|
117
120
|
`)}
|
|
118
121
|
|
|
119
122
|
${H}
|
|
120
|
-
`}function
|
|
121
|
-
`),
|
|
122
|
-
`)}function j($){return typeof $==="object"&&$!==null}function xH($){if(typeof $!=="string")throw Error("OpenAPI document missing valid openapi version");if($.startsWith("3.0."))return $8.V3_0;if($.startsWith("3.1."))return $8.V3_1;if($.startsWith("3.2."))return $8.V3_2;throw Error(`Unsupported OpenAPI version '${$}'. Supported families: 3.0.x, 3.1.x, 3.2.x`)}function I9($){let Q=$.match(/^#\/components\/schemas\/(.+)$/);if(!Q?.[1])throw Error(`Unsupported $ref '${$}'. Expected '#/components/schemas/<Name>'`);return Q[1]}function gH($,Q){let Z=`#/components/${Q}/`;if(!$.startsWith(Z))return null;return $.slice(Z.length).replace(/~1/g,"/").replace(/~0/g,"~")}function BX($,Q){if(Array.isArray($.oneOf))throw Error(`Unsupported oneOf at ${Q}`);if(Array.isArray($.anyOf))throw Error(`Unsupported anyOf at ${Q}`);if("not"in $)throw Error(`Unsupported not at ${Q}`);if("discriminator"in $)throw Error(`Unsupported discriminator at ${Q}`)}function C8($){let Q=$.nullable===!0,Z=$.type;if(!Array.isArray(Z))return{nullable:Q,normalizedType:typeof Z==="string"?Z:void 0};let X=Z.filter((W)=>typeof W==="string");if(X.length!==Z.length)throw Error("Unsupported mixed type array in OpenAPI schema");let U=X.filter((W)=>W!=="null");if(U.length!==1||X.length!==2||!X.includes("null"))throw Error(`Unsupported OpenAPI type array: [${X.join(", ")}]`);return{nullable:!0,normalizedType:U[0]}}function hH($,Q,Z,X){let U=I9(Q);if(X.has(U))throw Error(`Unsupported recursive schema cycle detected at ${Z} -> ${U}`);let W=$.schemas[U];if(!j(W))throw Error(`Missing referenced schema '${U}' at ${Z}`);return W}function uH($,Q,Z,X,U,W,J,G){if(!j(Q))throw Error(`Invalid property '${$}' at ${Z}`);if(U[$])throw Error(`Duplicate property '${$}' while flattening ${X}`);let _=`${u5(X.split("/").pop()??"")}${u5($)}`;U[$]=G(Q,W,`${Z}.properties.${$}`,_,J)}function dH($,Q,Z,X,U,W,J,G){let{normalizedType:_}=C8($),Y=$.properties;if(_!=="object"&&!j(Y))throw Error(`Unsupported allOf part at ${Q}. Expected object-like schema`);if(j(Y))for(let[H,V]of Object.entries(Y))uH(H,V,Q,Z,X,W,J,G);let z=$.required;if(Array.isArray(z)){for(let H of z)if(typeof H==="string")U.add(H)}}function mH($,Q,Z,X){for(let[U,W]of Object.entries($.properties)){if(Z[U])throw Error(`Duplicate property '${U}' while flattening ${Q}`);Z[U]=W}for(let U of $.required)X.add(U)}function lH($,Q,Z,X,U,W,J,G){let _=$,Y=null;if(typeof $.$ref==="string"){let z=$.$ref;Y=I9(z),_=hH(W,z,Q,J),J.add(Y)}try{if(BX(_,Q),Array.isArray(_.allOf)){let z=AX(_,W,Q,J,G);mH(z,Z,X,U);return}dH(_,Q,Z,X,U,W,J,G)}finally{if(Y)J.delete(Y)}}function AX($,Q,Z,X,U){let W=$.allOf;if(!Array.isArray(W))throw Error(`Expected allOf array at ${Z}`);let J={},G=new Set,_={};for(let[z,H]of Object.entries($))if(z!=="allOf"&&z!=="description"&&z!=="nullable")_[z]=H;let Y=[...W,_];for(let z=0;z<Y.length;z++){let H=Y[z];if(!j(H)||Object.keys(H).length===0)continue;let V=`${Z}.allOf[${z}]`;lH(H,V,Z,J,G,Q,X,U)}return{kind:l$.Object,properties:J,required:[...G],description:typeof $.description==="string"?$.description:void 0}}function MX($,Q){let Z=$.enum;if(!Array.isArray(Z))return null;if(Z.length===0)throw Error(`Enum at ${Q} cannot be empty`);let X=[];for(let U of Z){if(typeof U!=="string"&&typeof U!=="number")throw Error(`Enum at ${Q} must contain only string or number values`);X.push(U)}return X}function EX($,Q,Z,X){let U=Z.map((_)=>({key:JX(_),value:_})),W=new Set;for(let _ of U){if(W.has(_.key))throw Error(`Enum '${Q}' has duplicate normalized key '${_.key}' (path: ${X})`);W.add(_.key)}let J=$.enumGroups.get(Q);if(!J){let _={name:Q,schemaPath:X,values:Z,members:U};return $.enumGroups.set(Q,_),_}if(!(J.values.length===Z.length&&J.values.every((_,Y)=>_===Z[Y])))throw Error(`Enum name collision for '${Q}'. Paths: ${J.schemaPath} and ${X}`);return J}function nH($){if($===void 0)return!1;return Object.values(qX).some((Q)=>Q===$)}function d5($){if($===!0||$===!1)return $;if(typeof $==="number")return $;return}function iH($,Q,Z){return{kind:l$.Scalar,scalar:Q,format:typeof $.format==="string"?$.format:void 0,minLength:typeof $.minLength==="number"?$.minLength:void 0,maxLength:typeof $.maxLength==="number"?$.maxLength:void 0,minimum:typeof $.minimum==="number"?$.minimum:void 0,maximum:typeof $.maximum==="number"?$.maximum:void 0,exclusiveMinimum:d5($.exclusiveMinimum),exclusiveMaximum:d5($.exclusiveMaximum),pattern:typeof $.pattern==="string"?$.pattern:void 0,description:Z}}function oH($,Q,Z,X){let U=typeof $.$ref==="string"?$.$ref:"";if(!U)throw Error(`Missing $ref at ${Z}`);let W=I9(U),J=Q.schemas[W];if(!j(J))throw Error(`Missing referenced schema '${W}' at ${Z}`);let G=typeof $.description==="string"?$.description:void 0;if(X.has(W))return{kind:l$.Ref,ref:U,refName:W,description:G};X.add(W);let _=i1(J,Q,`#/components/schemas/${W}`,Y8(W),X);if(X.delete(W),_.kind!=="object"||Object.keys(_.properties).length===0)return _;return{kind:l$.Ref,ref:U,refName:W,description:G}}function aH($,Q,Z,X,U,W){let J=$.properties,G={};if(j(J))for(let[V,O]of Object.entries(J)){if(!j(O))throw Error(`Invalid property '${V}' at ${Z}`);let K=`${X}${Y8(V)}`;G[V]=i1(O,Q,`${Z}.properties.${V}`,K,W)}let _=$.required,Y=Array.isArray(_)&&_.every((V)=>typeof V==="string")?_:[],z=$.additionalProperties,H;if(z===!0)H={kind:l$.Unknown};else if(j(z))H=i1(z,Q,`${Z}.additionalProperties`,`${X}Value`,W);else if(z!==void 0&&z!==!1)throw Error(`Unsupported additionalProperties at ${Z}`);return{kind:l$.Object,properties:G,required:Y,additionalProperties:H,description:U}}function sH($,Q,Z,X,U){let W=EX(Q,Z,X,U);return{kind:l$.Enum,enumName:W.name,values:W.values,description:typeof $.description==="string"?$.description:void 0}}function tH($,Q,Z,X,U,W){let J=$.items;if(!j(J))throw Error(`Array schema at ${Z} is missing items`);let G=`${X}Item`;return{kind:l$.Array,items:i1(J,Q,`${Z}.items`,G,W),minItems:typeof $.minItems==="number"?$.minItems:void 0,maxItems:typeof $.maxItems==="number"?$.maxItems:void 0,description:U}}function i1($,Q,Z,X,U){if(BX($,Z),typeof $.$ref==="string")return oH($,Q,Z,U);let W=MX($,Z);if(W)return sH($,Q,X,W,Z);if(Array.isArray($.allOf))return AX($,Q,Z,U,i1);let{normalizedType:J}=C8($),G=typeof $.description==="string"?$.description:void 0;if(J==="array")return tH($,Q,Z,X,G,U);if(J==="object"||j($.properties))return aH($,Q,Z,X,G,U);if(nH(J))return iH($,J,G);throw Error(`Unsupported schema at ${Z}`)}function eH($,Q,Z,X=r0.Schema,U=F9.Schema){let W=MX(Q,`#/components/schemas/${$}`);if(W)return EX(Z,Y8($),W,`#/components/schemas/${$}`),null;let J=i1(Q,Z,`#/components/schemas/${$}`,Y8($),new Set);if(J.kind!=="object")return null;if(Object.keys(J.properties).length===0&&J.additionalProperties===void 0)return null;let G=Object.entries(J.properties).map(([_,Y])=>{let z=!J.required.includes(_),H=Q.nullable===!0,O=(j(Q.properties)?Q.properties:void 0)?.[_];if(j(O)){let{nullable:L}=C8(O);H=L||O.nullable===!0}let K=j(O)&&typeof O.description==="string"?O.description:void 0;return{name:_,schema:Y,optional:z,nullable:H,source:X,description:K}});return{schemaName:$,dtoName:r1($),schema:J,description:typeof Q.description==="string"?Q.description:void 0,properties:G,source:U}}function TX($,Q){if(!Q.has($.schemaName))return Q.add($.schemaName),$;let Z=2;while(Q.has(`${$.schemaName}${Z}`))Z+=1;let X=`${$.schemaName}${Z}`;return Q.add(X),{...$,schemaName:X,dtoName:r1(X)}}function a2($){if(!j($))return null;return j($.schema)?$.schema:null}function F8($){if(!j($))return null;let Q=a2($[A4]);if(Q)return Q;for(let[X,U]of Object.entries($)){if(!GZ.test(X))continue;let W=a2(U);if(W)return W}let Z=a2($[M4]);if(Z)return Z;for(let X of Object.keys($).sort((U,W)=>U.localeCompare(W))){let U=a2($[X]);if(U)return U}return null}function $V($,Q,Z){let X=typeof $.operationId==="string"?$.operationId.trim():"";return SX(X.length>0?X:`${Q} ${Z}`)}function CX($,Q,Z,X=new Set){if(!j($))return null;let U=$.$ref;if(typeof U!=="string")return $;if(X.has(U))return null;let W=gH(U,Z);if(!W)return null;let J=Q[Z];if(!j(J))return null;let G=J[W];if(!j(G))return null;return X.add(U),CX(G,Q,Z,X)}function QV($,Q,Z,X){let U=new Map,W=(J)=>{if(!Array.isArray(J))return;for(let G of J){let _=CX(G,Z,"parameters");if(!_||_.in!==X||typeof _.name!=="string")continue;U.set(`${X}:${_.name}`,_)}};return W($),W(Q),[...U.values()].sort((J,G)=>String(J.name).localeCompare(String(G.name)))}function ZV($){if(j($.schema))return $.schema;return F8($.content)}function XV($,Q){if(typeof Q.description!=="string"||typeof $.description==="string")return $;return{...$,description:Q.description}}function m5($,Q,Z,X,U,W,J){let G=QV($.parameters,Q.parameters,Z,W);if(G.length===0)return null;let _=[];for(let z of G){let H=z.name;if(typeof H!=="string")continue;let V=ZV(z);if(!V)continue;let O=XV(V,z),{nullable:K}=C8(O),L=`${U}${J}${SX(H)}`;_.push({name:H,schema:i1(O,X,`paths.${U}.${J}.${H}`,L,new Set),optional:W===r0.Path?!1:z.required!==!0,nullable:K,description:typeof z.description==="string"?z.description:void 0,source:W})}if(_.length===0)return null;let Y=`${U}${J}`;return{schemaName:Y,dtoName:r1(Y),schema:{kind:l$.Object,properties:Object.fromEntries(_.map((z)=>[z.name,z.schema])),required:_.filter((z)=>!z.optional).map((z)=>z.name)},properties:_,source:F9.Operation}}function UV($,Q,Z,X,U){let W=[];for(let J of LX){let G=Q[J];if(!j(G))continue;let _=$V(G,J,$),Y=[m5(Q,G,Z,X,_,r0.Path,t6.Params),m5(Q,G,Z,X,_,r0.Query,t6.Query)];for(let z of Y)if(z)W.push(TX(z,U))}return W}function WV($,Q,Z){if(!j($.paths))return[];let X=j($.components)?$.components:{},U=[];for(let[W,J]of Object.entries($.paths).sort(([G],[_])=>G.localeCompare(_))){if(!j(J))continue;U.push(...UV(W,J,X,Q,Z))}return U}function FX($,Q){if(!j($))return;for(let[Z,X]of Object.entries($)){if(!j(X)||!("schema"in X))continue;let U=X.schema;if(!j(U)||typeof U.$ref!=="string")throw Error(`Inline ${Q}.${Z}.schema`)}}function GV($,Q){if(!j(Q))return;FX(Q.content,`request schema is not allowed at ${$}.requestBody.content`)}function _V($,Q){if(!j(Q))return;for(let[Z,X]of Object.entries(Q)){if(!j(X))continue;FX(X.content,`response schema is not allowed at ${$}.responses.${Z}.content`)}}function YV($,Q,Z){let X=`paths.${$}.${Q}`;GV(X,Z.requestBody),_V(X,Z.responses)}function zV($,Q){if(!Q.enforceOperationSchemaRefs)return;let Z=$.paths;if(!j(Z))return;for(let[X,U]of Object.entries(Z)){if(!j(U))continue;for(let[W,J]of Object.entries(U)){if(!j(J))continue;if(W==="parameters")continue;YV(X,W,J)}}}function I8($,Q={}){if(!j($))throw Error("OpenAPI document must be an object");let Z=xH($.openapi);return zV($,{enforceOperationSchemaRefs:Q.enforceOperationSchemaRefs??!0}),Z}function HV($){let Q=$.components;if(!j(Q)||!j(Q.schemas))throw Error("OpenAPI document is missing components.schemas");return Q.schemas}function IX($){if(!j($))throw Error("OpenAPI document must be an object");let Q=I8($,{enforceOperationSchemaRefs:!0}),Z=HV($),X={schemas:Z,enumGroups:new Map},U=[],W=new Set;for(let[J,G]of Object.entries(Z)){if(!j(G))throw Error(`Invalid schema '${J}' in components.schemas`);let _=eH(J,G,X);if(_)U.push(TX(_,W))}return U.push(...WV($,X,W)),{family:Q,dtoModels:U,enumGroups:[...X.enumGroups.values()].sort((J,G)=>J.name.localeCompare(G.name))}}function VV($){return`./${E8($).replace(/\.ts$/,"")}`}function OV($){return`../enums/${A9($).replace(/\.ts$/,"")}`}function RX($,Q,Z){let X=$.imports.get(Q)??new Set;X.add(Z),$.imports.set(Q,X)}function KV($,Q){let Z=S1(Q);if(Z===$.currentName)return;RX($,VV(Q),Z)}function qV($,Q){RX($,OV(Q),S1(Q))}function NX($){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test($)?$:JSON.stringify($)}function R9($){return[...new Set($)].join(" | ")}function wX($,Q,Z,X){let U=c1($,Z,X);if(U==="unknown")return"unknown";return R9([U,...Q])}function LV($,Q,Z){let X=Object.entries($.properties);if(X.length===0)return $.additionalProperties?`Record<string, ${c1($.additionalProperties,Q,Z)}>`:"Record<string, unknown>";let U=" ".repeat(Z),W=" ".repeat(Z+1),J=["{"];for(let[G,_]of X){let Y=$.required.includes(G)?"":"?";J.push(`${W}${NX(G)}${Y}: ${c1(_,Q,Z+1)};`)}if($.additionalProperties){let G=X.map(([_,Y])=>{let z=$.required.includes(_)?[]:["undefined"];return R9([c1(Y,Q,Z+1),...z])});J.push(`${W}[key: string]: ${wX($.additionalProperties,G,Q,Z+1)};`)}return J.push(`${U}}`),J.join(`
|
|
123
|
-
`)}function
|
|
124
|
-
`:""} ${
|
|
123
|
+
`}function cZ($){return typeof $==="string"?`'${$.replace(/'/g,"\\'")}'`:String($)}function tH($){let Q=Q2($.name),Z=D6($.name),X=$.name,U=$.values.map((W)=>cZ(W)).join(", "),J=$.members.map((W)=>` ${W.key}: ${cZ(W.value)},`).join(`
|
|
124
|
+
`),Y=$.values.map((W)=>String(W)).join(" | ");return["/**",` * OpenAPI enum: ${$.name}`,` * Schema path: ${$.schemaPath}`,` * Values: ${Y}`," */",`export const ${Q} = [${U}] as const;`,"",`export type ${X} = (typeof ${Q})[number];`,"",`export const ${Z} = {`,J,"} as const;"].join(`
|
|
125
|
+
`)}function F($){return typeof $==="object"&&$!==null}function QV($){if(typeof $!=="string")throw Error("OpenAPI document missing valid openapi version");if($.startsWith("3.0."))return Y6.V3_0;if($.startsWith("3.1."))return Y6.V3_1;if($.startsWith("3.2."))return Y6.V3_2;throw Error(`Unsupported OpenAPI version '${$}'. Supported families: 3.0.x, 3.1.x, 3.2.x`)}function b9($){let Q=$.match(/^#\/components\/schemas\/(.+)$/);if(!Q?.[1])throw Error(`Unsupported $ref '${$}'. Expected '#/components/schemas/<Name>'`);return Q[1]}function ZV($,Q){let Z=`#/components/${Q}/`;if(!$.startsWith(Z))return null;return $.slice(Z.length).replace(/~1/g,"/").replace(/~0/g,"~")}function CX($,Q){if(Array.isArray($.oneOf))throw Error(`Unsupported oneOf at ${Q}`);if(Array.isArray($.anyOf))throw Error(`Unsupported anyOf at ${Q}`);if("not"in $)throw Error(`Unsupported not at ${Q}`);if("discriminator"in $)throw Error(`Unsupported discriminator at ${Q}`)}function w6($){let Q=$.nullable===!0,Z=$.type;if(!Array.isArray(Z))return{nullable:Q,normalizedType:typeof Z==="string"?Z:void 0};let X=Z.filter((J)=>typeof J==="string");if(X.length!==Z.length)throw Error("Unsupported mixed type array in OpenAPI schema");let U=X.filter((J)=>J!=="null");if(U.length!==1||X.length!==2||!X.includes("null"))throw Error(`Unsupported OpenAPI type array: [${X.join(", ")}]`);return{nullable:!0,normalizedType:U[0]}}function XV($,Q,Z,X){let U=b9(Q);if(X.has(U))throw Error(`Unsupported recursive schema cycle detected at ${Z} -> ${U}`);let J=$.schemas[U];if(!F(J))throw Error(`Missing referenced schema '${U}' at ${Z}`);return J}function UV($,Q,Z,X,U,J,Y,W){if(!F(Q))throw Error(`Invalid property '${$}' at ${Z}`);if(U[$])throw Error(`Duplicate property '${$}' while flattening ${X}`);let _=`${nZ(X.split("/").pop()??"")}${nZ($)}`;U[$]=W(Q,J,`${Z}.properties.${$}`,_,Y)}function JV($,Q,Z,X,U,J,Y,W){let{normalizedType:_}=w6($),G=$.properties;if(_!=="object"&&!F(G))throw Error(`Unsupported allOf part at ${Q}. Expected object-like schema`);if(F(G))for(let[H,V]of Object.entries(G))UV(H,V,Q,Z,X,J,Y,W);let z=$.required;if(Array.isArray(z)){for(let H of z)if(typeof H==="string")U.add(H)}}function YV($,Q,Z,X){for(let[U,J]of Object.entries($.properties)){if(Z[U])throw Error(`Duplicate property '${U}' while flattening ${Q}`);Z[U]=J}for(let U of $.required)X.add(U)}function WV($,Q,Z,X,U,J,Y,W){let _=$,G=null;if(typeof $.$ref==="string"){let z=$.$ref;G=b9(z),_=XV(J,z,Q,Y),Y.add(G)}try{if(CX(_,Q),Array.isArray(_.allOf)){let z=SX(_,J,Q,Y,W);YV(z,Z,X,U);return}JV(_,Q,Z,X,U,J,Y,W)}finally{if(G)Y.delete(G)}}function SX($,Q,Z,X,U){let J=$.allOf;if(!Array.isArray(J))throw Error(`Expected allOf array at ${Z}`);let Y={},W=new Set,_={};for(let[z,H]of Object.entries($))if(z!=="allOf"&&z!=="description"&&z!=="nullable")_[z]=H;let G=[...J,_];for(let z=0;z<G.length;z++){let H=G[z];if(!F(H)||Object.keys(H).length===0)continue;let V=`${Z}.allOf[${z}]`;WV(H,V,Z,Y,W,Q,X,U)}return{kind:p$.Object,properties:Y,required:[...W],description:typeof $.description==="string"?$.description:void 0}}function FX($,Q){let Z=$.enum;if(!Array.isArray(Z))return null;if(Z.length===0)throw Error(`Enum at ${Q} cannot be empty`);let X=[];for(let U of Z){if(typeof U!=="string"&&typeof U!=="number")throw Error(`Enum at ${Q} must contain only string or number values`);X.push(U)}return X}function IX($,Q,Z,X){let U=Z.map((_)=>({key:VX(_),value:_})),J=new Set;for(let _ of U){if(J.has(_.key))throw Error(`Enum '${Q}' has duplicate normalized key '${_.key}' (path: ${X})`);J.add(_.key)}let Y=$.enumGroups.get(Q);if(!Y){let _={name:Q,schemaPath:X,values:Z,members:U};return $.enumGroups.set(Q,_),_}if(!(Y.values.length===Z.length&&Y.values.every((_,G)=>_===Z[G])))throw Error(`Enum name collision for '${Q}'. Paths: ${Y.schemaPath} and ${X}`);return Y}function zV($){if($===void 0)return!1;return Object.values(TX).some((Q)=>Q===$)}function iZ($){if($===!0||$===!1)return $;if(typeof $==="number")return $;return}function HV($,Q,Z){return{kind:p$.Scalar,scalar:Q,format:typeof $.format==="string"?$.format:void 0,minLength:typeof $.minLength==="number"?$.minLength:void 0,maxLength:typeof $.maxLength==="number"?$.maxLength:void 0,minimum:typeof $.minimum==="number"?$.minimum:void 0,maximum:typeof $.maximum==="number"?$.maximum:void 0,exclusiveMinimum:iZ($.exclusiveMinimum),exclusiveMaximum:iZ($.exclusiveMaximum),pattern:typeof $.pattern==="string"?$.pattern:void 0,description:Z}}function OV($,Q,Z,X){let U=typeof $.$ref==="string"?$.$ref:"";if(!U)throw Error(`Missing $ref at ${Z}`);let J=b9(U),Y=Q.schemas[J];if(!F(Y))throw Error(`Missing referenced schema '${J}' at ${Z}`);let W=typeof $.description==="string"?$.description:void 0;if(X.has(J))return{kind:p$.Ref,ref:U,refName:J,description:W};X.add(J);let _=r1(Y,Q,`#/components/schemas/${J}`,q6(J),X);if(X.delete(J),_.kind!=="object"||Object.keys(_.properties).length===0)return _;return{kind:p$.Ref,ref:U,refName:J,description:W}}function KV($,Q,Z,X,U,J){let Y=$.properties,W={};if(F(Y))for(let[V,O]of Object.entries(Y)){if(!F(O))throw Error(`Invalid property '${V}' at ${Z}`);let K=`${X}${q6(V)}`;W[V]=r1(O,Q,`${Z}.properties.${V}`,K,J)}let _=$.required,G=Array.isArray(_)&&_.every((V)=>typeof V==="string")?_:[],z=$.additionalProperties,H;if(z===!0)H={kind:p$.Unknown};else if(F(z))H=r1(z,Q,`${Z}.additionalProperties`,`${X}Value`,J);else if(z!==void 0&&z!==!1)throw Error(`Unsupported additionalProperties at ${Z}`);return{kind:p$.Object,properties:W,required:G,additionalProperties:H,description:U}}function qV($,Q,Z,X,U){let J=IX(Q,Z,X,U);return{kind:p$.Enum,enumName:J.name,values:J.values,description:typeof $.description==="string"?$.description:void 0}}function BV($,Q,Z,X,U,J){let Y=$.items;if(!F(Y))throw Error(`Array schema at ${Z} is missing items`);let W=`${X}Item`;return{kind:p$.Array,items:r1(Y,Q,`${Z}.items`,W,J),minItems:typeof $.minItems==="number"?$.minItems:void 0,maxItems:typeof $.maxItems==="number"?$.maxItems:void 0,description:U}}function r1($,Q,Z,X,U){if(CX($,Z),typeof $.$ref==="string")return OV($,Q,Z,U);let J=FX($,Z);if(J)return qV($,Q,X,J,Z);if(Array.isArray($.allOf))return SX($,Q,Z,U,r1);let{normalizedType:Y}=w6($),W=typeof $.description==="string"?$.description:void 0;if(Y==="array")return BV($,Q,Z,X,W,U);if(Y==="object"||F($.properties))return KV($,Q,Z,X,W,U);if(zV(Y))return HV($,Y,W);throw Error(`Unsupported schema at ${Z}`)}function LV($,Q,Z,X=t0.Schema,U=P9.Schema){let J=FX(Q,`#/components/schemas/${$}`);if(J)return IX(Z,q6($),J,`#/components/schemas/${$}`),null;let Y=r1(Q,Z,`#/components/schemas/${$}`,q6($),new Set);if(Y.kind!=="object")return null;if(Object.keys(Y.properties).length===0&&Y.additionalProperties===void 0)return null;let W=Object.entries(Y.properties).map(([_,G])=>{let z=!Y.required.includes(_),H=Q.nullable===!0,O=(F(Q.properties)?Q.properties:void 0)?.[_];if(F(O)){let{nullable:q}=w6(O);H=q||O.nullable===!0}let K=F(O)&&typeof O.description==="string"?O.description:void 0;return{name:_,schema:G,optional:z,nullable:H,source:X,description:K}});return{schemaName:$,dtoName:o1($),schema:Y,description:typeof Q.description==="string"?Q.description:void 0,properties:W,source:U}}function DX($,Q){if(!Q.has($.schemaName))return Q.add($.schemaName),$;let Z=2;while(Q.has(`${$.schemaName}${Z}`))Z+=1;let X=`${$.schemaName}${Z}`;return Q.add(X),{...$,schemaName:X,dtoName:o1(X)}}function Z6($){if(!F($))return null;return F($.schema)?$.schema:null}function P6($){if(!F($))return null;let Q=Z6($[v4]);if(Q)return Q;for(let[X,U]of Object.entries($)){if(!O7.test(X))continue;let J=Z6(U);if(J)return J}let Z=Z6($[x4]);if(Z)return Z;for(let X of Object.keys($).sort((U,J)=>U.localeCompare(J))){let U=Z6($[X]);if(U)return U}return null}function AV($,Q,Z){let X=typeof $.operationId==="string"?$.operationId.trim():"";return NX(X.length>0?X:`${Q} ${Z}`)}function wX($,Q,Z,X=new Set){if(!F($))return null;let U=$.$ref;if(typeof U!=="string")return $;if(X.has(U))return null;let J=ZV(U,Z);if(!J)return null;let Y=Q[Z];if(!F(Y))return null;let W=Y[J];if(!F(W))return null;return X.add(U),wX(W,Q,Z,X)}function MV($,Q,Z,X){let U=new Map,J=(Y)=>{if(!Array.isArray(Y))return;for(let W of Y){let _=wX(W,Z,"parameters");if(!_||_.in!==X||typeof _.name!=="string")continue;U.set(`${X}:${_.name}`,_)}};return J($),J(Q),[...U.values()].sort((Y,W)=>String(Y.name).localeCompare(String(W.name)))}function jV($){if(F($.schema))return $.schema;return P6($.content)}function TV($,Q){if(typeof Q.description!=="string"||typeof $.description==="string")return $;return{...$,description:Q.description}}function rZ($,Q,Z,X,U,J,Y){let W=MV($.parameters,Q.parameters,Z,J);if(W.length===0)return null;let _=[];for(let z of W){let H=z.name;if(typeof H!=="string")continue;let V=jV(z);if(!V)continue;let O=TV(V,z),{nullable:K}=w6(O),q=`${U}${Y}${NX(H)}`;_.push({name:H,schema:r1(O,X,`paths.${U}.${Y}.${H}`,q,new Set),optional:J===t0.Path?!1:z.required!==!0,nullable:K,description:typeof z.description==="string"?z.description:void 0,source:J})}if(_.length===0)return null;let G=`${U}${Y}`;return{schemaName:G,dtoName:o1(G),schema:{kind:p$.Object,properties:Object.fromEntries(_.map((z)=>[z.name,z.schema])),required:_.filter((z)=>!z.optional).map((z)=>z.name)},properties:_,source:P9.Operation}}function EV($,Q,Z,X,U){let J=[];for(let Y of EX){let W=Q[Y];if(!F(W))continue;let _=AV(W,Y,$),G=[rZ(Q,W,Z,X,_,t0.Path,U9.Params),rZ(Q,W,Z,X,_,t0.Query,U9.Query)];for(let z of G)if(z)J.push(DX(z,U))}return J}function CV($,Q,Z){if(!F($.paths))return[];let X=F($.components)?$.components:{},U=[];for(let[J,Y]of Object.entries($.paths).sort(([W],[_])=>W.localeCompare(_))){if(!F(Y))continue;U.push(...EV(J,Y,X,Q,Z))}return U}function PX($,Q){if(!F($))return;for(let[Z,X]of Object.entries($)){if(!F(X)||!("schema"in X))continue;let U=X.schema;if(!F(U)||typeof U.$ref!=="string")throw Error(`Inline ${Q}.${Z}.schema`)}}function FV($,Q){if(!F(Q))return;PX(Q.content,`request schema is not allowed at ${$}.requestBody.content`)}function IV($,Q){if(!F(Q))return;for(let[Z,X]of Object.entries(Q)){if(!F(X))continue;PX(X.content,`response schema is not allowed at ${$}.responses.${Z}.content`)}}function DV($,Q,Z){let X=`paths.${$}.${Q}`;FV(X,Z.requestBody),IV(X,Z.responses)}function RV($,Q){if(!Q.enforceOperationSchemaRefs)return;let Z=$.paths;if(!F(Z))return;for(let[X,U]of Object.entries(Z)){if(!F(U))continue;for(let[J,Y]of Object.entries(U)){if(!F(Y))continue;if(J==="parameters")continue;DV(X,J,Y)}}}function b6($,Q={}){if(!F($))throw Error("OpenAPI document must be an object");let Z=QV($.openapi);return RV($,{enforceOperationSchemaRefs:Q.enforceOperationSchemaRefs??!0}),Z}function NV($){let Q=$.components;if(!F(Q)||!F(Q.schemas))throw Error("OpenAPI document is missing components.schemas");return Q.schemas}function bX($){if(!F($))throw Error("OpenAPI document must be an object");let Q=b6($,{enforceOperationSchemaRefs:!0}),Z=NV($),X={schemas:Z,enumGroups:new Map},U=[],J=new Set;for(let[Y,W]of Object.entries(Z)){if(!F(W))throw Error(`Invalid schema '${Y}' in components.schemas`);let _=LV(Y,W,X);if(_)U.push(DX(_,J))}return U.push(...CV($,X,J)),{family:Q,dtoModels:U,enumGroups:[...X.enumGroups.values()].sort((Y,W)=>Y.name.localeCompare(W.name))}}function wV($){return`./${I6($).replace(/\.ts$/,"")}`}function PV($){return`../enums/${S9($).replace(/\.ts$/,"")}`}function fX($,Q,Z){let X=$.imports.get(Q)??new Set;X.add(Z),$.imports.set(Q,X)}function bV($,Q){let Z=C1(Q);if(Z===$.currentName)return;fX($,wV(Q),Z)}function kV($,Q){fX($,PV(Q),C1(Q))}function yX($){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test($)?$:JSON.stringify($)}function f9($){return[...new Set($)].join(" | ")}function vX($,Q,Z,X){let U=n1($,Z,X);if(U==="unknown")return"unknown";return f9([U,...Q])}function fV($,Q,Z){let X=Object.entries($.properties);if(X.length===0)return $.additionalProperties?`Record<string, ${n1($.additionalProperties,Q,Z)}>`:"Record<string, unknown>";let U=" ".repeat(Z),J=" ".repeat(Z+1),Y=["{"];for(let[W,_]of X){let G=$.required.includes(W)?"":"?";Y.push(`${J}${yX(W)}${G}: ${n1(_,Q,Z+1)};`)}if($.additionalProperties){let W=X.map(([_,G])=>{let z=$.required.includes(_)?[]:["undefined"];return f9([n1(G,Q,Z+1),...z])});Y.push(`${J}[key: string]: ${vX($.additionalProperties,W,Q,Z+1)};`)}return Y.push(`${U}}`),Y.join(`
|
|
126
|
+
`)}function n1($,Q,Z){if($.kind==="scalar")return $.scalar==="integer"?"number":$.scalar;if($.kind==="enum")return kV(Q,$.enumName),C1($.enumName);if($.kind==="ref")return bV(Q,$.refName),C1($.refName);if($.kind==="array")return`${n1($.items,Q,Z)}[]`;if($.kind==="unknown")return"unknown";return fV($,Q,Z)}function yV($,Q){let Z=$.optional?"?":"",X=!$.optional&&$.nullable?" | null":"";return`${$.description?` /** ${$.description.replace(/\*\//g,"*\\/")} */
|
|
127
|
+
`:""} ${yX($.name)}${Z}: ${n1($.schema,Q,1)}${X};`}function vV($,Q){if($.schema?.kind!=="object"||!$.schema.additionalProperties)return null;let Z=$.properties.map((X)=>{let U=X.optional?["undefined"]:[],J=!X.optional&&X.nullable?["null"]:[];return f9([n1(X.schema,Q,1),...J,...U])});return` [key: string]: ${vX($.schema.additionalProperties,Z,Q,1)};`}function xV($){let Q=[...$.imports.entries()].sort(([Z],[X])=>Z.localeCompare(X)).map(([Z,X])=>{return`import type { ${[...X].sort((J,Y)=>J.localeCompare(Y)).join(", ")} } from '${Z}';`});return Q.length>0?`${Q.join(`
|
|
125
128
|
`)}
|
|
126
129
|
|
|
127
|
-
`:""}function
|
|
128
|
-
`:"",U=$.properties.map((_)=>
|
|
129
|
-
`):" // empty schema";return`${
|
|
130
|
-
${
|
|
130
|
+
`:""}function gV($){let Q=C1($.schemaName),Z={currentName:Q,imports:new Map},X=$.description?`/** ${$.description.replace(/\*\//g,"*\\/")} */
|
|
131
|
+
`:"",U=$.properties.map((_)=>yV(_,Z)),J=vV($,Z),Y=[...U,...J?[J]:[]],W=Y.length>0?Y.join(`
|
|
132
|
+
`):" // empty schema";return`${xV(Z)}${X}export interface ${Q} {
|
|
133
|
+
${W}
|
|
131
134
|
}
|
|
132
|
-
`}function
|
|
135
|
+
`}function y($){return typeof $==="object"&&$!==null}function M1($){if(typeof $!=="string")return;let Q=$.trim();return Q.length>0?Q:void 0}function s$($){return $.replaceAll("\\","\\\\").replaceAll("'","\\'")}function B6($){if(typeof $==="string")return`'${s$($)}'`;if(typeof $==="number"||typeof $==="boolean")return String($);if($===null)return"null";if(Array.isArray($))return`[${$.map((Q)=>B6(Q)).join(", ")}]`;if(y($))return`{ ${Object.entries($).map(([Z,X])=>{return`${/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(Z)?Z:`'${s$(Z)}'`}: ${B6(X)}`}).join(", ")} }`;return"undefined"}function M0($,Q){let Z=$.match(new RegExp(`^#/components/${Q}/(.+)$`));if(!Z?.[1])throw Error(`Unsupported $ref '${$}'. Expected '#/components/${Q}/<Name>'`);return Z[1]}function xX($,Q){let Z=Q===A$.Post?q7:K7;for(let U of Z){let J=$[U];if(F(J))return{statusCode:U,response:J}}let X=Object.keys($).filter((U)=>B7.test(U)).sort((U,J)=>Number(U)-Number(J));for(let U of X){let J=$[U];if(F(J))return{statusCode:U,response:J}}return null}function dV($){let Q=y($.components)?$.components:{};return{schemas:y(Q.schemas)?Q.schemas:{},parameters:y(Q.parameters)?Q.parameters:{},requestBodies:y(Q.requestBodies)?Q.requestBodies:{},responses:y(Q.responses)?Q.responses:{}}}function mV($,Q){if(!$)return;if(typeof $.$ref==="string"){let Z=M0($.$ref,s1.Schemas),X=Q.schemas[Z];return y(X)?X:void 0}return $}function lV($){if(!$)return!1;if(Array.isArray($.enum))return!1;if(Array.isArray($.allOf))return!0;if($.type!=="object"&&!y($.properties))return!1;return y($.properties)&&Object.keys($.properties).length>0}function oZ($,Q){if(!$||typeof $.$ref!=="string")return;let Z=M0($.$ref,s1.Schemas),X=Q.schemas[Z];if(!y(X)||!lV(X))return;return{name:o1(Z),importPath:pV($)}}function pV($){if(!$||typeof $.$ref!=="string")throw Error("Expected schema $ref while building DTO import path");let Q=M0($.$ref,s1.Schemas);return`./dto/${C9(Q).replace(/\.ts$/,"")}`}function aZ($){return P6($)??void 0}function cV($,Q){let Z=$.requestBody;if(!y(Z))return;if(typeof Z.$ref==="string"){let X=M0(Z.$ref,s1.RequestBodies),U=Q.requestBodies[X];return y(U)?U:void 0}return Z}function nV($,Q){if(!y($))return;if(typeof $.$ref==="string"){let Z=M0($.$ref,s1.Responses),X=Q.responses[Z];return y(X)?X:void 0}return $}function iV($){if(!Array.isArray($))return;let Q=[];for(let Z of $){if(typeof Z!=="string"&&typeof Z!=="number"&&typeof Z!=="boolean")return;Q.push(Z)}return Q}function hX($,Q){let Z=mV($,Q);if(!Z)return{};let X=Z.type,U=iV(Z.enum),J=Z.example;if(X==="array"){let Y=y(Z.items)?Z.items:void 0,W=hX(Y,Q);return{typeCtor:W.typeCtor??V0.String,isArray:!0,enumValues:W.enumValues,example:J??W.example}}if(X==="string")return{typeCtor:V0.String,enumValues:U,example:J};if(X==="number"||X==="integer")return{typeCtor:V0.Number,enumValues:U,example:J};if(X==="boolean")return{typeCtor:V0.Boolean,enumValues:U,example:J};if(X==="object")return{typeCtor:V0.Object,enumValues:U,example:J};return{enumValues:U,example:J}}function rV($,Q){if(!y($))return;if(typeof $.$ref==="string"){let Z=M0($.$ref,s1.Parameters),X=Q.parameters[Z];return y(X)?X:void 0}return $}function oV($,Q){let Z=rV($,Q);if(!Z)return;let X=Z.in;if(X!==$$.Path&&X!==$$.Query)return;let U=M1(Z.name);if(!U)return;let J=y(Z.schema)?Z.schema:void 0,Y=hX(J,Q),W=Z.required===!0||X===$$.Path,_=M1(Z.description),G=Z.example??Y.example;return{location:X,name:U,required:W,description:_,typeCtor:Y.typeCtor,isArray:Y.isArray,enumValues:Y.enumValues,example:G}}function aV($,Q){if(!Array.isArray($))return{path:[],query:[]};let Z=new Map;for(let J of $){let Y=oV(J,Q);if(!Y)continue;Z.set(`${Y.location}:${Y.name}`,Y)}let X=[],U=[];for(let J of Z.values()){if(J.location===$$.Path)X.push(J);if(J.location===$$.Query)U.push(J)}return{path:X.sort((J,Y)=>J.name.localeCompare(Y.name)),query:U.sort((J,Y)=>J.name.localeCompare(Y.name))}}function sV($,Q){let Z=new Map,X=(U)=>{if(!Array.isArray(U))return;for(let J of U){if(!y(J))continue;if(typeof J.$ref==="string"){Z.set(J.$ref,J);continue}let Y=M1(J.in),W=M1(J.name);if(!Y||!W)continue;Z.set(`${Y}:${W}`,J)}};return X($),X(Q),[...Z.values()]}function $O($,Q){let Z=Q.replaceAll("{","").replaceAll("}","").replace(/\//g," ").trim(),X=`${$} ${Z||"root"}`;return eV(X)}function QO($,Q){let Z=$,X=2;while(Q.has(Z))Z=`${$}_${X}`,X+=1;return Q.add(Z),Z}function ZO($,Q,Z,X,U,J){let Y=M1(Z.operationId)??$O(Q,$),W=QO(A0(Y),J),_=sV(X,Z.parameters),G=aV(_,U),z=cV(Z,U),H=y(z?.content)?z.content:void 0,V=H?aZ(H):void 0,O=oZ(V,U),K=y(Z.responses)?Z.responses:{},q=xX(K,Q),B=q?nV(q.response,U):void 0,S=y(B?.content)?B.content:void 0,M=S?aZ(S):void 0,R=oZ(M,U),w=M1(B?.description),P=M1(Z.summary)??`${Q.toUpperCase()} ${$}`,l=M1(Z.description)??P;return{key:W,constantName:`SWG_${W}`,operationId:Y,method:Q.toUpperCase(),path:$,summary:P,description:l,bodyDtoName:O?.name,bodyDtoImportPath:O?.importPath,responseDtoName:R?.name,responseDtoImportPath:R?.importPath,responseDescription:w,paramDto:G.path,queryDto:G.query}}function XO($){let Q=y($.paths)?$.paths:{},Z=dV($),X=[],U=new Set;for(let[J,Y]of Object.entries(Q)){if(!y(Y))continue;let W=Y.parameters;for(let _ of uX){let G=Y[_];if(!y(G))continue;X.push(ZO(J,_,G,W,Z,U))}}return X.sort((J,Y)=>{let W=J.path.localeCompare(Y.path);if(W!==0)return W;return J.method.localeCompare(Y.method)})}function sZ($){let Q=[`name: '${s$($.name)}'`];if($.required===!0)Q.push("required: true");if($.description)Q.push(`description: '${s$($.description)}'`);if($.typeCtor)Q.push(`type: ${$.typeCtor}`);if($.isArray)Q.push("isArray: true");if($.enumValues&&$.enumValues.length>0)Q.push(`enum: ${B6($.enumValues)}`);if($.example!==void 0)Q.push(`example: ${B6($.example)}`);return`{ ${Q.join(", ")} }`}function JO($){let Q=[];if(Q.push("/**"),Q.push(` * ${$.summary}`),Q.push(` * @operationId ${$.operationId}`),Q.push(` * @route ${$.method} ${$.path}`),Q.push(" */"),Q.push(`export const ${$.constantName} = {`),Q.push(` operationId: '${s$($.operationId)}',`),Q.push(` method: '${$.method}',`),Q.push(` path: '${s$($.path)}',`),Q.push(` summary: '${s$($.summary)}',`),Q.push(` description: '${s$($.description)}',`),$.paramDto.length>0){let Z=$.paramDto.map((X)=>` ${sZ(X)}`).join(`,
|
|
133
136
|
`);Q.push(` paramDto: [
|
|
134
137
|
${Z}
|
|
135
|
-
],`)}if($.queryDto.length>0){let Z=$.queryDto.map((X)=>` ${
|
|
138
|
+
],`)}if($.queryDto.length>0){let Z=$.queryDto.map((X)=>` ${sZ(X)}`).join(`,
|
|
136
139
|
`);Q.push(` queryDto: [
|
|
137
140
|
${Z}
|
|
138
141
|
],`)}if($.bodyDtoName)Q.push(` bodyDto: ${$.bodyDtoName},`);if($.responseDtoName)Q.push(` responseDto: ${$.responseDtoName},`);if($.responseDescription)Q.push(` responseDescription: '${s$($.responseDescription)}',`);return Q.push("} as const;"),Q.join(`
|
|
139
|
-
`)}function
|
|
140
|
-
`;let Q=
|
|
142
|
+
`)}function YO($){if(!y($))return`export const SWAGGER_OPERATIONS = {} as const;
|
|
143
|
+
`;let Q=XO($),Z=new Map;for(let _ of Q){if(_.bodyDtoName&&_.bodyDtoImportPath){let G=Z.get(_.bodyDtoImportPath)??new Set;G.add(_.bodyDtoName),Z.set(_.bodyDtoImportPath,G)}if(_.responseDtoName&&_.responseDtoImportPath){let G=Z.get(_.responseDtoImportPath)??new Set;G.add(_.responseDtoName),Z.set(_.responseDtoImportPath,G)}}let X=[...Z.entries()].sort(([_],[G])=>_.localeCompare(G)).map(([_,G])=>{return`import { ${[...G].sort((H,V)=>H.localeCompare(V)).join(", ")} } from '${_}';`}).join(`
|
|
141
144
|
`),U=X.length>0?`${X}
|
|
142
145
|
|
|
143
146
|
`:"";if(Q.length===0)return`${U}export const SWAGGER_OPERATIONS = {} as const;
|
|
144
|
-
`;let
|
|
147
|
+
`;let J=Q.map((_)=>JO(_)).join(`
|
|
145
148
|
|
|
146
|
-
`),
|
|
149
|
+
`),W=`/** Generated OpenAPI operation metadata map. */
|
|
147
150
|
export const SWAGGER_OPERATIONS = {
|
|
148
151
|
${Q.map((_)=>` ${_.key}: ${_.constantName},`).join(`
|
|
149
152
|
`)}
|
|
150
|
-
} as const;`;return`${U}${
|
|
153
|
+
} as const;`;return`${U}${J}
|
|
151
154
|
|
|
152
|
-
${
|
|
153
|
-
`}async function
|
|
154
|
-
`):"export {};";return
|
|
155
|
-
`)}async function
|
|
156
|
-
`))_=!0;return _}async function
|
|
155
|
+
${W}
|
|
156
|
+
`}async function zO($){let Q;try{Q=await y9($,{withFileTypes:!0})}catch{return!1}let Z=!1;return await Promise.all(Q.filter((X)=>X.isFile()&&X.name.endsWith(M7)).map(async(X)=>{await Y2(Z$($,X.name),{force:!0}),Z=!0})),Z}async function mX($){try{await dX($)}catch{return!1}return await Y2($,{force:!0}),!0}async function tZ($){try{await dX($)}catch{return!1}return await Y2($,{recursive:!0,force:!0}),!0}async function v9($,Q){let Z;try{Z=await y9($,{withFileTypes:!0})}catch{return!1}let X=!1;return await Promise.all(Z.filter((U)=>U.isFile()&&U.name.endsWith(".ts")&&U.name!==H9&&!Q.has(U.name)).map(async(U)=>{await Y2(Z$($,U.name),{force:!0}),X=!0})),X}async function HO($,Q){let Z;try{Z=await y9($,{withFileTypes:!0})}catch{return!1}let X=!1;return await Promise.all(Z.filter((U)=>U.isFile()&&U.name.endsWith(".contract.ts")&&!Q.has(U.name)).map(async(U)=>{await Y2(Z$($,U.name),{force:!0}),X=!0})),X}async function _2($,Q,Z){return Z?q9($,Q):$}async function VO($,Q,Z,X){let U=!1,J=[],Y=new Set;for(let W of $.enumGroups){let _=S9(W.name);Y.add(_);let G=Z$(Q,_),z=await _2(tH(W),G,X);if(await W$(G,z))U=!0;if(J.push(`./${_.replace(/\.ts$/,"")}`),Z)W2.step(` \u2713 ${G}`)}if(await v9(Q,Y))U=!0;if(await L0(Q,J.sort()))U=!0;return U}async function OO($,Q,Z){let X=!1;for(let U of $.enumGroups){let J=I6(U.name);if(!Q.has(J)){let Y=Z$(Z,J);if(await mX(Y))X=!0}}return X}async function KO($,Q,Z,X){let U=!1,J=[],Y=new Set;for(let W of $){let _=I6(W.schemaName);if(Y.has(_))throw Error(`Duplicate OpenAPI model output file '${_}'`);Y.add(_);let G=Z$(Q,_),z=await _2(gV(W),G,X);if(await W$(G,z))U=!0;if(J.push(`./${_.replace(/\.ts$/,"")}`),Z)W2.step(` \u2713 ${G}`)}if(await v9(Q,Y))U=!0;if(await L0(Q,J.sort()))U=!0;return U}async function qO($,Q,Z,X){let U=!1,J=[],Y=new Set,W=new Map;for(let _ of $.dtoModels.filter((G)=>G.properties.length>0)){let G=C9(_.schemaName);if(Y.has(G))throw Error(`Duplicate OpenAPI DTO output file '${G}'`);let z=o1(_.schemaName),H=W.get(z);if(H)throw Error(`Duplicate OpenAPI DTO class symbol '${z}' from schemas '${H}' and '${_.schemaName}'`);W.set(z,_.schemaName),Y.add(G);let V=Z$(Q,G),O=await _2(aH(_),V,X);if(await W$(V,O))U=!0;if(J.push(`./${G.replace(M7,".dto")}`),Z)W2.step(` \u2713 ${V}`)}if(await v9(Q,Y))U=!0;return{changed:U,dtoExports:J}}async function BO($,Q,Z,X){let U=!1,J=[],Y=new Set;for(let W of $){let _=HX(W.schemaName);if(Y.has(_))throw Error(`Duplicate OpenAPI contract output file '${_}'`);Y.add(_);let G=Z$(Q,_),z=await _2(CH(W),G,X);if(await W$(G,z))U=!0;if(J.push(`./${_.replace(/\.ts$/,"")}`),Z)W2.step(` \u2713 ${G}`)}if(await HO(Q,Y))U=!0;return{changed:U,contractExports:J}}async function LO($,Q,Z,X){let U=!1,J=await BO($,Q,Z,X);if(J.changed)U=!0;if(await L0(Q,J.contractExports.sort()))U=!0;return U}async function AO($,Q,Z,X,U,J){let Y=!1,W=await qO($,Z,U,J);if(W.changed)Y=!0;if(await L0(Z,W.dtoExports.sort()))Y=!0;let _=await _2(YO(Q),X,J);if(await W$(X,_))Y=!0;if(U)W2.step(` \u2713 ${X}`);return Y}function lX($){return`export * from '${$}';`}function J9($,Q){return`export * as ${$} from '${Q}';`}async function MO($,Q){let Z=Q.length>0?Q.sort().join(`
|
|
157
|
+
`):"export {};";return W$(Z$($,H9),`${Z}
|
|
158
|
+
`)}async function jO($){return await zO($)}async function TO($,Q,Z,X,U,J,Y,W,_){let{httpDir:G,dtoDir:z}=X,H=Z$(G,"zod"),V=Z$(G,"swagger.ts"),O=!1;if(U){if(await LO(Z,H,Y,W))O=!0;_.push(J9("ZodContracts","./zod"))}else if(await tZ(H))O=!0;if(J){if(await AO($,Q,z,V,Y,W))O=!0;_.push(J9("Dtos","./dto"),lX("./swagger"))}else{let K=await tZ(z),q=await mX(V);if(K||q)O=!0}return O}async function EO($,Q,Z,X,U){let{httpDir:J,enumDir:Y,modelDir:W}=Z,_=!1,G=await GO.parse($,{validate:{spec:!1}});b6(G,{enforceOperationSchemaRefs:!0});let z=bX(G),H=z.dtoModels.filter((S)=>S.source!=="operation"),V=new Set(H.map((S)=>I6(S.schemaName))),O=U.dtos===!0,K=U.zod===!0||!O,q=U.formatFiles!==!1;_=await jO(J)||_;let B=[J9("Models","./models"),lX("./enums")];if(await VO(z,Y,X,q))_=!0;if(await OO(z,V,W))_=!0;if(await KO(H,W,X,q))_=!0;if(await TO(z,G,H,Z,K,O,X,q,B))_=!0;if(await MO(J,B))_=!0;if(await W$(Z$(Q,H9),`export * as HttpSchemas from './http';
|
|
159
|
+
`))_=!0;return _}async function CO($,Q,Z,X={}){let U=_O(Q);try{let J=Z$(Q,"http"),Y={httpDir:J,dtoDir:Z$(J,"dto"),enumDir:Z$(J,"enums"),modelDir:Z$(J,"models")},W=await EO($,Q,Y,Z,X);return{success:!0,service:U,changed:W}}catch(J){return{success:!1,service:U,error:J instanceof Error?J:Error(String(J))}}}function c($){return typeof $==="object"&&$!==null}function L6($){if(typeof $!=="string")return;let Q=$.trim();return Q.length>0?Q:void 0}function IO($){return $.replaceAll("\\","\\\\").replaceAll("'","\\'")}function c$($){return`'${IO($)}'`}function O0($){return`${wO}${$}}`}function h9($){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test($)}function G2($){return h9($)?$:JSON.stringify($)}function pX($,Q){return h9(Q)?`${$}.${Q}`:`${$}[${JSON.stringify(Q)}]`}function cX($,Q){if(Q==="PascalCase")return x9($);if(Q==="snake_case")return g9($);if(Q==="original")return $;return f6($)}function DO($,Q){if(Q==="PascalCase")return x9($);if(Q==="snake_case")return g9($);if(Q==="original")return $;return f6($)}function RO($,Q){if(Q==="camelCase")return f6(String($));if(Q==="snake_case")return g9(String($));if(Q==="UPPERCASE")return FO(String($));if(Q==="original")return String($);return x9(String($))}function nX($){let Q=f6($);return/^[A-Za-z_$]/.test(Q)?Q:`_${Q}`}function NO($){let Q=h9($)?$:nX($);return L7.has(Q)?`${Q}Value`:Q}function iX($){return $.modelPropertyNaming??($.type===N.TypeScriptAngular?"original":"camelCase")}function z2($){return $.useSingleRequestParameter??$.type===N.TypeScriptFetch}function u9($,Q){let Z=$.match(new RegExp(`^#/components/${Q}/(.+)$`));if(!Z?.[1])throw Error(`Unsupported $ref '${$}'`);return Z[1]}function m9($){return $.map((Q)=>{let Z=Q.parameters.map((U)=>{let J=U.required?"":"?";return` ${G2(U.name)}${J}: ${U.typeName};`});if(Q.bodyType)Z.push(` body: ${Q.bodyType};`);let X=Z.length>0?Z.join(`
|
|
157
160
|
`):" [key: string]: never;";return`export interface ${Q.requestName} {
|
|
158
161
|
${X}
|
|
159
|
-
}`})}function
|
|
160
|
-
`)}function
|
|
162
|
+
}`})}function PO(){return["export interface DecodeJson {"," <T>(value: unknown, operationId: string): T;","}","","export interface RequestConfig {"," baseUrl?: string;"," headers?: HeadersInit;"," fetch?: typeof fetch;"," decodeJson?: DecodeJson;","}","","export function buildPath(template: string, params: Record<string, unknown>): string {"," return template.replace(/\\{([^}]+)\\}/g, (_match, key: string) => {"," const value = params[key];"," if (value === undefined || value === null) {",` throw new Error(\`Missing required path parameter '${O0("key")}'\`);`," }"," return encodeURIComponent(String(value));"," });","}","","export function buildQuery(params: Record<string, unknown>): string {"," const search = new URLSearchParams();"," for (const [key, value] of Object.entries(params)) {"," if (value === undefined || value === null) continue;"," if (Array.isArray(value)) {"," for (const item of value) search.append(key, String(item));"," continue;"," }"," search.set(key, String(value));"," }"," const query = search.toString();",` return query ? \`?${O0("query")}\` : '';`,"}","","export async function parseUnknownJsonResponse(response: Response): Promise<unknown> {"," if (response.status === 204) return undefined;"," const responseText = await response.text();"," return responseText.length > 0 ? JSON.parse(responseText) : undefined;","}","","export async function parseJsonResponse<T>("," response: Response,"," operationId: string,"," decodeJson: DecodeJson","): Promise<T> {"," const value = await parseUnknownJsonResponse(response);"," return decodeJson<T>(value, operationId);","}"].join(`
|
|
163
|
+
`)}function l9($){return{pathParams:$.parameters.filter((Q)=>Q.location===$$.Path),queryParams:$.parameters.filter((Q)=>Q.location===$$.Query)}}function e0($,Q){return $.map((Z)=>{let X=Q?pX("request",Z.name):Z.variableName;return`${G2(Z.wireName)}: ${X}`}).join(", ")}function bO($,Q){if($.length===0)return[];let Z=[" let params = new HttpParams();"];for(let X of $){let U=Q?pX("request",X.name):X.variableName;Z.push(` if (Array.isArray(${U})) {`,` for (const item of ${U}) params = params.append(${c$(X.wireName)}, String(item));`,` } else if (${U} !== undefined && ${U} !== null) {`,` params = params.set(${c$(X.wireName)}, String(${U}));`," }")}return Z}function p9($,Q){if(z2(Q)){let U=$.parameters.length===0&&!$.bodyType?" = {}":"";return`request: ${$.requestName}${U}`}let X=$.parameters.map((U)=>{let J=U.required?"":"?";return`${U.variableName}${J}: ${U.typeName}`});if($.bodyType)X.push(`body: ${$.bodyType}`);return X.join(", ")}function c9($){return z2($)?"request.body":"body"}function B0($){return $}function kO($){if($.responseType==="unknown")return[" return parseUnknownJsonResponse(response);"];return[" if (!this.config.decodeJson) {",` throw new Error(${c$(`Missing JSON decoder for operation '${$.operationId}'`)});`," }",` return parseJsonResponse<${B0($.responseType)}>(response, ${c$($.operationId)}, this.config.decodeJson);`]}function fO($,Q,Z){let X=["import type { RequestConfig } from './runtime';","import { buildPath, buildQuery, parseJsonResponse, parseUnknownJsonResponse } from './runtime';","import type * as Models from './models';","",...m9($),"",`export class ${d9(Q)}FetchClient {`," constructor(private readonly config: RequestConfig = {}) {}"];for(let U of $){let{pathParams:J,queryParams:Y}=l9(U),W=z2(Z),_=U.bodyType?`body: JSON.stringify(${c9(Z)}),`:"",G=U.bodyType?"headers: { 'content-type': 'application/json', ...this.config.headers },":"headers: this.config.headers,";X.push(` async ${U.functionName}(${p9(U,Z)}): Promise<${B0(U.responseType)}> {`,` const path = buildPath(${c$(U.path)}, { ${e0(J,W)} });`,` const query = buildQuery({ ${e0(Y,W)} });`," const fetchImpl = this.config.fetch ?? fetch;",` const response = await fetchImpl(\`${O0("this.config.baseUrl ?? ''")}${O0("path")}${O0("query")}\`, {`,` method: ${c$(U.method)},`,` ${G}`,` ${_}`," });",` if (!response.ok) throw new Error(\`Request failed with status ${O0("response.status")}\`);`,...kO(U)," }")}return X.push("}",""),`${X.join(`
|
|
161
164
|
`)}
|
|
162
|
-
`}function
|
|
165
|
+
`}function yO($,Q,Z){let U=["import axios, { type AxiosInstance, type AxiosRequestConfig } from 'axios';",$.some((J)=>J.parameters.some((Y)=>Y.location===$$.Query))?"import { buildPath, buildQuery } from './runtime';":"import { buildPath } from './runtime';","import type * as Models from './models';","","export interface AxiosClientConfig {"," baseURL?: string;"," axios?: AxiosInstance;"," requestConfig?: AxiosRequestConfig;","}","",...m9($),"",`export class ${d9(Q)}AxiosClient {`," private readonly client: AxiosInstance;",""," constructor(private readonly config: AxiosClientConfig = {}) {"," this.client = config.axios ?? axios.create({ baseURL: config.baseURL });"," }"];for(let J of $){let{pathParams:Y,queryParams:W}=l9(J),_=z2(Z),G=J.bodyType?`data: ${c9(Z)},`:"",z=W.length?`params: { ${e0(W,_)} },`:"",H=W.length?"paramsSerializer: (params: Record<string, unknown>) => buildQuery(params).slice(1),":"";U.push(` async ${J.functionName}(${p9(J,Z)}): Promise<${B0(J.responseType)}> {`,` const url = buildPath(${c$(J.path)}, { ${e0(Y,_)} });`,` const response = await this.client.request<${B0(J.responseType)}>({`," ...this.config.requestConfig,"," url,",` method: ${c$(J.method)},`,` ${z}`,` ${H}`,` ${G}`," });"," return response.data;"," }")}return U.push("}",""),`${U.join(`
|
|
163
166
|
`)}
|
|
164
|
-
`}function
|
|
167
|
+
`}function vO($,Q,Z,X){let Y=["import { Injectable } from '@angular/core';",$.some((W)=>W.parameters.some((_)=>_.location===$$.Query))?"import { HttpClient, HttpParams } from '@angular/common/http';":"import { HttpClient } from '@angular/common/http';","import type { Observable } from 'rxjs';","import { buildPath } from './runtime';","import type * as Models from './models';","",...m9($),"",`@Injectable({ providedIn: ${c$(X)} })`,`export class ${d9(Q)}ApiService {`," constructor(private readonly http: HttpClient, private readonly baseUrl = '') {}"];for(let W of $){let{pathParams:_,queryParams:G}=l9(W),z=z2(Z),H=G.length>0?"{ params }":"{}",V=W.bodyType?`${c9(Z)}, `:"",O=W.method.toLowerCase(),K=W.bodyType||O!==A$.Get?`\`\${this.baseUrl}\${path}\`, ${V}${H}`:`\`\${this.baseUrl}\${path}\`, ${H}`;Y.push(` ${W.functionName}(${p9(W,Z)}): Observable<${B0(W.responseType)}> {`,` const path = buildPath(${c$(W.path)}, { ${e0(_,z)} });`,...bO(G,z),` return this.http.${O}<${B0(W.responseType)}>(${K});`," }")}return Y.push("}",""),`${Y.join(`
|
|
165
168
|
`)}
|
|
166
|
-
`}function
|
|
167
|
-
${
|
|
169
|
+
`}function xO($,Q,Z){if(Z.type===N.TypeScriptAxios)return yO($,Q,Z);if(Z.type===N.TypeScriptAngular)return vO($,Q,Z,Z.providedIn??"root");return fO($,Q,Z)}function A6($){return[...new Set($)].join(" | ")}function i9($){if(!$)return"unknown";if(typeof $.$ref==="string")return n9(u9($.$ref,"schemas"));if(Array.isArray($.enum))return $.enum.map((Q)=>JSON.stringify(Q)).join(" | ");if($.type==="integer"||$.type==="number")return"number";if($.type==="boolean")return"boolean";if($.type==="array"){let Q=c($.items)?$.items:void 0;return`Array<${i9(Q)}>`}if($.type==="object")return"Record<string, unknown>";return"string"}function hO($,Q,Z){if($.kind!=="object")return t$($,Q,Z);let X=Object.entries($.properties);if(X.length===0)return $.additionalProperties?`Record<string, ${t$($.additionalProperties,Q,Z)}>`:"Record<string, unknown>";let U=" ".repeat(Z),J=" ".repeat(Z+1),Y=iX(Q),W=X.map(([_,G])=>{let z=cX(_,Y),H=$.required.includes(_)?"":"?";return`${J}${G2(z)}${H}: ${t$(G,Q,Z+1)};`});if($.additionalProperties){let _=t$($.additionalProperties,Q,Z+1),G=X.map(([z,H])=>{let V=$.required.includes(z)?[]:["undefined"];return A6([t$(H,Q,Z+1),...V])});W.push(`${J}[key: string]: ${_==="unknown"?"unknown":A6([_,...G])};`)}return`{
|
|
170
|
+
${W.join(`
|
|
168
171
|
`)}
|
|
169
|
-
${U}}`}function t$($,Q,Z=1){if($.kind==="ref")return
|
|
172
|
+
${U}}`}function t$($,Q,Z=1){if($.kind==="ref")return C1($.refName);if($.kind==="enum")return n9($.enumName);if($.kind==="array")return`Array<${t$($.items,Q,Z)}>`;if($.kind==="object")return hO($,Q,Z);if($.kind==="unknown")return"unknown";if($.scalar==="integer")return"number";return $.scalar}function uO($,Q){let Z=[...$];if(Q.enumUnknownDefaultCase===!0&&Z.every((X)=>typeof X==="string"))Z.push(iO);return Z}function dO($,Q,Z){let X=n9($),U=uO(Q,Z).map((J)=>({key:RO(J,Z.enumPropertyNaming),value:J}));return[`export const ${X} = {`,...U.map((J)=>` ${G2(J.key)}: ${JSON.stringify(J.value)},`),"} as const;",`export type ${X} = (typeof ${X})[keyof typeof ${X}];`]}function mO($,Q){return Q.sortModelPropertiesByRequiredFlag===!1?$.properties:[...$.properties].sort((Z,X)=>Number(Z.optional)-Number(X.optional))}function lO($,Q,Z){let X=cX($.name,Z),U=t$($.schema,Q),J=$.optional?"?":"",Y=$.nullable?" | null":"";return` ${G2(X)}${J}: ${U}${Y};`}function pO($,Q){let Z=$.optional?["undefined"]:[],X=$.nullable?["null"]:[];return A6([t$($.schema,Q),...X,...Z])}function cO($,Q,Z){if($.schema?.kind!=="object"||!$.schema.additionalProperties)return null;let X=t$($.schema.additionalProperties,Z),U=Q.map((J)=>pO(J,Z));return` [key: string]: ${X==="unknown"?"unknown":A6([X,...U])};`}function nO($,Q){let Z=iX(Q),X=mO($,Q),U=[`export interface ${C1($.schemaName)} {`];U.push(...X.map((Y)=>lO(Y,Q,Z)));let J=cO($,X,Q);if(J)U.push(J);if(X.length===0&&!J)U.push(" // empty schema");return U.push("}"),U}function rX($,Q){let Z=["/* Generated by Kontract. */"];for(let X of $.enumGroups)Z.push(...dO(X.name,X.values,Q));for(let X of $.dtoModels)Z.push(...nO(X,Q));return`${Z.join(`
|
|
170
173
|
|
|
171
174
|
`)}
|
|
172
|
-
`}function bO($){let Q=c($.components)?$.components:{};return{schemas:c(Q.schemas)?Q.schemas:{},parameters:c(Q.parameters)?Q.parameters:{},requestBodies:c(Q.requestBodies)?Q.requestBodies:{},responses:c(Q.responses)?Q.responses:{}}}function m9($,Q,Z){if(!c($)||typeof $.$ref!=="string")return $;let X=f9($.$ref,Z);return Q[Z][X]}function kO($,Q){return wO(`${$} ${Q.replaceAll("{","").replaceAll("}","").replace(/\//g," ")}`)}function PO($){if(!Array.isArray($.enum))return null;let Q=[];for(let Z of $.enum){if(typeof Z!=="string"&&typeof Z!=="number")return null;Q.push(Z)}return Q.length>0?Q:null}function fO($,Q,Z){let X=L1(Q),U=$.get(X);if(U){if(!(U.values.length===Z.length&&U.values.every((J,G)=>J===Z[G])))throw Error(`Inline SDK enum name collision for '${X}'`);return`Models.${L1(U.name)}`}return $.set(X,{name:X,schemaPath:`sdk:inline:${X}`,values:Z,members:Z.map((W)=>({key:JX(W),value:W}))}),`Models.${X}`}function Q8($,Q,Z){if(!$)return null;if(typeof $.$ref==="string")return`Models.${L1(f9($.$ref,"schemas"))}`;let X=PO($);if(X)return fO(Q,Z,X);if($.type==="integer"||$.type==="number")return"number";if($.type==="boolean")return"boolean";if($.type==="array"){let U=c($.items)?$.items:void 0;return`Array<${Q8(U,Q,`${Z}Item`)??d9(U)}>`}if($.type==="object")return"Record<string, unknown>";return"string"}function yO($,Q){let Z=m9($,Q,"parameters");return c(Z)?Z:null}function vO($,Q){let Z=[...Array.isArray($)?$:[],...Array.isArray(Q)?Q:[]],X=new Map;for(let U of Z){if(!c(U))continue;if(typeof U.$ref==="string"){X.set(U.$ref,U);continue}let W=H8(U.in),J=H8(U.name);if(W&&J)X.set(`${W}:${J}`,U)}return[...X.values()]}function xO($,Q){let Z=m9($.requestBody,Q,"requestBodies");if(!c(Z)||!c(Z.content))return;return F8(Z.content)??void 0}function gO($,Q,Z){let X=c($.responses)?$.responses:{},U=bX(X,Z);if(!U)return;let W=m9(U.response,Q,"responses");if(!c(W)||!c(W.content))return;return F8(W.content)??void 0}function hO($,Q){let Z=c($.paths)?$.paths:{},X=bO($),U=[],W=new Map;for(let[J,G]of Object.entries(Z)){if(!c(G))continue;for(let _ of pX){let Y=G[_];if(!c(Y))continue;let z=H8(Y.operationId)??kO(_,J),V=vO(G.parameters,Y.parameters).map((I)=>yO(I,X)).filter((I)=>Boolean(I)).filter((I)=>I.in===e.Path||I.in===e.Query).map((I)=>{let y=H8(I.name)??"param",N=YO(y,Q.paramNaming),w=I.in===e.Path?e.Path:e.Query,l=c(I.schema)?I.schema:void 0,v=`${L1(z)}${L1(y)}`;return{name:N,variableName:HO(N),wireName:y,location:w,required:I.required===!0||w===e.Path,typeName:Q8(l,W,v)??d9(l)}}),O=Q.sortParamsByRequiredFlag===!1?V:V.sort((I,y)=>Number(!I.required)-Number(!y.required)),K=xO(Y,X),L=gO(Y,X,_),q=Q8(L,W,`${L1(z)}Response`)??"unknown",S=Q8(K,W,`${L1(z)}RequestBody`);U.push({operationId:z,method:_.toUpperCase(),path:J,functionName:uX(z),requestName:`${L1(z)}Request`,responseType:q,bodyType:S,parameters:O})}}return{operations:U.sort((J,G)=>J.operationId.localeCompare(G.operationId)),inlineEnumGroups:[...W.values()].sort((J,G)=>J.name.localeCompare(G.name))}}async function iX($,Q,Z){return Z?Y9($,Q):$}async function lO($,Q,Z,X,U){let W=!1,J=cX(Q,"models.ts"),G=await iX(mX($,Z),J,U);if(await J$(J,G))W=!0;if(X)nX.step(` \u2713 ${J}`);if(await L0(Q,["./models"]))W=!0;return W}async function pO($,Q,Z,X,U,W,J){let G=!1,{operations:_,inlineEnumGroups:Y}=hO($,U),z=new Set(Q.enumGroups.map((O)=>O.name)),H={...Q,enumGroups:[...Q.enumGroups,...Y.filter((O)=>!z.has(O.name))]},V=[["models.ts",mX(H,U)],["runtime.ts",OO()],["api.ts",MO(_,X,U)]];for(let[O,K]of V){let L=cX(Z,O),q=await iX(K,L,J);if(await J$(L,q))G=!0;if(W)nX.step(` \u2713 ${L}`)}if(await L0(Z,["./models","./api"]))G=!0;return G}async function cO($,Q,Z,X,U={}){let W=dO(Q);try{let J=await mO.parse($,{validate:{spec:!1}});if(I8(J,{enforceOperationSchemaRefs:!0}),!c(J))throw Error("OpenAPI document must be an object");let G=IX(J);if(Z.type===R.TypeScriptModels){let Y=await lO(G,Q,Z,X,U.formatFiles!==!1);return{success:!0,service:W,changed:Y}}let _=await pO(J,G,Q,W,Z,X,U.formatFiles!==!1);return{success:!0,service:W,changed:_}}catch(J){return{success:!1,service:W,error:J instanceof Error?J:Error(String(J))}}}function iO($){if($.success)return{success:!0,service:$.service,changed:$.changed};let Q=Error($.message);if($.stack)Q.stack=$.stack;return{success:!1,service:$.service,error:Q}}function rO(){let $=new Worker(new URL("./generate-worker.ts",import.meta.url).href),Q={worker:$,pending:new Map};return $.onmessage=(Z)=>{let X=Q.pending.get(Z.data.id);if(!X)return;Q.pending.delete(Z.data.id),X.resolve(iO(Z.data.result))},$.onerror=(Z)=>{let X=Error(Z.message||"Kontract worker failed");for(let U of Q.pending.values())U.reject(X);Q.pending.clear()},Q}function oO($){let Q=Math.max(1,Math.floor($)),Z=Array.from({length:Q},()=>rO()),X=1,U=0;return{run:(G)=>{let _=Z[U]??Z[0];if(!_)return Promise.reject(Error("Kontract worker pool has no available workers"));U=(U+1)%Z.length;let Y=X;X+=1;let z={id:Y,task:G};return new Promise((H,V)=>{k("worker.tasks"),_.pending.set(Y,{resolve:H,reject:V}),_.worker.postMessage(z)})},close:async()=>{await Promise.all(Z.map((G)=>G.worker.terminate()))}}}function aO($){let Q=Z8;return Z8=$,()=>{Z8=Q}}function sO($){return Z8?.run($)??null}async function i5($){if($.kind===K0.OpenApiNestJs)return WO($.inputFile,$.outputDir,$.verbose,$.options);if($.kind===K0.OpenApiSdk)return cO($.inputFile,$.outputDir,$.generator,$.verbose,{formatFiles:$.formatFiles});return tz($.inputFile,$.outputDir,$.verbose,{sharedTypesImportPath:$.sharedTypesImportPath,sharedTypesOutputFile:$.sharedTypesOutputFile,addressPrefix:$.addressPrefix,formatFiles:$.formatFiles})}async function $9($){let Q=sO($);if(!Q)return i5($);try{return await Q}catch{return k("worker.fallbacks"),i5($)}}function eO($){return $.type!==R.AsyncApiNats}function $K($){return $.type===R.AsyncApiNats}function QK($){return $.type===R.TypeScriptFetch||$.type===R.TypeScriptAxios||$.type===R.TypeScriptAngular}function ZK($){return QK($)||$.type===R.TypeScriptModels}function XK($){let Q=$.source?$.config.sources.filter((Z)=>Z.name===$.source):$.config.sources;if(Q.length===0)throw Error(`No kontract source named '${$.source}'`);return Q}function UK($){let Q=[];for(let Z of XK($)){let X=$.target?Z.targets.filter((U)=>U.name===$.target):Z.targets;for(let U of X)Q.push({sourceName:Z.name,targetName:U.name,inputDir:r5(Z.input),outputDir:r5(U.output),generator:U.generator})}if($.target&&Q.length===0)throw Error(`No kontract target named '${$.target}'`);return Q}async function WK($){let Q=new Map;for(let X of $)if(!Q.has(X.sourceName))Q.set(X.sourceName,X);let Z=[];for(let X of Q.values()){let[U,W]=await Y$("discovery",()=>Promise.all([eZ(X.inputDir),$X(X.inputDir)]));Z.push({sourceName:X.sourceName,inputDir:X.inputDir,openApiRoots:U,asyncApiGroups:W})}return Z}function o5($,Q){return Q?$.filter((Z)=>Z.name===Q):[...$]}async function JK($,Q){if(await Q9(Q,{recursive:!0}),$.files.length===0)throw Error(`No AsyncAPI files found for service '${$.name}'`);if($.files.length===1){let U=$.files[0];if(!U)throw Error(`Missing AsyncAPI file for service '${$.name}'`);return{specFile:U,cleanup:null}}let Z=e$(Q,r6($.name)),X=await Xz($.files,Z);if(!X.success)throw X.error;return{specFile:X.outputPath,cleanup:()=>oX(Z,{force:!0})}}async function GK($,Q){let Z=X8.get(Q);if(Z)return k("bundle.cacheCoalescedHits"),Z;if(await Bun.file(Q).exists())return k("bundle.cacheHits"),{specFile:Q,cleanup:null};k("bundle.cacheMisses");let X=Y$("bundle.openapi",async()=>{let U=await aZ([$.rootFile],Q);if(!U.success)throw U.error;return{specFile:U.outputPath,cleanup:null}});X8.set(Q,X);try{return await X}finally{X8.delete(Q)}}async function _K($,Q,Z,X){if(await Q9(Q,{recursive:!0}),!await Y$("bundle.decision",()=>VK($.rootFile)))return k("bundle.skippedInternalRefs"),{specFile:$.rootFile,cleanup:null};if(X){let G=e$(Q,_4);await Q9(G,{recursive:!0});let _=O0(Z).slice(0,24),Y=e$(G,r6(`${$.name}-${_}`));if(await Bun.file(Y).exists())return k("bundle.cacheHits"),{specFile:Y,cleanup:null};return GK($,Y)}let W=e$(Q,r6($.name)),J=await Y$("bundle.openapi",()=>aZ([$.rootFile],W));if(!J.success)throw J.error;return{specFile:J.outputPath,cleanup:()=>oX(W,{force:!0})}}function YK($){return $.match(/\$ref\s*:\s*['"]?([^'"\s]+)['"]?\s*$/)?.[1]??null}function zK($){return/\$ref\s*:\s*$/.test($)||/\$ref\s*:\s*[|>]/.test($)}function HK($){for(let Q of $.split(/\r?\n/)){if(!Q.includes("$ref"))continue;if(zK(Q))return null;let Z=YK(Q);if(!Z)return null;if(!Z.startsWith("#"))return!0}return!1}async function VK($){try{let Q=HK(await Bun.file($).text());if(Q===null)return k("bundle.ambiguousRefs"),!0;return Q}catch{return!0}}function OK($,Q){let Z=Q.find((X)=>X.sourceName===$.sourceName);if(!Z)throw Error(`Missing discovery result for source '${$.sourceName}'`);return Z}function KK($){if($.generator.type===R.TypeScriptNestJs)return W$.Http;if($.generator.type===R.TypeScriptModels)return W$.Models;return W$.Sdk}async function qK($,Q,Z,X){if($.generator.type===R.TypeScriptNestJs)return $9({kind:K0.OpenApiNestJs,inputFile:Z.specFile,outputDir:Q,verbose:X.verbose,options:{zod:$.generator.zod===!0,dtos:$.generator.dtos===!0,formatFiles:!1}});if(!ZK($.generator))throw Error(`Generator '${$.generator.type}' cannot emit OpenAPI TypeScript`);return $9({kind:K0.OpenApiSdk,inputFile:Z.specFile,outputDir:Q,generator:$.generator,verbose:X.verbose,formatFiles:!1})}function LK($,Q,Z,X){let U=KK($);return{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,outputDir:$.outputDir,channel:U,run:async()=>{let W=null,J=B8(Z,$),G=e$($.outputDir,Q.name),_=await PZ([Q.rootFile]),Y=xZ(J,U,Q.name);if((await gZ({sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:U,generator:$.generator,manifestPath:Y,source:_,outputDir:G})).skipped)return{success:!0,service:Q.name,changed:!1,skippedByManifest:!0};try{let H=_.safe?FZ(Z,$.sourceName):J,V=await _K(Q,H,_.hash,_.safe);W=V.cleanup;let O=await qK($,G,V,X);return O.success?{...O,manifest:{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:U,generator:$.generator,manifestPath:Y,source:_,outputDir:G}}:O}finally{if(W)await W()}}}}function BK($,Q,Z){return{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,outputDir:$.outputDir,channel:W$.Nats,run:async()=>{let X=null,U=B8(Z,$),W=e$($.outputDir,Q.name),J=e$($.outputDir,KZ),G=await PZ(Q.files),_=xZ(U,W$.Nats,Q.name);if((await gZ({sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:W$.Nats,generator:$.generator,manifestPath:_,source:G,outputDir:W,additionalOutputDirs:[J]})).skipped)return{success:!0,service:Q.name,changed:!1,skippedByManifest:!0};try{let z=await JK(Q,U);X=z.cleanup;let H=e$(J,"runtime.ts"),V=e4(e$(W,"nats"),H),O=await $9({kind:K0.AsyncApiNats,inputFile:z.specFile,outputDir:W,verbose:!1,sharedTypesImportPath:V,sharedTypesOutputFile:H,addressPrefix:$.generator.type===R.AsyncApiNats?$.generator.prefix:void 0,formatFiles:!1});return O.success?{...O,manifest:{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:W$.Nats,generator:$.generator,manifestPath:_,source:G,outputDir:W,additionalOutputDirs:[J]}}:O}finally{if(X)await X()}}}}function AK($,Q,Z,X){let U=[];for(let W of $){let J=OK(W,Q);if(eO(W.generator)){let G=o5(J.openApiRoots,X.specific);U.push(...G.map((_)=>LK(W,_,Z,X)))}if($K(W.generator)){let G=o5(J.asyncApiGroups,X.specific);U.push(...G.map((_)=>BK(W,_,Z)))}}return U}async function MK($){let Q=UK($),Z=t4(Q),X=await WK(Q),U=AK(Q,X,Z,$);return{jobs:Q,discovered:X,workItems:U,cacheRoot:Z}}function CK($){if($===W$.Http)return W$.Http;if($===W$.Nats)return W$.Nats;if($===W$.Models)return W$.Models;return W$.Sdk}async function FK($,Q){let Z=new Set;for(let X of $){let U=await v3({cwd:process.cwd(),inputDir:X.inputDir,outputDir:X.outputDir,generators:[X.generator]});for(let W of U){let J=`${W.title}
|
|
173
|
-
${
|
|
174
|
-
`));else if(!Z&&X&&
|
|
175
|
-
`).map((
|
|
176
|
-
`):void 0}}function
|
|
175
|
+
`}function oO($){let Q=c($.components)?$.components:{};return{schemas:c(Q.schemas)?Q.schemas:{},parameters:c(Q.parameters)?Q.parameters:{},requestBodies:c(Q.requestBodies)?Q.requestBodies:{},responses:c(Q.responses)?Q.responses:{}}}function r9($,Q,Z){if(!c($)||typeof $.$ref!=="string")return $;let X=u9($.$ref,Z);return Q[Z][X]}function aO($,Q){return rO(`${$} ${Q.replaceAll("{","").replaceAll("}","").replace(/\//g," ")}`)}function sO($){if(!Array.isArray($.enum))return null;let Q=[];for(let Z of $.enum){if(typeof Z!=="string"&&typeof Z!=="number")return null;Q.push(Z)}return Q.length>0?Q:null}function tO($,Q,Z){let X=B1(Q),U=$.get(X);if(U){if(!(U.values.length===Z.length&&U.values.every((Y,W)=>Y===Z[W])))throw Error(`Inline SDK enum name collision for '${X}'`);return`Models.${B1(U.name)}`}return $.set(X,{name:X,schemaPath:`sdk:inline:${X}`,values:Z,members:Z.map((J)=>({key:VX(J),value:J}))}),`Models.${X}`}function W6($,Q,Z){if(!$)return null;if(typeof $.$ref==="string")return`Models.${B1(u9($.$ref,"schemas"))}`;let X=sO($);if(X)return tO(Q,Z,X);if($.type==="integer"||$.type==="number")return"number";if($.type==="boolean")return"boolean";if($.type==="array"){let U=c($.items)?$.items:void 0;return`Array<${W6(U,Q,`${Z}Item`)??i9(U)}>`}if($.type==="object")return"Record<string, unknown>";return"string"}function eO($,Q){let Z=r9($,Q,"parameters");return c(Z)?Z:null}function $K($,Q){let Z=[...Array.isArray($)?$:[],...Array.isArray(Q)?Q:[]],X=new Map;for(let U of Z){if(!c(U))continue;if(typeof U.$ref==="string"){X.set(U.$ref,U);continue}let J=L6(U.in),Y=L6(U.name);if(J&&Y)X.set(`${J}:${Y}`,U)}return[...X.values()]}function QK($,Q){let Z=r9($.requestBody,Q,"requestBodies");if(!c(Z)||!c(Z.content))return;return P6(Z.content)??void 0}function ZK($,Q,Z){let X=c($.responses)?$.responses:{},U=xX(X,Z);if(!U)return;let J=r9(U.response,Q,"responses");if(!c(J)||!c(J.content))return;return P6(J.content)??void 0}function XK($,Q){let Z=c($.paths)?$.paths:{},X=oO($),U=[],J=new Map;for(let[Y,W]of Object.entries(Z)){if(!c(W))continue;for(let _ of aX){let G=W[_];if(!c(G))continue;let z=L6(G.operationId)??aO(_,Y),V=$K(W.parameters,G.parameters).map((M)=>eO(M,X)).filter((M)=>Boolean(M)).filter((M)=>M.in===$$.Path||M.in===$$.Query).map((M)=>{let R=L6(M.name)??"param",w=DO(R,Q.paramNaming),P=M.in===$$.Path?$$.Path:$$.Query,l=c(M.schema)?M.schema:void 0,v=`${B1(z)}${B1(R)}`;return{name:w,variableName:NO(w),wireName:R,location:P,required:M.required===!0||P===$$.Path,typeName:W6(l,J,v)??i9(l)}}),O=Q.sortParamsByRequiredFlag===!1?V:V.sort((M,R)=>Number(!M.required)-Number(!R.required)),K=QK(G,X),q=ZK(G,X,_),B=W6(q,J,`${B1(z)}Response`)??"unknown",S=W6(K,J,`${B1(z)}RequestBody`);U.push({operationId:z,method:_.toUpperCase(),path:Y,functionName:nX(z),requestName:`${B1(z)}Request`,responseType:B,bodyType:S,parameters:O})}}return{operations:U.sort((Y,W)=>Y.operationId.localeCompare(W.operationId)),inlineEnumGroups:[...J.values()].sort((Y,W)=>Y.name.localeCompare(W.name))}}async function eX($,Q,Z){return Z?q9($,Q):$}async function WK($,Q,Z,X,U){let J=!1,Y=sX(Q,"models.ts"),W=await eX(rX($,Z),Y,U);if(await W$(Y,W))J=!0;if(X)tX.step(` \u2713 ${Y}`);if(await L0(Q,["./models"]))J=!0;return J}async function _K($,Q,Z,X,U,J,Y){let W=!1,{operations:_,inlineEnumGroups:G}=XK($,U),z=new Set(Q.enumGroups.map((O)=>O.name)),H={...Q,enumGroups:[...Q.enumGroups,...G.filter((O)=>!z.has(O.name))]},V=[["models.ts",rX(H,U)],["runtime.ts",PO()],["api.ts",xO(_,X,U)]];for(let[O,K]of V){let q=sX(Z,O),B=await eX(K,q,Y);if(await W$(q,B))W=!0;if(J)tX.step(` \u2713 ${q}`)}if(await L0(Z,["./models","./api"]))W=!0;return W}async function GK($,Q,Z,X,U={}){let J=JK(Q);try{let Y=await YK.parse($,{validate:{spec:!1}});if(b6(Y,{enforceOperationSchemaRefs:!0}),!c(Y))throw Error("OpenAPI document must be an object");let W=bX(Y);if(Z.type===N.TypeScriptModels){let G=await WK(W,Q,Z,X,U.formatFiles!==!1);return{success:!0,service:J,changed:G}}let _=await _K(Y,W,Q,J,Z,X,U.formatFiles!==!1);return{success:!0,service:J,changed:_}}catch(Y){return{success:!1,service:J,error:Y instanceof Error?Y:Error(String(Y))}}}function HK($){if($.success)return{success:!0,service:$.service,changed:$.changed};let Q=Error($.message);if($.stack)Q.stack=$.stack;return{success:!1,service:$.service,error:Q}}function VK(){let $=new Worker(new URL("./generate-worker.ts",import.meta.url).href),Q={worker:$,pending:new Map};return $.onmessage=(Z)=>{let X=Q.pending.get(Z.data.id);if(!X)return;Q.pending.delete(Z.data.id),X.resolve(HK(Z.data.result))},$.onerror=(Z)=>{let X=Error(Z.message||"Kontract worker failed");for(let U of Q.pending.values())U.reject(X);Q.pending.clear()},Q}function OK($){let Q=Math.max(1,Math.floor($)),Z=Array.from({length:Q},()=>VK()),X=1,U=0;return{run:(W)=>{let _=Z[U]??Z[0];if(!_)return Promise.reject(Error("Kontract worker pool has no available workers"));U=(U+1)%Z.length;let G=X;X+=1;let z={id:G,task:W};return new Promise((H,V)=>{k("worker.tasks"),_.pending.set(G,{resolve:H,reject:V}),_.worker.postMessage(z)})},close:async()=>{await Promise.all(Z.map((W)=>W.worker.terminate()))}}}function KK($){let Q=_6;return _6=$,()=>{_6=Q}}function qK($){return _6?.run($)??null}async function eZ($){if($.kind===q0.OpenApiNestJs)return CO($.inputFile,$.outputDir,$.verbose,$.options);if($.kind===q0.OpenApiSdk)return GK($.inputFile,$.outputDir,$.generator,$.verbose,{formatFiles:$.formatFiles});return BH($.inputFile,$.outputDir,$.verbose,{sharedTypesImportPath:$.sharedTypesImportPath,sharedTypesOutputFile:$.sharedTypesOutputFile,addressPrefix:$.addressPrefix,formatFiles:$.formatFiles})}async function Y9($){let Q=qK($);if(!Q)return eZ($);try{return await Q}catch{return k("worker.fallbacks"),eZ($)}}function LK($){return $.type!==N.AsyncApiNats}function AK($){return $.type===N.AsyncApiNats}function MK($){return $.type===N.TypeScriptFetch||$.type===N.TypeScriptAxios||$.type===N.TypeScriptAngular}function jK($){return MK($)||$.type===N.TypeScriptModels}function TK($){let Q=$.source?$.config.sources.filter((Z)=>Z.name===$.source):$.config.sources;if(Q.length===0)throw Error(`No kontract source named '${$.source}'`);return Q}function EK($){let Q=[];for(let Z of TK($)){let X=$.target?Z.targets.filter((U)=>U.name===$.target):Z.targets;for(let U of X)Q.push({sourceName:Z.name,targetName:U.name,inputDir:$7(Z.input),outputDir:$7(U.output),generator:U.generator})}if($.target&&Q.length===0)throw Error(`No kontract target named '${$.target}'`);return Q}async function CK($){let Q=new Map;for(let X of $)if(!Q.has(X.sourceName))Q.set(X.sourceName,X);let Z=[];for(let X of Q.values()){let[U,J]=await H$("discovery",()=>Promise.all([JX(X.inputDir),YX(X.inputDir)]));Z.push({sourceName:X.sourceName,inputDir:X.inputDir,openApiRoots:U,asyncApiGroups:J})}return Z}function Q7($,Q){return Q?$.filter((Z)=>Z.name===Q):[...$]}async function SK($,Q){if(await W9(Q,{recursive:!0}),$.files.length===0)throw Error(`No AsyncAPI files found for service '${$.name}'`);if($.files.length===1){let U=$.files[0];if(!U)throw Error(`Missing AsyncAPI file for service '${$.name}'`);return{specFile:U,cleanup:null}}let Z=e$(Q,$9($.name)),X=await T3($.files,Z);if(!X.success)throw X.error;return{specFile:X.outputPath,cleanup:()=>QU(Z,{force:!0})}}async function FK($,Q){let Z=G6.get(Q);if(Z)return k("bundle.cacheCoalescedHits"),Z;if(await Bun.file(Q).exists())return k("bundle.cacheHits"),{specFile:Q,cleanup:null};k("bundle.cacheMisses");let X=H$("bundle.openapi",async()=>{let U=await ZX([$.rootFile],Q);if(!U.success)throw U.error;return{specFile:U.outputPath,cleanup:null}});G6.set(Q,X);try{return await X}finally{G6.delete(Q)}}async function IK($,Q,Z,X){if(await W9(Q,{recursive:!0}),!await H$("bundle.decision",()=>wK($.rootFile)))return k("bundle.skippedInternalRefs"),{specFile:$.rootFile,cleanup:null};if(X){let W=e$(Q,I4);await W9(W,{recursive:!0});let _=K0(Z).slice(0,24),G=e$(W,$9(`${$.name}-${_}`));if(await Bun.file(G).exists())return k("bundle.cacheHits"),{specFile:G,cleanup:null};return FK($,G)}let J=e$(Q,$9($.name)),Y=await H$("bundle.openapi",()=>ZX([$.rootFile],J));if(!Y.success)throw Y.error;return{specFile:Y.outputPath,cleanup:()=>QU(J,{force:!0})}}function DK($){return $.match(/\$ref\s*:\s*['"]?([^'"\s]+)['"]?\s*$/)?.[1]??null}function RK($){return/\$ref\s*:\s*$/.test($)||/\$ref\s*:\s*[|>]/.test($)}function NK($){for(let Q of $.split(/\r?\n/)){if(!Q.includes("$ref"))continue;if(RK(Q))return null;let Z=DK(Q);if(!Z)return null;if(!Z.startsWith("#"))return!0}return!1}async function wK($){try{let Q=NK(await Bun.file($).text());if(Q===null)return k("bundle.ambiguousRefs"),!0;return Q}catch{return!0}}function PK($,Q){let Z=Q.find((X)=>X.sourceName===$.sourceName);if(!Z)throw Error(`Missing discovery result for source '${$.sourceName}'`);return Z}function bK($){if($.generator.type===N.TypeScriptNestJs)return Y$.Http;if($.generator.type===N.TypeScriptModels)return Y$.Models;return Y$.Sdk}async function kK($,Q,Z,X){if($.generator.type===N.TypeScriptNestJs)return Y9({kind:q0.OpenApiNestJs,inputFile:Z.specFile,outputDir:Q,verbose:X.verbose,options:{zod:$.generator.zod===!0,dtos:$.generator.dtos===!0,formatFiles:!1}});if(!jK($.generator))throw Error(`Generator '${$.generator.type}' cannot emit OpenAPI TypeScript`);return Y9({kind:q0.OpenApiSdk,inputFile:Z.specFile,outputDir:Q,generator:$.generator,verbose:X.verbose,formatFiles:!1})}function fK($,Q,Z,X){let U=bK($);return{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,outputDir:$.outputDir,channel:U,run:async()=>{let J=null,Y=C6(Z,$),W=e$($.outputDir,Q.name),_=await h7([Q.rootFile]),G=l7(Y,U,Q.name);if((await p7({sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:U,generator:$.generator,manifestPath:G,source:_,outputDir:W})).skipped)return{success:!0,service:Q.name,changed:!1,skippedByManifest:!0};try{let H=_.safe?P7(Z,$.sourceName):Y,V=await IK(Q,H,_.hash,_.safe);J=V.cleanup;let O=await kK($,W,V,X);return O.success?{...O,manifest:{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:U,generator:$.generator,manifestPath:G,source:_,outputDir:W}}:O}finally{if(J)await J()}}}}function yK($,Q,Z){return{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,outputDir:$.outputDir,channel:Y$.Nats,run:async()=>{let X=null,U=C6(Z,$),J=e$($.outputDir,Q.name),Y=e$($.outputDir,j7),W=await h7(Q.files),_=l7(U,Y$.Nats,Q.name);if((await p7({sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:Y$.Nats,generator:$.generator,manifestPath:_,source:W,outputDir:J,additionalOutputDirs:[Y]})).skipped)return{success:!0,service:Q.name,changed:!1,skippedByManifest:!0};try{let z=await SK(Q,U);X=z.cleanup;let H=e$(Y,"runtime.ts"),V=Lz(e$(J,"nats"),H),O=await Y9({kind:q0.AsyncApiNats,inputFile:z.specFile,outputDir:J,verbose:!1,sharedTypesImportPath:V,sharedTypesOutputFile:H,addressPrefix:$.generator.type===N.AsyncApiNats?$.generator.prefix:void 0,formatFiles:!1});return O.success?{...O,manifest:{sourceName:$.sourceName,targetName:$.targetName,serviceName:Q.name,channel:Y$.Nats,generator:$.generator,manifestPath:_,source:W,outputDir:J,additionalOutputDirs:[Y]}}:O}finally{if(X)await X()}}}}function vK($,Q,Z,X){let U=[];for(let J of $){let Y=PK(J,Q);if(LK(J.generator)){let W=Q7(Y.openApiRoots,X.specific);U.push(...W.map((_)=>fK(J,_,Z,X)))}if(AK(J.generator)){let W=Q7(Y.asyncApiGroups,X.specific);U.push(...W.map((_)=>yK(J,_,Z)))}}return U}async function xK($){let Q=EK($),Z=Bz(Q),X=await CK(Q),U=vK(Q,X,Z,$);return{jobs:Q,discovered:X,workItems:U,cacheRoot:Z}}function mK($){if($===Y$.Http)return Y$.Http;if($===Y$.Nats)return Y$.Nats;if($===Y$.Models)return Y$.Models;return Y$.Sdk}async function lK($,Q){let Z=new Set;for(let X of $){let U=await $3({cwd:process.cwd(),inputDir:X.inputDir,outputDir:X.outputDir,generators:[X.generator]});for(let J of U){let Y=`${J.title}
|
|
176
|
+
${J.details??""}`;if(Z.has(Y))continue;Z.add(Y),Q(J.title,J.details)}}}async function pK($,Q,Z,X){let U=[...X,...$.map((J)=>C6(Z,J)),...JU($,Z),...Q.map((J)=>_9(J.outputDir,J.serviceName))];await Promise.all(U.map((J)=>hK(J,{recursive:!0}))),await Promise.all(X.map((J)=>XU(_9(J,".cache"),{recursive:!0,force:!0})))}function UU($){return[...new Set($)].sort((Q,Z)=>Q.localeCompare(Z))}function cK($){let Q=UU($.map((X)=>dK(X))).sort((X,U)=>X.length-U.length||X.localeCompare(U)),Z=[];for(let X of Q){if(Z.some((U)=>E6(U,X)))continue;Z.push(X)}return Z}function JU($,Q){let Z=$.filter((X)=>X.generator.type!==N.AsyncApiNats).map((X)=>X.sourceName);return UU(Z.map((X)=>P7(Q,X)))}async function nK($,Q,Z,X){let U=[...$.map((Y)=>C6(Q,Y)),...JU($,Q)],J=cK([...Z,...U]);X.printStep("Cleaning selected generated outputs and Kontract cache..."),await Promise.all(J.map((Y)=>XU(Y,{recursive:!0,force:!0})))}function iK($,Q,Z,X,U,J){let Y=0,W=(G,z)=>{if(Y+=1,z===m1.Generated)$.generatedCount+=1;if(z===m1.Unchanged)$.unchangedCount+=1;if(z===m1.Failed)$.failedCount+=1;let H=`Generating contracts (${Y}/${Q.length}) \u2022 ${G.sourceName}/${G.targetName}/${G.serviceName} (${mK(G.channel)}, ${z})`;if(Z){Z.message(H);return}if(!X&&U)J(H)},_=(G,z)=>{$.failures.push(Z3(`${G.sourceName}/${G.targetName}/${G.serviceName}`,z)),W(G,m1.Failed)};return async(G)=>{try{let z=await G.run();if($.results.push(z),z.success){if(z.skippedByManifest)k("generation.manifestSkipped");else $.touchedServiceDirs.add(_9(G.outputDir,G.serviceName));if(z.manifest)$.pendingManifestWrites.push(z.manifest);if(z.changed)$.changedOutputRoots.add(G.outputDir);return W(G,z.changed?m1.Generated:m1.Unchanged),!0}return _(G,z.error.message),!1}catch(z){let H=z instanceof Error?z:Error(String(z));return $.results.push({success:!1,service:G.serviceName,error:H}),_(G,H.message),!1}}}async function rK($,Q,Z,X,U){if(Q)Q.message("Formatting generated contracts...");else if(!Z&&X)U.printStep("Formatting generated contracts...");for(let J of $){let Y=await Vz(J);if(!Y.success)throw Error([`Could not run post-generation Biome format pass for ${w7(J)}.`,Y.details].filter(Boolean).join(`
|
|
177
|
+
`));else if(!Z&&X&&Y.details)U.printInfo(Y.details)}}async function oK($){let Q=[];for(let Z of $)try{if((await uK(Z)).isDirectory())Q.push(Z)}catch(X){if(X instanceof Error&&"code"in X&&X.code==="ENOENT")continue;throw X}return Q}function aK($,Q,Z){let X=$.find((U)=>E6(U,Z));if(X)Q.changedOutputRoots.add(X)}function sK(){return{results:[],touchedServiceDirs:new Set,changedOutputRoots:new Set,pendingManifestWrites:[],failures:[],generatedCount:0,unchangedCount:0,failedCount:0}}function tK($){return[...new Set($.map((Q)=>Q.outputDir))].sort((Q,Z)=>Q.localeCompare(Z))}async function eK($,Q){let Z=await Promise.all([...$.touchedServiceDirs].map(async(X)=>({serviceDir:X,changed:await $z(X)})));for(let X of Z)if(X.changed)aK(Q,$,X.serviceDir)}async function $q($,Q){let Z=await Promise.all(Q.map(async(U)=>({outputRoot:U,changed:await Qz(U)}))),X=await Promise.all(Q.map(async(U)=>({outputRoot:U,changed:await Xz(U)})));for(let U of[...Z,...X])if(U.changed)$.changedOutputRoots.add(U.outputRoot)}async function Qq($,Q,Z,X,U){let J=[...$.changedOutputRoots],Y=await oK(J);if(Y.length===0)return;k("format.changedOutputRoots",Y.length),await rK(Y,Q,Z,X,U)}async function Zq($){if($.pendingManifestWrites.length===0)return;await Promise.all($.pendingManifestWrites.map((Q)=>Rz(Q)))}function Xq($){return $>1&&process.env[V7]!=="1"&&process.env[R4]!=="1"}function Uq($){if(!Xq($))return k("worker.disabled"),null;try{let Q=OK($);return k("worker.enabled"),k("worker.count",$),Q}catch(Q){k("worker.startFailures");let Z=Q instanceof Error?Q.message:String(Q);throw Error(`Could not start Kontract worker pool: ${Z}. Set ${V7}=1 to run on the main thread.`)}}function Jq($,Q,Z,X){let U=`Done: ${$.generatedCount} generated, ${$.unchangedCount} unchanged, ${$.failedCount} failed`;if(Q)if($.failedCount>0)Q.error(U);else Q.stop(U);else if(!Z)X.printStep(U);if($.failures.length>0)for(let J of $.failures)X.printFailure(J)}async function Yq($){let Q=m4($.metrics??null);try{return await Wq($)}finally{Q()}}async function Wq($){let{concurrency:Q,verbose:Z,quiet:X}=$,U=X?null:await import("@clack/prompts"),J=U?.spinner(V1("purple"))??null,Y=X3(X,U),{printStep:W,printInfo:_,printFailure:G}=Y,z;try{z=await H$("plan",()=>xK($))}catch(w){let P=w instanceof Error?w:Error(String(w));return G({title:`\u2717 ${P.message}`}),1}let{jobs:H,workItems:V,cacheRoot:O}=z,K=H.map((w)=>`${w.sourceName}/${w.targetName} \u2192 ${w7(w.outputDir)}`).join(", ");if(W(`Kontract generate: ${K}`),V.length===0)return _("No schema files found for selected sources and targets."),0;await H$("dependencyWarnings",()=>lK(H,Y.printWarning));let q=tK(H);if($.clean===!0)await H$("clean",()=>nK(H,O,q,Y));let B=sK();if(J)J.start(`Generating contracts (0/${V.length})...`);await H$("prepareOutputDirectories",()=>pK(H,V,O,q));let S=iK(B,V,J,X,Z,W),M=Uq(Q),R=KK(M);try{await H$("processItems",()=>t8(V,S,Q))}finally{R(),await M?.close()}await H$("barrels",async()=>{if(B.touchedServiceDirs.size===0&&B.changedOutputRoots.size===0){k("barrels.skipped");return}await eK(B,q),await $q(B,q)});try{await H$("format",()=>Qq(B,J,X,Z,Y)),await H$("manifest.write",()=>Zq(B))}catch(w){let P=w instanceof Error?w:Error(String(w));B.failures.push({title:`\u2717 ${P.message}`}),B.failedCount+=1}return Jq(B,J,X,Y),B.failedCount>0?1:0}function Oq($,Q){let Z=Q.split(`
|
|
178
|
+
`).map((J)=>J.trim()).filter((J)=>J.length>0),[X="Unexpected error",...U]=Z;return{title:`\u274C ${$}: ${X}`,details:U.length>0?U.join(`
|
|
179
|
+
`):void 0}}function Kq($){return $.type!==N.AsyncApiNats}function qq($){return $.type===N.AsyncApiNats}function Bq($){let Q=$.source?$.config.sources.filter((U)=>U.name===$.source):$.config.sources;if(Q.length===0)throw Error(`No kontract source named '${$.source}'`);let Z=[],X=!1;for(let U of Q){let J=$.target?U.targets.filter((W)=>W.name===$.target):U.targets;if(J.length>0)X=!0;let Y=J.map((W)=>W.generator);Z.push({source:U,inputDir:Hq(U.input),validateOpenApi:Y.some(Kq),validateAsyncApi:Y.some(qq)})}if($.target&&!X)throw Error(`No kontract target named '${$.target}'`);return Z.filter((U)=>U.validateOpenApi||U.validateAsyncApi)}async function Lq($){let Q=Bun.spawn(["bunx","@asyncapi/cli","validate",$],{stdout:"pipe",stderr:"pipe",env:{...process.env}});if(await Q.exited!==0){let X=await new Response(Q.stderr).text();return{success:!1,file:$,kind:b$.AsyncApi,error:Error(X.trim())}}return{success:!0,file:$,kind:b$.AsyncApi}}async function Aq($){try{let Q=await Vq.parse($,{validate:{spec:!1}});return b6(Q,{enforceOperationSchemaRefs:!0}),{success:!0,file:$,kind:b$.OpenApi}}catch(Q){return{success:!1,file:$,kind:b$.OpenApi,error:Q instanceof Error?Q:Error(String(Q))}}}function Mq($,Q){return{printStep:(J)=>{if($)return;if(Q){Q.log.step(J,J$("step"));return}X6.step(J)},printInfo:(J)=>{if($)return;if(Q){Q.log.info(J,J$("info"));return}X6.info(J)},printFailure:(J)=>{if(!$&&Q){if(Q.log.error(J.title,{...J$("error"),symbol:"\u274C"}),J.details)Q.note(J.details,"Details",P$("dim"));return}if(X6.error(J.title),J.details)X6.error(J.details)}}}async function jq($){let Q=[],Z=[];for(let X of $){if(X.validateOpenApi){let U=await JX(X.inputDir);Q.push(...U.map((J)=>J.rootFile))}if(X.validateAsyncApi){let U=await YX(X.inputDir);Z.push(...U.flatMap((J)=>J.files))}}return{openApiFiles:Q,asyncApiFiles:Z}}function Tq($){let Q=$.filter((J)=>J.success&&J.kind===b$.OpenApi).length,Z=$.filter((J)=>!J.success&&J.kind===b$.OpenApi).length,X=$.filter((J)=>J.success&&J.kind===b$.AsyncApi).length,U=$.filter((J)=>!J.success&&J.kind===b$.AsyncApi).length;return{summary:`OpenAPI: ${Q} passed, ${Z} failed | AsyncAPI: ${X} passed, ${U} failed`,failedCount:Z+U}}function Z7($,Q,Z){return async(X)=>{let U=await Q(X);Z.results.push(U);let J=zq(X);if(U.success)return Z.updateProgress(J,$,G9.Passed),!0;return Z.failures.push(Oq(`${J} (${$})`,U.error.message)),Z.updateProgress(J,$,G9.Failed),U.success}}function Eq($,Q,Z,X,U){let J=0;return(Y,W,_)=>{J+=1;let G=`Validating schemas (${J}/${$}) \u2022 ${Y} (${W}, ${_})`;if(Q){Q.message(G);return}if(!Z&&X)U(G)}}function Cq($,Q,Z,X,U){if(Z){if(Q>0)Z.error($);else Z.stop($);return}if(!X)U($)}async function Sq($){let{concurrency:Q,verbose:Z,quiet:X}=$,U=X?null:await import("@clack/prompts"),J=U?.spinner(V1("purple"))??null,{printStep:Y,printInfo:W,printFailure:_}=Mq(X,U),G;try{G=Bq($)}catch(B){let S=B instanceof Error?B:Error(String(B));return _({title:`\u2717 ${S.message}`}),1}Y(`Kontract validate: ${G.map((B)=>B.source.name).join(", ")}`);let z,H;try{({openApiFiles:z,asyncApiFiles:H}=await jq(G))}catch(B){let S=B instanceof Error?B:Error(String(B));return _({title:`\u2717 ${S.message}`}),1}let V=z.length+H.length;if(V===0)return W("No schema files found for selected sources and targets."),0;if(J)J.start(`Validating schemas (0/${V})...`);let O={results:[],failures:[],updateProgress:Eq(V,J,X,Z,Y)};await Promise.all([t8(z,Z7(b$.OpenApi,Aq,O),Q),t8(H,Z7(b$.AsyncApi,Lq,O),Q)]);let{summary:K,failedCount:q}=Tq(O.results);if(Cq(K,q,J,X,Y),O.failures.length>0)for(let B of O.failures)_(B);return q>0?1:0}function Pq($){let Q=U7($,w4);if(!X7(U7($,".git")))return!1;let Z=`${G7}/${N4}`,X=X7(Q)?Dq(Q,"utf8"):"";if(X.split(/\r?\n/).includes(Z))return!1;return Iq(wq(Q),{recursive:!0}),Rq(Q,`${X.trimEnd()}
|
|
177
180
|
${Z}
|
|
178
|
-
`,"utf8"),!0}function
|
|
179
|
-
`),0;if(!X)
|
|
181
|
+
`,"utf8"),!0}function bq($){let{cwd:Q,json:Z,quiet:X}=$,U=$.writeOutput??((Y)=>{Nq(1,Y)});u0(fZ,{cwd:Q});let J=Pq(Q);if(Z)return U(`${JSON.stringify({ok:!0,command:"kontract init",data:{activated:fZ,excludeUpdated:J,hint:yZ},warnings:[],error:null},null,2)}
|
|
182
|
+
`),0;if(!X)f("Kontract is now active for this workspace.",{details:yZ});return 0}function pq($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function $2($,Q){if(!pq($))throw Error(`${Q} must be an object`);return $}function M6($,Q,Z){let X=$[Q];if(typeof X!=="string"||X.trim().length===0)throw Error(`${Z}.${Q} must be a non-empty string`);return X.trim()}function J7($,Q,Z){let X=$[Q];if(X===void 0)return;if(typeof X!=="string"||X.trim().length===0)throw Error(`${Z}.${Q} must be a non-empty string`);return X.trim()}function L1($,Q,Z){let X=$[Q];if(X===void 0)return;if(typeof X!=="boolean")throw Error(`${Z}.${Q} must be a boolean`);return X}function _U($,Q){if(!Array.isArray($)||$.length===0)throw Error(`${Q} must be a non-empty array`);return $}function A1($,Q,Z){let X=new Set(Q);for(let U of Object.keys($))if(!X.has(U))throw Error(`${Z}.${U} is not supported`)}function cq($){for(let Q of xq)if(Q in $)throw Error(`kontract.${Q} is not supported. Use kontract.sources[].targets[]`)}function z6($,Q,Z,X){let U=$[Q];if(U===void 0)return;if(typeof U!=="string")throw Error(`${X}.${Q} must be one of: ${Z.join(", ")}`);for(let J of Z)if(U===J)return J;throw Error(`${X}.${Q} must be one of: ${Z.join(", ")}`)}function U6($,Q){return{useSingleRequestParameter:L1($,"useSingleRequestParameter",Q),stringEnums:L1($,"stringEnums",Q),enumUnknownDefaultCase:L1($,"enumUnknownDefaultCase",Q),modelPropertyNaming:z6($,"modelPropertyNaming",C7,Q),paramNaming:z6($,"paramNaming",S7,Q),enumPropertyNaming:z6($,"enumPropertyNaming",F7,Q),sortModelPropertiesByRequiredFlag:L1($,"sortModelPropertiesByRequiredFlag",Q),sortParamsByRequiredFlag:L1($,"sortParamsByRequiredFlag",Q)}}function nq($,Q){let Z=L1($,"dto",Q),X=L1($,"dtos",Q);if(Z!==void 0&&X!==void 0&&Z!==X)throw Error(`${Q}.dto conflicts with ${Q}.dtos. Use only one DTO option.`);return X??Z}function iq($,Q){let Z=z6($,"type",s8,Q);if(!Z)throw Error(`${Q}.type must be one of: ${s8.join(", ")}`);if(Z===N.AsyncApiNats)return A1($,uq,Q),{type:Z,prefix:J7($,"prefix",Q)};if(Z===N.TypeScriptNestJs)return A1($,dq,Q),{type:Z,...U6($,Q),dtos:nq($,Q),zod:L1($,"zod",Q)};if(Z===N.TypeScriptAngular)return A1($,mq,Q),{type:Z,...U6($,Q),providedIn:J7($,"providedIn",Q)};if(Z===N.TypeScriptModels)return A1($,lq,Q),{type:Z,...U6($,Q)};return A1($,WU,Q),{type:Z,...U6($,Q)}}function rq($,Q){let Z=$2($,Q);A1(Z,hq,Q);let X=iq($2(Z.generator,`${Q}.generator`),`${Q}.generator`);return{name:M6(Z,"name",Q),output:M6(Z,"output",Q),generator:X}}function oq($,Q){let Z=$2($,Q);A1(Z,gq,Q);let X=_U(Z.targets,`${Q}.targets`).map((U,J)=>rq(U,`${Q}.targets[${J}]`));return{name:M6(Z,"name",Q),input:M6(Z,"input",Q),targets:X}}function Y7($,Q){let Z=new Set;for(let X of $){if(Z.has(X.name))throw Error(`Duplicate ${Q} name '${X.name}'`);Z.add(X.name)}}function aq($){let Q=vq($),Z=$2(Q,"sumr.yaml"),X=$2(Z.kontract,"kontract");cq(X),A1(X,["sources"],"kontract");let U=_U(X.sources,"kontract.sources").map((Y,W)=>oq(Y,`kontract.sources[${W}]`));Y7(U,"source");let J=U.flatMap((Y)=>Y.targets);return Y7(J,"target"),{sources:U}}function sq($){let Q=yq($,bZ);if(!kq(Q))throw Error(`${bZ} not found. Define kontract.sources[].targets[]`);let Z=fq(Q,"utf8");return aq(Z)}function W7($,Q,Z){if(Z&&!Z.startsWith("-"))return $[Q]=Z,!0;return $[Q]=!0,!1}function QB($,Q,Z,X){if($.startsWith("--")){let U=$.indexOf("=");if(U!==-1)return Z[$.slice(2,U)]=$.slice(U+1),!1;return W7(Z,$.slice(2),Q)}if($.startsWith("-")&&$.length===2)return W7(Z,$.slice(1),Q);return X.push($),!1}function o9($){let Q={},Z=[];for(let X=0;X<$.length;X+=1){let U=$[X];if(!U)continue;if(QB(U,$[X+1],Q,Z))X+=1}return{positionals:Z,options:Q}}function p1($,Q){for(let Z of Q){let X=$[Z];if(typeof X==="string")return X}return}function i1($,Q){return Q.some((Z)=>$[Z]===!0)}function a9($,Q){if(Q.length===0)return 0;return r("sumr kontract"),L$(`Use \`sumr kontract ${$}\` with flags only.`),1}function GU(){try{return sq(process.cwd())}catch($){let Q=$ instanceof Error?$.message:String($);return r("sumr kontract"),L$(`Kontract config error: ${Q}`),null}}async function ZB($){let Q=o9($.argv.slice(1)),Z=a9("generate",Q.positionals);if(Z!==0)return Z;let X=process.env.CI==="true",U=GU();if(!U)return 1;let J=i1(Q.options,["quiet"])||X;if(!J)r("sumr kontract");let{runGenerate:Y}=await Promise.resolve().then(()=>(_q(),ZU));return Y({config:U,concurrency:Number(p1(Q.options,["max-concurrent","concurrency","c"])??z9),source:p1(Q.options,["source"]),target:p1(Q.options,["target"]),specific:p1(Q.options,["specific","s"]),clean:i1(Q.options,["clean"]),verbose:i1(Q.options,["verbose"]),quiet:J})}async function XB($){let Q=o9($.argv.slice(1)),Z=a9("init",Q.positionals);if(Z!==0)return Z;let X=process.env.CI==="true",U=i1(Q.options,["quiet"])||X,J=i1(Q.options,["json"]);if(!U&&!J)r("sumr kontract");return bq({cwd:process.cwd(),json:J,quiet:U})}async function UB($){let Q=o9($.argv.slice(1)),Z=a9("validate",Q.positionals);if(Z!==0)return Z;let X=process.env.CI==="true",U=GU();if(!U)return 1;let J=i1(Q.options,["quiet"])||X;if(!J)r("sumr kontract");let{runValidate:Y}=await Promise.resolve().then(()=>(Fq(),YU));return Y({config:U,concurrency:Number(p1(Q.options,["concurrency","c"])??z9),source:p1(Q.options,["source"]),target:p1(Q.options,["target"]),verbose:i1(Q.options,["verbose"]),quiet:J})}var j4,T4=($)=>$,_7=($,Q)=>{for(var Z in Q)j4($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:E4.bind(Q,Z)})},j=($,Q)=>()=>($&&(Q=$($=0)),Q),PZ="biome",z9,bZ="sumr.yaml",S4="SUMR_CACHE_DIR",G7=".sumr-cache",z7="kontract",F4="manifests",I4="bundle-cache",D4="source-cache",H7=1,V7="KONTRACT_DISABLE_WORKERS",R4="KONTRACT_FORCE_MAIN_THREAD",kZ="0.0.0",N4="activations.json",fZ="kontract",w4=".git/info/exclude",yZ="Run `sumr playbook sync` to install Kontract AI guidance into your AI tools.",P4="**/*.openapi.{yml,yaml}",b4="**/*.asyncapi.{yml,yaml}",k4="_bundle.yml",f4="@redocly/cli@2.28.1",y4="KONTRACT_DISABLE_REDOCLY_CORE",v4="application/json",x4="*/*",O7,K7,q7,B7,L7,A7="openapi:",g4="asyncapi:",M7=".dto.ts",h4="index.ts",u4="shared.ts",H9="index.ts",j7="shared",T7="<auto-generated>",E7,X$,N,s8,C7,S7,F7,b$,Y$,S1,J6=null,j6,N7,T6,A9,c7,Nz="sha256:",n7,i7,s0=null,Q6=null,r7,m1,wz,Q3,U3=()=>{},xZ=2,E3=150,Q9,gZ,C3,WX,q0,_X,N3=`export interface IMsgContext {
|
|
180
183
|
userId: string;
|
|
181
184
|
orgId: string;
|
|
182
|
-
}`,
|
|
185
|
+
}`,w3=`export interface IRouteContract<Req, Res> {
|
|
183
186
|
request: Req;
|
|
184
187
|
response: Res;
|
|
185
|
-
}`,
|
|
188
|
+
}`,P3=`export type IRouteContracts = Record<
|
|
186
189
|
string,
|
|
187
190
|
IRouteContract<unknown, unknown>
|
|
188
|
-
>;`,
|
|
191
|
+
>;`,b3=`export interface IRawClientProxy {
|
|
189
192
|
emit<TResult = unknown, TInput = unknown>(
|
|
190
193
|
router: unknown,
|
|
191
194
|
message: TInput,
|
|
@@ -196,7 +199,7 @@ ${Z}
|
|
|
196
199
|
message: TInput,
|
|
197
200
|
...extra: unknown[]
|
|
198
201
|
): Observable<TResult>;
|
|
199
|
-
}`,
|
|
202
|
+
}`,k3=`export interface IClientProxy<
|
|
200
203
|
TRoutes extends { [K in keyof TRoutes]: IRouteContract<unknown, unknown> } = IRouteContracts,
|
|
201
204
|
> {
|
|
202
205
|
emit<Route extends keyof TRoutes & string>(
|
|
@@ -219,7 +222,7 @@ ${Z}
|
|
|
219
222
|
message: Req,
|
|
220
223
|
ctx?: IMsgContext,
|
|
221
224
|
): Observable<Res>;
|
|
222
|
-
}`,
|
|
225
|
+
}`,f3=`class RouteTypedClientProxy<
|
|
223
226
|
TRoutes extends { [K in keyof TRoutes]: IRouteContract<unknown, unknown> },
|
|
224
227
|
> implements IClientProxy<TRoutes> {
|
|
225
228
|
constructor(private readonly client: IRawClientProxy) {}
|
|
@@ -265,15 +268,15 @@ export function createRouteTypedClientProxy<
|
|
|
265
268
|
TRoutes extends { [K in keyof TRoutes]: IRouteContract<unknown, unknown> },
|
|
266
269
|
>(client: IRawClientProxy): IClientProxy<TRoutes> {
|
|
267
270
|
return new RouteTypedClientProxy<TRoutes>(client);
|
|
268
|
-
}`,
|
|
271
|
+
}`,y3=`export interface CommandReturnType {
|
|
269
272
|
commandId: string;
|
|
270
|
-
}`,
|
|
271
|
-
`)}),
|
|
272
|
-
`)});
|
|
273
|
-
`));let Z=$.flow?.preset,X=Z&&Q7(Z)?Z:C$.Basic,U=$.flow?.steps?.length?$.flow.steps.map(XB):NU[X];return{preset:X,steps:U}}function v8($){let Q=aL($),Z=QB(Q.steps);return{preset:Q.preset,hash:sL(Q.preset,Z),steps:Z.map((X)=>({uses:X.uses,enabled:X.enabled??!0,advance:X.advance??T.Manual,status:X.enabled===!1?P$.Skipped:P$.Pending}))}}function sL($,Q){return nL("sha256").update(JSON.stringify({preset:$,steps:Q})).digest("hex").slice(0,12)}function tL($){if(!$.flow)return $;let Q=$.flow.steps.map((Z)=>{let X=Z.enabled?JB($,Z.uses):P$.Skipped,U=GB($,Z.uses)??Z.artifactPath,W=X!==Z.status||U!==Z.artifactPath?new Date().toISOString():Z.updatedAt;return{...Z,status:X,artifactPath:U,updatedAt:W}});return{...$,flow:{...$.flow,steps:Q}}}function eL($){if(!$.flow)return;let Q=$.flow.steps.find((X)=>X.enabled&&X.status!==P$.Done);if(!Q)return"Close the mission.";if(Q.status===P$.Blocked)return`Resolve blocked step: ${r9(Q.uses).label}.`;let Z=r9(Q.uses);if(Q.advance===T.Human)return`${Z.nextAction} Human approval required.`;if(Q.advance===T.Ask)return`${Z.nextAction} Ask before continuing.`;return Z.nextAction}function x8($){return $.steps.map((Q)=>{let Z=[];if(!Q.enabled||Q.status===P$.Skipped)Z.push(P$.Skipped);if(Q.advance!==T.Auto)Z.push(Q.advance);return Z.length>0?`${Q.uses}(${Z.join(", ")})`:Q.uses}).join(" -> ")}function g8($){let Q=[],Z=$?.preset;if(Z&&!Q7(Z))Q.push(`Unknown Mission flow preset: ${Z}`);for(let[X,U]of($?.steps??[]).entries()){if(!DU(U.uses))Q.push(`Unknown Mission action at flow.steps[${X}]: ${U.uses}`);if(U.advance&&!RU(U.advance))Q.push(`Invalid advance at flow.steps[${X}]: ${U.advance}`)}return Q}function $B($){return NU[$].map((Q)=>({...Q}))}function QB($){return $.map((Q)=>({uses:Q.uses,enabled:Q.enabled,advance:Q.advance??ZB(Q.uses)}))}function ZB($){return r9($).externalWrite?T.Human:T.Manual}function XB($){if(!DU($.uses))throw Error(`Unknown Mission action: ${$.uses}`);let{advance:Q}=$;return{uses:$.uses,enabled:$.enabled,advance:UB(Q)}}function UB($){if(!$)return;if(RU($))return $;throw Error(`Invalid Mission flow advance: ${$}`)}function JB($,Q){if($.blocker)return P$.Blocked;let Z=WB[Q];if(!Z)return P$.Ready;return Z($)?P$.Done:P$.Ready}function GB($,Q){switch(Q){case A.PlanCreate:case A.PlanApprove:return $.plan?.latestPath;case A.ImplementationReport:return $.reports.implementation;case A.ReviewReport:return $.reports.review;case A.ValidationReport:return $.reports.validation;case A.QualityGate:return $.reports.quality;case A.PrPrepare:case A.PrCreate:return $.pr?.latestPath??$.pr?.url;default:return}}function _B($){let Q=YB($);if(!Q)return{mission:{issuePrefixes:[],retentionDays:Z7}};let Z=wL(Q,"utf8");return{filePath:Q,rootDir:SU(Q),mission:bU(Z)}}function YB($){let Q=$;while(!0){for(let X of v0){let U=bL(Q,X);if(NL(U))return U}let Z=SU(Q);if(Z===Q)return;Q=Z}}function zB($,Q){let Z=f8(Q);if(Z.length===0)return;h8($,{issuePrefixes:Z})}function HB($,Q){if(!Q)return;h8($,{tracker:{provider:Q}})}function VB($,Q){if(!Q)return;h8($,{git:{provider:Q}})}function wU($,Q){if(!Q)return;h8($,{flow:{preset:Q,steps:$B(Q)}})}function h8($,Q){let Z=k2($),X=bU(Z),U={...X,...Q,tracker:{...X.tracker,...Q.tracker},git:{...X.git,...Q.git},flow:{...X.flow,...Q.flow}};DB($,IB(U))}function R1($){$.inIssuePrefixes=!1,$.inTracker=!1,$.inGit=!1,$.inFlow=!1,$.inFlowSteps=!1}function OB($,Q){if(!/^\S/.test(Q))return!1;return $.inMission=/^mission:\s*$/.test(Q),R1($),$.currentFlowStepIndex=-1,!0}function KB($,Q){if(/^ {2}issuePrefixes:\s*$/.test(Q))return R1($),$.inIssuePrefixes=!0,$.mission.issuePrefixes=[],!0;if(/^ {2}tracker:\s*$/.test(Q))return R1($),$.inTracker=!0,$.mission.tracker=$.mission.tracker??{},!0;if(/^ {2}git:\s*$/.test(Q))return R1($),$.inGit=!0,$.mission.git=$.mission.git??{},!0;if(/^ {2}flow:\s*$/.test(Q))return R1($),$.inFlow=!0,$.mission.flow=$.mission.flow??{},!0;return!1}function qB($,Q){if(!($.inTracker&&/^ {4}provider:\s*(.+)$/.test(Q)))return!1;let Z=Q.match(/^ {4}provider:\s*(.+)$/)?.[1],X=Z?W1(Z):void 0;if(X)$.mission.tracker={provider:X};return!0}function LB($,Q){if(!$.inGit)return!1;if(/^ {4}provider:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}provider:\s*(.+)$/)?.[1],X=Z?W1(Z):void 0;if(X)$.mission.git={...$.mission.git,provider:X};return!0}if(/^ {4}baseBranch:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}baseBranch:\s*(.+)$/)?.[1];if(Z)$.mission.git={...$.mission.git,baseBranch:W1(Z)};return!0}if(/^ {4}prMode:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}prMode:\s*(.+)$/)?.[1],X=Z?W1(Z):void 0;if(X)$.mission.git={...$.mission.git,prMode:X};return!0}return!1}function BB($,Q){if(!$.inFlow)return!1;if(/^ {4}preset:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}preset:\s*(.+)$/)?.[1],X=Z?W1(Z):void 0;if(X)$.mission.flow={...$.mission.flow,preset:X};return!0}if(/^ {4}steps:\s*$/.test(Q))return $.inFlowSteps=!0,$.currentFlowStepIndex=-1,$.mission.flow={...$.mission.flow,steps:[]},!0;return!1}function AB($,Q){if(!/^ {6}-\s+uses:\s*(.+)$/.test(Q))return!1;let Z=Q.match(/^ {6}-\s+uses:\s*(.+)$/)?.[1],X=Z?W1(Z):void 0;if(X)$.mission.flow=$.mission.flow??{},$.mission.flow.steps=$.mission.flow.steps??[],$.mission.flow.steps.push({uses:X}),$.currentFlowStepIndex=$.mission.flow.steps.length-1;return!0}function MB($,Q){if($.currentFlowStepIndex<0)return!1;if(/^ {8}enabled:\s*(true|false)/.test(Q)){let Z=/^ {8}enabled:\s*true/.test(Q),X=$.mission.flow?.steps?.[$.currentFlowStepIndex];if(X)X.enabled=Z;return!0}if(/^ {8}advance:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {8}advance:\s*(.+)$/)?.[1],X=Z?W1(Z):void 0;if(X){let U=$.mission.flow?.steps?.[$.currentFlowStepIndex];if(U)U.advance=X}return!0}return!1}function EB($,Q){if(!$.inFlowSteps)return!1;if(AB($,Q))return!0;return MB($,Q)}function TB($,Q){if(/^ {2}repoId:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {2}repoId:\s*(.+)$/)?.[1];if(Z)$.mission.repoId=W1(Z);return R1($),!0}if(/^ {2}retentionDays:\s*(\d+)/.test(Q)){let Z=Q.match(/^ {2}retentionDays:\s*(\d+)/)?.[1];if(Z)$.mission.retentionDays=Number(Z);return R1($),!0}return!1}function jB($,Q){let Z=Q.trimEnd();if(!Z||Z.trimStart().startsWith("#"))return;if(OB($,Z))return;if(!$.inMission)return;if(KB($,Z))return;if(qB($,Z))return;if(LB($,Z))return;if(BB($,Z))return;if(EB($,Z))return;if(TB($,Z))return;if(/^ {2}\S/.test(Z))R1($);if($.inIssuePrefixes&&/^ {4}-\s+(.+)$/.test(Z)){let X=Z.match(/^ {4}-\s+(.+)$/)?.[1];if(X)$.mission.issuePrefixes.push(W1(X).toUpperCase())}}function bU($){let Q={mission:{issuePrefixes:[],retentionDays:Z7},inMission:!1,inIssuePrefixes:!1,inTracker:!1,inGit:!1,inFlow:!1,inFlowSteps:!1,currentFlowStepIndex:-1};for(let Z of $.split(/\r?\n/))jB(Q,Z);return mL(Q.mission,"sumr.yaml mission")}function W1($){let Q=$.replace(/\s+#.*$/,"").trim();if(Q.startsWith('"')&&Q.endsWith('"')||Q.startsWith("'")&&Q.endsWith("'"))return Q.slice(1,-1).trim();return Q}function SB($){if(!($.git?.provider||$.git?.baseBranch||$.git?.prMode))return[];let Q=[" git:"];if($.git.provider)Q.push(` provider: ${$.git.provider}`);if($.git.baseBranch)Q.push(` baseBranch: ${$.git.baseBranch}`);if($.git.prMode)Q.push(` prMode: ${$.git.prMode}`);return Q}function CB($){if(!$.flow?.steps?.length)return[];let Q=[" steps:"];for(let Z of $.flow.steps){if(Q.push(` - uses: ${Z.uses}`),Z.enabled!==void 0)Q.push(` enabled: ${Z.enabled}`);if(Z.advance)Q.push(` advance: ${Z.advance}`)}return Q}function FB($){if(!($.flow?.preset||$.flow?.steps?.length))return[];let Q=[" flow:"];if($.flow.preset)Q.push(` preset: ${$.flow.preset}`);return Q.push(...CB($)),Q}function IB($){let Q=["# Mission","mission:"];if($.repoId)Q.push(` repoId: ${$.repoId}`);if($.tracker?.provider)Q.push(" tracker:"),Q.push(` provider: ${$.tracker.provider}`);if(Q.push(...SB($)),Q.push(...FB($)),$.issuePrefixes.length>0)Q.push(" issuePrefixes:"),Q.push(...$.issuePrefixes.map((Z)=>` - ${Z}`));if($.retentionDays!==Z7)Q.push(` retentionDays: ${$.retentionDays}`);return Q}function DB($,Q){g1($,"mission",Q,{sectionComment:"# Mission"})}function o($={}){let Q=$.cwd??process.cwd(),Z=$.home??pq(),X=_B(Q),U=TL(Q),W=kB({cwd:Q,gitRoot:U,configuredRepoId:X.mission.repoId}),J=X.rootDir?j0.Repo:j0.Global,G=X.rootDir?D1(X.rootDir,NB,...bB):D1(Z,RB,...wB),_=D1(G,"repos",W.repoId);return{cwd:Q,home:Z,storageScope:J,baseDir:G,repoDir:_,missionsDir:D1(_,"missions"),repoId:W.repoId,repoLabel:W.repoLabel,config:X.mission,sumrConfigPath:X.filePath,sumrRootDir:X.rootDir,gitRoot:U}}function w1($,Q){let Z=DL(Q),X=D1($.missionsDir,Z);return{issueKey:Q,issuePathKey:Z,missionId:`${$.repoId}:${Q}`,missionDir:X,missionJsonPath:D1(X,"mission.json")}}function kB($){if($.configuredRepoId)return{repoId:fB($.configuredRepoId),repoLabel:$.configuredRepoId};let Q=e9($.cwd);if(Q){let Z=PB(Q);return{repoId:JU(Z),repoLabel:Z}}if($.gitRoot){let Z=`path:${$.gitRoot}`;return{repoId:JU(Z),repoLabel:Z}}return{repoId:j0.Global,repoLabel:j0.Global}}function PB($){let Q=$.trim().replace(/\.git$/,""),Z=Q.match(/^git@([^:]+):(.+)$/);if(Z?.[1]&&Z[2])return`${Z[1]}/${Z[2]}`;try{let X=new URL(Q),U=X.pathname.replace(/^\/+/,"");return`${X.hostname}/${U}`}catch{return Q.replace(/^[^@]+@/,"")}}function JU($){return mq("sha256").update($).digest("hex").slice(0,12)}function fB($){return $.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"repo"}function yB($){if(!$.gitRoot)return;let Q=D1($.gitRoot,".git");if(!lq(Q))return;return D1(Q,"info","exclude")}function dB($,Q,Z){let X=Q.indexOf("="),U=X===-1?Q.slice(2):Q.slice(2,X),W=X===-1?void 0:Q.slice(X+1);if(W!==void 0)return GU($,U,W),!1;if(uB.has(U)&&Z&&!Z.startsWith("-"))return GU($,U,Z),!0;return $[U]=!0,!1}function mB($){let Q={},Z=[];for(let X=0;X<$.length;X+=1){let U=$[X];if(!U)continue;if(!U.startsWith("--")){Z.push(U);continue}if(dB(Q,U,$[X+1]))X+=1}return{positionals:Z,options:Q}}function GU($,Q,Z){if(Q!=="prefix"){$[Q]=Z;return}let X=$[Q];if(Array.isArray(X)){X.push(Z);return}if(typeof X==="string"){$[Q]=[X,Z];return}$[Q]=Z}function s($,Q){let Z=$[Q];return typeof Z==="string"?Z:void 0}function lB($,Q){let Z=$[Q];if(Array.isArray(Z))return Z;if(typeof Z==="string")return[Z];return[]}function f$($,Q){return $[Q]===!0}function nB($){if($.status===d.Closed)return"Mission closed.";let Q=eL($);if(Q)return Q;if($.blocker)return`Resolve blocker: ${$.blocker.reason}`;if(!$.plan)return"Create and approve a plan.";if(!$.plan.approved)return"Approve the latest plan.";if(!$.claim)return"Claim the mission for implementation.";if(!$.reports.implementation)return"Create an implementation report.";if(!$.reports.review)return"Create a review report.";if(!$.reports.validation)return"Create a validation report.";if($.flow?.steps.some((Z)=>Z.uses===A.QualityGate)&&!$.reports.quality)return"Create a quality gate report.";return"Close the mission."}function iB($){if($.status===d.Closed)return d.Closed;if($.blocker)return d.Blocked;if($.reports.validation)return d.Validated;if($.reports.review)return d.Review;if($.claim)return d.InProgress;if($.plan?.approved)return d.Planned;return d.Planning}function P8(){return new Date().toISOString()}function C0($){d8($.missionsDir,{recursive:!0});let Q=s1($.repoDir,"state.json");if(u8(Q)){let U=sB(Q),W={version:1,repoId:$.repoId,createdAt:U.createdAt,repoLabel:$.repoLabel,storageScope:$.storageScope,tracker:$.config.tracker,git:$.config.git,flow:$.config.flow,issuePrefixes:i9($.config.issuePrefixes),updatedAt:P8()};return o9(Q,W),W}let Z=P8(),X={version:1,repoId:$.repoId,repoLabel:$.repoLabel,storageScope:$.storageScope,createdAt:Z,updatedAt:Z,tracker:$.config.tracker,git:$.config.git,flow:$.config.flow,issuePrefixes:i9($.config.issuePrefixes)};return o9(Q,X),X}function fU($,Q,Z){C0($);let X=w1($,Q),U=vU(X);if(U)return U;d8(X.missionDir,{recursive:!0});let W=P8(),J=yU({version:1,missionId:X.missionId,repoId:$.repoId,repoLabel:$.repoLabel,issueKey:Q,issuePathKey:X.issuePathKey,title:Z,status:d.Planning,storageScope:$.storageScope,createdAt:W,updatedAt:W,reports:{},flow:v8($.config),nextAction:"Create and approve a plan."});return c$($,J),J}function t1($,Q){return vU(w1($,Q))}function rB($,Q){let Z=Q.includes(":")?Q.slice(Q.indexOf(":")+1):Q,X=t1($,Z);if(X)return X;for(let U of O2($,{allRepos:!1}))if(U.missionId===Q||U.issuePathKey===Q)return U;return}function c$($,Q){let Z=w1($,Q.issueKey);d8(Z.missionDir,{recursive:!0});let X=yU({...Q,updatedAt:P8()});return o9(Z.missionJsonPath,X),X}function O2($,Q){let Z=Q.allRepos?YU(s1($.baseDir,"repos")):[$.repoDir],X=[];for(let U of Z){let W=s1(U,"missions");for(let J of YU(W)){let G=s1(J,"mission.json");if(!u8(G))continue;X.push(xU(G))}}return X.sort((U,W)=>W.updatedAt.localeCompare(U.updatedAt))}function oB($,Q,Z){if(!Z.force&&!Q.reports.validation)throw Error("Mission cannot close before a validation report exists. Use --force to override.");return c$($,{...Q,status:d.Closed,blocker:void 0,nextAction:"Mission closed."})}function aB($,Q){let Z=Date.now()-Q.olderThanDays*24*60*60*1000,X=[],U=[];for(let W of O2($,{allRepos:!0})){if(W.status!==d.Closed)continue;let J=Date.parse(W.updatedAt);if(Number.isNaN(J)||J>Z)continue;let G=w1({...$,repoId:W.repoId,repoLabel:W.repoLabel,repoDir:s1($.baseDir,"repos",W.repoId),missionsDir:s1($.baseDir,"repos",W.repoId,"missions")},W.issueKey).missionDir;if(X.push(G),!Q.dryRun)PU(G,{recursive:!0,force:!0}),U.push(G)}return{eligible:X,removed:U}}function yU($){let Q=$.status===d.Closed?d.Closed:iB($),Z=tL({...$,status:Q}),X=Q===d.Closed?"Mission closed.":nB(Z);return{...Z,nextAction:X}}function vU($){if(!u8($.missionJsonPath))return;return xU($.missionJsonPath)}function sB($){return lL(gU($),$)}function xU($){return pL(gU($),$)}function gU($){try{return JSON.parse(kU($,"utf8"))}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);throw Error(`${$} contains invalid JSON: ${Z}`)}}function o9($,Q){d8(tB($),{recursive:!0});let Z=`${$}.sumr-tmp-${Date.now()}`;_U(Z,`${JSON.stringify(Q,null,2)}
|
|
274
|
-
`,"utf8"),
|
|
275
|
-
`)}function
|
|
276
|
-
`)}function
|
|
273
|
+
}`,GX,v3,U$=()=>{},O$,u3,XH,HH,LH,SH,dH,X9,sH,eH,Y6,p$,TX,t0,P9,U2,EX,U9,$V,a1,_V,GV,VV,RX,k9,SV,k6,kX,hV,A$,$$,V0,J2,gX,s1,uV,tV,uX,UO,WO,SO,wO="${",y6,gO,iO="unknown_default_open_api",oX,aX,UK,zK,_6=null,$U=()=>{},BK,G6,gK,ZU,_q,G9,Gq,YU,Fq,xq,gq,hq,uq,dq,WU,mq,lq,tq,eq,$B,JB;var HU=v2(()=>{D();D();D();D();D();j4=Object.defineProperty;X$=j(()=>{z9=Math.max(C4().length-1,2),O7=/^application\/.+\+json$/i,K7=["200","201","202","204"],q7=["201","200","202","204"],B7=/^2\d\d$/,L7=new Set(["abstract","arguments","async","await","boolean","break","case","catch","class","const","continue",["debug","ger"].join(""),"declare","default","delete","do","else","enum","eval","export","extends","false","finally","for","from","function","if","implements","import","in","infer","instanceof","interface","keyof","let","module","namespace","never","new","null","number","object","package","private","protected","public","readonly","require","return","satisfies","static","string","super","switch","symbol","this","throw","true","try","type","typeof","undefined","unique","unknown","var","void","while","with","yield"]),E7=[`// ${T7}`,"// Generated by SUMR Kontract. Do not edit this file directly.","// Changes will be overwritten. Update the source OpenAPI/AsyncAPI spec and run:","// sumr kontract generate","// </auto-generated>","",""].join(`
|
|
274
|
+
`)}),S1=j(()=>{N={AsyncApiNats:"asyncapi-nats",TypeScriptAngular:"typescript-angular",TypeScriptAxios:"typescript-axios",TypeScriptFetch:"typescript-fetch",TypeScriptModels:"typescript-models",TypeScriptNestJs:"typescript-nestjs"},s8=[N.TypeScriptNestJs,N.AsyncApiNats,N.TypeScriptFetch,N.TypeScriptAxios,N.TypeScriptAngular,N.TypeScriptModels],C7=["camelCase","PascalCase","snake_case","original"],S7=["camelCase","PascalCase","snake_case","original"],F7=["PascalCase","camelCase","snake_case","UPPERCASE","original"],b$={AsyncApi:"asyncapi",ContractLink:"contract-link",OpenApi:"openapi"},Y$={Http:"http",Models:"models",Nats:"nats",Sdk:"sdk"}});j6=j(()=>{X$()});T6=j(()=>{X$(),N7={$schema:"https://biomejs.dev/schemas/2.4.15/schema.json",formatter:{enabled:!0,indentStyle:"space",indentWidth:2,lineWidth:100},javascript:{formatter:{quoteStyle:"single",semicolons:"always",trailingCommas:"es5"}}}});A9=j(()=>{X$()});r7=j(()=>{A9(),X$(),c7=/\$ref\s*:\s*['"]?([^'"\s#]+(?:#[^'"\s]+)?|#[^'"\s]+)['"]?/g,n7=new URL("../../package.json",import.meta.url),i7=["src/generators/**/*.ts","src/shared/**/*.ts","src/cli/generate*.ts"]}),wz=j(()=>{m1={Failed:"failed",Generated:"generated",Unchanged:"unchanged"}});Q3=j(()=>{S1()});C3=j(()=>{X$(),Q9=Promise.resolve()});WX=j(()=>{X$()}),_X=j(()=>{q0={AsyncApiNats:"asyncapi-nats",OpenApiNestJs:"openapi-nestjs",OpenApiSdk:"openapi-sdk"}}),v3=j(()=>{GX=["import { Observable } from 'rxjs';","",N3,"",w3,"",P3,"",b3,"",k3,"",f3,"",y3].join(`
|
|
275
|
+
`)});u3=j(()=>{O$={Command:"command",Event:"event",Query:"query"}});XH=j(()=>{U$(),u3()});HH=j(()=>{U$()});LH=j(()=>{X$(),j6(),T6(),v3(),U$(),XH(),HH()});SH=j(()=>{U$()});dH=j(()=>{U$()});sH=j(()=>{U$(),dH(),X9={addDtoImport:N9,addEnumImport:R9,emitHelperDto:w9}});eH=j(()=>{U$()}),U2=j(()=>{Y6={V3_0:"3.0",V3_1:"3.1",V3_2:"3.2"},p$={Array:"array",Enum:"enum",Object:"object",Ref:"ref",Scalar:"scalar",Unknown:"unknown"},TX={Boolean:"boolean",Integer:"integer",Number:"number",String:"string"},t0={Body:"body",Path:"path",Query:"query",Schema:"schema"},P9={Operation:"operation",Schema:"schema"}}),$V=j(()=>{EX=["get","post","put","patch","delete","options","head","trace"],U9={Params:"Params",Query:"Query"}});a1=j(()=>{U2()});_V=j(()=>{U2(),a1()});GV=j(()=>{U$()});VV=j(()=>{U2()});RX=j(()=>{U$(),U2(),_V(),GV(),VV(),a1()});k9=j(()=>{X$(),a1()});SV=j(()=>{U$(),U2(),$V(),RX(),a1(),k9()});k6=j(()=>{a1()});kX=j(()=>{SV(),RX(),a1(),k6()});hV=j(()=>{U$()});J2=j(()=>{A$={Delete:"delete",Get:"get",Patch:"patch",Post:"post",Put:"put"},$$={Path:"path",Query:"query"},V0={Array:"Array",Boolean:"Boolean",Number:"Number",Object:"Object",String:"String"}});gX=j(()=>{X$(),J2(),a1()}),uV=j(()=>{s1={Parameters:"parameters",RequestBodies:"requestBodies",Responses:"responses",Schemas:"schemas"}});tV=j(()=>{U$(),J2(),uV(),k9()});UO=j(()=>{U$(),J2(),gX(),tV(),uX=[A$.Get,A$.Post,A$.Put,A$.Patch,A$.Delete]});WO=j(()=>{UO()});SO=j(()=>{X$(),j6(),T6(),U$(),SH(),sH(),eH(),kX(),k6(),hV(),WO()});y6=j(()=>{X$(),S1()});gO=j(()=>{S1(),J2(),y6()});oX=j(()=>{U$(),y6()});UK=j(()=>{U$(),J2(),k9(),gX(),y6(),oX(),aX=[A$.Get,A$.Post,A$.Put,A$.Patch,A$.Delete]});zK=j(()=>{j6(),T6(),S1(),kX(),k6(),gO(),y6(),oX(),UK()});BK=j(()=>{LH(),SO(),zK(),_X(),$U()});gK=j(()=>{X$(),C3(),r7(),WX(),S1(),_X(),A9(),BK(),G6=new Map}),ZU={};_7(ZU,{runGenerate:()=>Yq});_q=j(()=>{X$(),j6(),T6(),r7(),wz(),S1(),Q3(),U3(),A9(),gK(),$U()}),Gq=j(()=>{G9={Failed:"failed",Passed:"passed"}}),YU={};_7(YU,{runValidate:()=>Sq});Fq=j(()=>{k6(),WX(),Gq(),S1()});X$();X$();S1();X$();xq=["input","output","natsPrefix"],gq=["name","input","targets"],hq=["name","output","generator"],uq=["type","prefix"],dq=["type","dto","dtos","zod","useSingleRequestParameter","stringEnums","enumUnknownDefaultCase","modelPropertyNaming","paramNaming","enumPropertyNaming","sortModelPropertiesByRequiredFlag","sortParamsByRequiredFlag"],WU=["type","useSingleRequestParameter","stringEnums","enumUnknownDefaultCase","modelPropertyNaming","paramNaming","enumPropertyNaming","sortModelPropertiesByRequiredFlag","sortParamsByRequiredFlag"],mq=[...WU,"providedIn"],lq=["type","stringEnums","enumUnknownDefaultCase","modelPropertyNaming","enumPropertyNaming","sortModelPropertiesByRequiredFlag"];tq={name:"kontract generate",description:"Generate TypeScript contracts and SDKs from configured schema sources",usage:["sumr kontract generate","sumr kontract generate --source portal --target web-fetch"],options:[{flag:"--source <name>",description:"Generate only one configured source"},{flag:"--target <name>",description:"Generate only one configured target"},{flag:"-c, --concurrency <n>",description:"Max parallel generators"},{flag:"-s, --specific <name>",description:"Generate only schemas matching this name"},{flag:"--clean",description:"Delete selected outputs and Kontract cache before generate"},{flag:"--verbose",description:"Verbose output"},{flag:"--quiet",description:"Suppress all output except errors"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr kontract generate --source portal --target api-nestjs"]},eq={name:"kontract init",description:"Activate Kontract AI guidance for this workspace",usage:["sumr kontract init","sumr kontract init --json"],options:[{flag:"--json",description:"Output a machine-readable JSON envelope"},{flag:"--quiet",description:"Suppress all output except errors"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr kontract init"]},$B={name:"kontract validate",description:"Validate configured OpenAPI and AsyncAPI schema sources",usage:["sumr kontract validate","sumr kontract validate --source portal"],options:[{flag:"--source <name>",description:"Validate only one configured source"},{flag:"--target <name>",description:"Validate schemas needed by one target"},{flag:"--max-concurrent <n>",description:"Max parallel validators"},{flag:"-c, --concurrency <n>",description:"Alias for --max-concurrent"},{flag:"--verbose",description:"Show passing files"},{flag:"--quiet",description:"Suppress all output except errors"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr kontract validate --source portal"]};JB=K1({name:"kontract",description:"Generate and validate API contract code",group:"modules",visibility:"public",commands:[T({name:"init",description:"Activate Kontract AI guidance for this workspace",group:"modules",visibility:"public",help:eq,execute:XB}),T({name:"generate",description:"Generate TypeScript contracts from API specs",group:"modules",visibility:"public",help:tq,execute:ZB}),T({name:"validate",description:"Validate API specifications",group:"modules",visibility:"public",help:$B,execute:UB})]})});var QJ={};y2(QJ,{missionModule:()=>dM});import{createHash as YB}from"crypto";import{existsSync as WB}from"fs";import{homedir as _B}from"os";import{join as D1}from"path";import{spawnSync as gB}from"child_process";import{createHash as mB}from"crypto";import{existsSync as iB,readFileSync as rB}from"fs";import{dirname as NU,join as oB}from"path";import{z as L}from"zod";import{createHash as zL}from"crypto";import{existsSync as $A,readFileSync as QA,writeSync as ZA}from"fs";import{join as XA}from"path";import{existsSync as n6,mkdirSync as i6,readdirSync as _A,readFileSync as gU,rmSync as hU,writeFileSync as KU}from"fs";import{basename as GA,join as t1}from"path";import{existsSync as fA,mkdirSync as yA,readFileSync as vA,writeFileSync as xA}from"fs";import{dirname as gA}from"path";import{mkdirSync as tU,readFileSync as YM,writeFileSync as eU}from"fs";import{join as q2}from"path";import{spawnSync as OQ}from"child_process";import{mkdirSync as MM,readFileSync as jM,writeFileSync as TM}from"fs";import{join as jU}from"path";function S0($,Q){let Z=gB("git",[...Q],{cwd:$,stdio:"pipe",encoding:"utf8"});if(Z.status!==0)return;return Z.stdout.trim()||void 0}function hB($){return S0($,["rev-parse","--show-toplevel"])}function UQ($){return S0($,["branch","--show-current"])}function uB($){return S0($,["rev-parse","--short=12","HEAD"])}function JQ($){return S0($,["config","--get","remote.origin.url"])}function dB($){let Q=S0($,["symbolic-ref","--quiet","--short","refs/remotes/origin/HEAD"]);if(Q?.startsWith("origin/"))return Q.slice(7);return S0($,["config","--get","init.defaultBranch"])}function u6($){let Q=$.map((Z)=>Z.trim().toUpperCase()).filter((Z)=>DU.test(Z));return[...new Set(Q)]}function RU($){return $.map((Q)=>Q.trim()).filter((Q)=>Q.length>0&&!DU.test(Q.toUpperCase()))}function e9($){let Q=u6($);return Q.length>0?Q:[...lB]}function d6($){let Q=$.issueKey.trim();if(!Q)return{ok:!1,message:"Mission issue key cannot be empty."};let Z=e9($.prefixes);if(Z.some((U)=>new RegExp(`^${nB(U)}-[0-9]+$`).test(Q)))return{ok:!0,issueKey:Q};if($.allowCustomKey&&pB.test(Q))return{ok:!0,issueKey:Q};return{ok:!1,message:`Mission issue key "${Q}" does not match configured prefixes (${Z.join(", ")}). Use --allow-custom-key for a slug.`}}function cB($){let Q=$.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80),Z=mB("sha256").update($).digest("hex").slice(0,8);return`${Q||"mission"}--${Z}`}function nB($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function YL($,Q){return YQ(sB,$,Q)}function WL($,Q){return YQ(UL,$,Q)}function _L($,Q){return YQ(JL,$,Q)}function YQ($,Q,Z){let X=$.safeParse(Q);if(X.success)return X.data;throw Error(GL(Z,X.error))}function GL($,Q){let Z=Q.issues.map((X)=>{return`${X.path.length>0?X.path.join("."):"<root>"}: ${X.message}`}).join("; ");return`${$} is not valid Mission data: ${Z}`}function kU($){return B2(EU,$)}function fU($){return B2(TU,$)}function WQ($){return B2(XQ,$)}function HL($){return B2(SU,$)}function VL($){return B2(CU,$)}function B2($,Q){return $.some((Z)=>Z===Q)}function $Q($){let Q=OL.find((Z)=>Z.id===$);if(Q)return Q;throw Error(`Unknown Mission action: ${$}`)}function KL($){let Q=p6($.flow);if(Q.length>0)throw Error(Q.join(`
|
|
276
|
+
`));let Z=$.flow?.preset,X=Z&&WQ(Z)?Z:D$.Basic,U=$.flow?.steps?.length?$.flow.steps.map(TL):yU[X];return{preset:X,steps:U}}function m6($){let Q=KL($),Z=ML(Q.steps);return{preset:Q.preset,hash:qL(Q.preset,Z),steps:Z.map((X)=>({uses:X.uses,enabled:X.enabled??!0,advance:X.advance??C.Manual,status:X.enabled===!1?f$.Skipped:f$.Pending}))}}function qL($,Q){return zL("sha256").update(JSON.stringify({preset:$,steps:Q})).digest("hex").slice(0,12)}function BL($){if(!$.flow)return $;let Q=$.flow.steps.map((Z)=>{let X=Z.enabled?SL($,Z.uses):f$.Skipped,U=FL($,Z.uses)??Z.artifactPath,J=X!==Z.status||U!==Z.artifactPath?new Date().toISOString():Z.updatedAt;return{...Z,status:X,artifactPath:U,updatedAt:J}});return{...$,flow:{...$.flow,steps:Q}}}function LL($){if(!$.flow)return;let Q=$.flow.steps.find((X)=>X.enabled&&X.status!==f$.Done);if(!Q)return"Close the mission.";if(Q.status===f$.Blocked)return`Resolve blocked step: ${$Q(Q.uses).label}.`;let Z=$Q(Q.uses);if(Q.advance===C.Human)return`${Z.nextAction} Human approval required.`;if(Q.advance===C.Ask)return`${Z.nextAction} Ask before continuing.`;return Z.nextAction}function l6($){return $.steps.map((Q)=>{let Z=[];if(!Q.enabled||Q.status===f$.Skipped)Z.push(f$.Skipped);if(Q.advance!==C.Auto)Z.push(Q.advance);return Z.length>0?`${Q.uses}(${Z.join(", ")})`:Q.uses}).join(" -> ")}function p6($){let Q=[],Z=$?.preset;if(Z&&!WQ(Z))Q.push(`Unknown Mission flow preset: ${Z}`);for(let[X,U]of($?.steps??[]).entries()){if(!kU(U.uses))Q.push(`Unknown Mission action at flow.steps[${X}]: ${U.uses}`);if(U.advance&&!fU(U.advance))Q.push(`Invalid advance at flow.steps[${X}]: ${U.advance}`)}return Q}function AL($){return yU[$].map((Q)=>({...Q}))}function ML($){return $.map((Q)=>({uses:Q.uses,enabled:Q.enabled,advance:Q.advance??jL(Q.uses)}))}function jL($){return $Q($).externalWrite?C.Human:C.Manual}function TL($){if(!kU($.uses))throw Error(`Unknown Mission action: ${$.uses}`);let{advance:Q}=$;return{uses:$.uses,enabled:$.enabled,advance:EL(Q)}}function EL($){if(!$)return;if(fU($))return $;throw Error(`Invalid Mission flow advance: ${$}`)}function SL($,Q){if($.blocker)return f$.Blocked;let Z=CL[Q];if(!Z)return f$.Ready;return Z($)?f$.Done:f$.Ready}function FL($,Q){switch(Q){case A.PlanCreate:case A.PlanApprove:return $.plan?.latestPath;case A.ImplementationReport:return $.reports.implementation;case A.ReviewReport:return $.reports.review;case A.ValidationReport:return $.reports.validation;case A.QualityGate:return $.reports.quality;case A.PrPrepare:case A.PrCreate:return $.pr?.latestPath??$.pr?.url;default:return}}function IL($){let Q=DL($);if(!Q)return{mission:{issuePrefixes:[],retentionDays:_Q}};let Z=rB(Q,"utf8");return{filePath:Q,rootDir:NU(Q),mission:xU(Z)}}function DL($){let Q=$;while(!0){for(let X of h0){let U=oB(Q,X);if(iB(U))return U}let Z=NU(Q);if(Z===Q)return;Q=Z}}function RL($,Q){let Z=u6(Q);if(Z.length===0)return;c6($,{issuePrefixes:Z})}function NL($,Q){if(!Q)return;c6($,{tracker:{provider:Q}})}function wL($,Q){if(!Q)return;c6($,{git:{provider:Q}})}function vU($,Q){if(!Q)return;c6($,{flow:{preset:Q,steps:AL(Q)}})}function c6($,Q){let Z=g2($),X=xU(Z),U={...X,...Q,tracker:{...X.tracker,...Q.tracker},git:{...X.git,...Q.git},flow:{...X.flow,...Q.flow}};cL($,pL(U))}function R1($){$.inIssuePrefixes=!1,$.inTracker=!1,$.inGit=!1,$.inFlow=!1,$.inFlowSteps=!1}function PL($,Q){if(!/^\S/.test(Q))return!1;return $.inMission=/^mission:\s*$/.test(Q),R1($),$.currentFlowStepIndex=-1,!0}function bL($,Q){if(/^ {2}issuePrefixes:\s*$/.test(Q))return R1($),$.inIssuePrefixes=!0,$.mission.issuePrefixes=[],!0;if(/^ {2}tracker:\s*$/.test(Q))return R1($),$.inTracker=!0,$.mission.tracker=$.mission.tracker??{},!0;if(/^ {2}git:\s*$/.test(Q))return R1($),$.inGit=!0,$.mission.git=$.mission.git??{},!0;if(/^ {2}flow:\s*$/.test(Q))return R1($),$.inFlow=!0,$.mission.flow=$.mission.flow??{},!0;return!1}function kL($,Q){if(!($.inTracker&&/^ {4}provider:\s*(.+)$/.test(Q)))return!1;let Z=Q.match(/^ {4}provider:\s*(.+)$/)?.[1],X=Z?J1(Z):void 0;if(X)$.mission.tracker={provider:X};return!0}function fL($,Q){if(!$.inGit)return!1;if(/^ {4}provider:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}provider:\s*(.+)$/)?.[1],X=Z?J1(Z):void 0;if(X)$.mission.git={...$.mission.git,provider:X};return!0}if(/^ {4}baseBranch:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}baseBranch:\s*(.+)$/)?.[1];if(Z)$.mission.git={...$.mission.git,baseBranch:J1(Z)};return!0}if(/^ {4}prMode:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}prMode:\s*(.+)$/)?.[1],X=Z?J1(Z):void 0;if(X)$.mission.git={...$.mission.git,prMode:X};return!0}return!1}function yL($,Q){if(!$.inFlow)return!1;if(/^ {4}preset:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {4}preset:\s*(.+)$/)?.[1],X=Z?J1(Z):void 0;if(X)$.mission.flow={...$.mission.flow,preset:X};return!0}if(/^ {4}steps:\s*$/.test(Q))return $.inFlowSteps=!0,$.currentFlowStepIndex=-1,$.mission.flow={...$.mission.flow,steps:[]},!0;return!1}function vL($,Q){if(!/^ {6}-\s+uses:\s*(.+)$/.test(Q))return!1;let Z=Q.match(/^ {6}-\s+uses:\s*(.+)$/)?.[1],X=Z?J1(Z):void 0;if(X)$.mission.flow=$.mission.flow??{},$.mission.flow.steps=$.mission.flow.steps??[],$.mission.flow.steps.push({uses:X}),$.currentFlowStepIndex=$.mission.flow.steps.length-1;return!0}function xL($,Q){if($.currentFlowStepIndex<0)return!1;if(/^ {8}enabled:\s*(true|false)/.test(Q)){let Z=/^ {8}enabled:\s*true/.test(Q),X=$.mission.flow?.steps?.[$.currentFlowStepIndex];if(X)X.enabled=Z;return!0}if(/^ {8}advance:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {8}advance:\s*(.+)$/)?.[1],X=Z?J1(Z):void 0;if(X){let U=$.mission.flow?.steps?.[$.currentFlowStepIndex];if(U)U.advance=X}return!0}return!1}function gL($,Q){if(!$.inFlowSteps)return!1;if(vL($,Q))return!0;return xL($,Q)}function hL($,Q){if(/^ {2}repoId:\s*(.+)$/.test(Q)){let Z=Q.match(/^ {2}repoId:\s*(.+)$/)?.[1];if(Z)$.mission.repoId=J1(Z);return R1($),!0}if(/^ {2}retentionDays:\s*(\d+)/.test(Q)){let Z=Q.match(/^ {2}retentionDays:\s*(\d+)/)?.[1];if(Z)$.mission.retentionDays=Number(Z);return R1($),!0}return!1}function uL($,Q){let Z=Q.trimEnd();if(!Z||Z.trimStart().startsWith("#"))return;if(PL($,Z))return;if(!$.inMission)return;if(bL($,Z))return;if(kL($,Z))return;if(fL($,Z))return;if(yL($,Z))return;if(gL($,Z))return;if(hL($,Z))return;if(/^ {2}\S/.test(Z))R1($);if($.inIssuePrefixes&&/^ {4}-\s+(.+)$/.test(Z)){let X=Z.match(/^ {4}-\s+(.+)$/)?.[1];if(X)$.mission.issuePrefixes.push(J1(X).toUpperCase())}}function xU($){let Q={mission:{issuePrefixes:[],retentionDays:_Q},inMission:!1,inIssuePrefixes:!1,inTracker:!1,inGit:!1,inFlow:!1,inFlowSteps:!1,currentFlowStepIndex:-1};for(let Z of $.split(/\r?\n/))uL(Q,Z);return YL(Q.mission,"sumr.yaml mission")}function J1($){let Q=$.replace(/\s+#.*$/,"").trim();if(Q.startsWith('"')&&Q.endsWith('"')||Q.startsWith("'")&&Q.endsWith("'"))return Q.slice(1,-1).trim();return Q}function dL($){if(!($.git?.provider||$.git?.baseBranch||$.git?.prMode))return[];let Q=[" git:"];if($.git.provider)Q.push(` provider: ${$.git.provider}`);if($.git.baseBranch)Q.push(` baseBranch: ${$.git.baseBranch}`);if($.git.prMode)Q.push(` prMode: ${$.git.prMode}`);return Q}function mL($){if(!$.flow?.steps?.length)return[];let Q=[" steps:"];for(let Z of $.flow.steps){if(Q.push(` - uses: ${Z.uses}`),Z.enabled!==void 0)Q.push(` enabled: ${Z.enabled}`);if(Z.advance)Q.push(` advance: ${Z.advance}`)}return Q}function lL($){if(!($.flow?.preset||$.flow?.steps?.length))return[];let Q=[" flow:"];if($.flow.preset)Q.push(` preset: ${$.flow.preset}`);return Q.push(...mL($)),Q}function pL($){let Q=["# Mission","mission:"];if($.repoId)Q.push(` repoId: ${$.repoId}`);if($.tracker?.provider)Q.push(" tracker:"),Q.push(` provider: ${$.tracker.provider}`);if(Q.push(...dL($)),Q.push(...lL($)),$.issuePrefixes.length>0)Q.push(" issuePrefixes:"),Q.push(...$.issuePrefixes.map((Z)=>` - ${Z}`));if($.retentionDays!==_Q)Q.push(` retentionDays: ${$.retentionDays}`);return Q}function cL($,Q){h1($,"mission",Q,{sectionComment:"# Mission"})}function a($={}){let Q=$.cwd??process.cwd(),Z=$.home??_B(),X=IL(Q),U=hB(Q),J=aL({cwd:Q,gitRoot:U,configuredRepoId:X.mission.repoId}),Y=X.rootDir?C0.Repo:C0.Global,W=X.rootDir?D1(X.rootDir,iL,...oL):D1(Z,nL,...rL),_=D1(W,"repos",J.repoId);return{cwd:Q,home:Z,storageScope:Y,baseDir:W,repoDir:_,missionsDir:D1(_,"missions"),repoId:J.repoId,repoLabel:J.repoLabel,config:X.mission,sumrConfigPath:X.filePath,sumrRootDir:X.rootDir,gitRoot:U}}function w1($,Q){let Z=cB(Q),X=D1($.missionsDir,Z);return{issueKey:Q,issuePathKey:Z,missionId:`${$.repoId}:${Q}`,missionDir:X,missionJsonPath:D1(X,"mission.json")}}function aL($){if($.configuredRepoId)return{repoId:tL($.configuredRepoId),repoLabel:$.configuredRepoId};let Q=JQ($.cwd);if(Q){let Z=sL(Q);return{repoId:VU(Z),repoLabel:Z}}if($.gitRoot){let Z=`path:${$.gitRoot}`;return{repoId:VU(Z),repoLabel:Z}}return{repoId:C0.Global,repoLabel:C0.Global}}function sL($){let Q=$.trim().replace(/\.git$/,""),Z=Q.match(/^git@([^:]+):(.+)$/);if(Z?.[1]&&Z[2])return`${Z[1]}/${Z[2]}`;try{let X=new URL(Q),U=X.pathname.replace(/^\/+/,"");return`${X.hostname}/${U}`}catch{return Q.replace(/^[^@]+@/,"")}}function VU($){return YB("sha256").update($).digest("hex").slice(0,12)}function tL($){return $.trim().replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"repo"}function eL($){if(!$.gitRoot)return;let Q=D1($.gitRoot,".git");if(!WB(Q))return;return D1(Q,"info","exclude")}function JA($,Q,Z){let X=Q.indexOf("="),U=X===-1?Q.slice(2):Q.slice(2,X),J=X===-1?void 0:Q.slice(X+1);if(J!==void 0)return OU($,U,J),!1;if(UA.has(U)&&Z&&!Z.startsWith("-"))return OU($,U,Z),!0;return $[U]=!0,!1}function YA($){let Q={},Z=[];for(let X=0;X<$.length;X+=1){let U=$[X];if(!U)continue;if(!U.startsWith("--")){Z.push(U);continue}if(JA(Q,U,$[X+1]))X+=1}return{positionals:Z,options:Q}}function OU($,Q,Z){if(Q!=="prefix"){$[Q]=Z;return}let X=$[Q];if(Array.isArray(X)){X.push(Z);return}if(typeof X==="string"){$[Q]=[X,Z];return}$[Q]=Z}function t($,Q){let Z=$[Q];return typeof Z==="string"?Z:void 0}function WA($,Q){let Z=$[Q];if(Array.isArray(Z))return Z;if(typeof Z==="string")return[Z];return[]}function y$($,Q){return $[Q]===!0}function zA($){if($.status===d.Closed)return"Mission closed.";let Q=LL($);if(Q)return Q;if($.blocker)return`Resolve blocker: ${$.blocker.reason}`;if(!$.plan)return"Create and approve a plan.";if(!$.plan.approved)return"Approve the latest plan.";if(!$.claim)return"Claim the mission for implementation.";if(!$.reports.implementation)return"Create an implementation report.";if(!$.reports.review)return"Create a review report.";if(!$.reports.validation)return"Create a validation report.";if($.flow?.steps.some((Z)=>Z.uses===A.QualityGate)&&!$.reports.quality)return"Create a quality gate report.";return"Close the mission."}function HA($){if($.status===d.Closed)return d.Closed;if($.blocker)return d.Blocked;if($.reports.validation)return d.Validated;if($.reports.review)return d.Review;if($.claim)return d.InProgress;if($.plan?.approved)return d.Planned;return d.Planning}function h6(){return new Date().toISOString()}function F0($){i6($.missionsDir,{recursive:!0});let Q=t1($.repoDir,"state.json");if(n6(Q)){let U=qA(Q),J={version:1,repoId:$.repoId,createdAt:U.createdAt,repoLabel:$.repoLabel,storageScope:$.storageScope,tracker:$.config.tracker,git:$.config.git,flow:$.config.flow,issuePrefixes:e9($.config.issuePrefixes),updatedAt:h6()};return QQ(Q,J),J}let Z=h6(),X={version:1,repoId:$.repoId,repoLabel:$.repoLabel,storageScope:$.storageScope,createdAt:Z,updatedAt:Z,tracker:$.config.tracker,git:$.config.git,flow:$.config.flow,issuePrefixes:e9($.config.issuePrefixes)};return QQ(Q,X),X}function uU($,Q,Z){F0($);let X=w1($,Q),U=mU(X);if(U)return U;i6(X.missionDir,{recursive:!0});let J=h6(),Y=dU({version:1,missionId:X.missionId,repoId:$.repoId,repoLabel:$.repoLabel,issueKey:Q,issuePathKey:X.issuePathKey,title:Z,status:d.Planning,storageScope:$.storageScope,createdAt:J,updatedAt:J,reports:{},flow:m6($.config),nextAction:"Create and approve a plan."});return n$($,Y),Y}function e1($,Q){return mU(w1($,Q))}function VA($,Q){let Z=Q.includes(":")?Q.slice(Q.indexOf(":")+1):Q,X=e1($,Z);if(X)return X;for(let U of L2($,{allRepos:!1}))if(U.missionId===Q||U.issuePathKey===Q)return U;return}function n$($,Q){let Z=w1($,Q.issueKey);i6(Z.missionDir,{recursive:!0});let X=dU({...Q,updatedAt:h6()});return QQ(Z.missionJsonPath,X),X}function L2($,Q){let Z=Q.allRepos?qU(t1($.baseDir,"repos")):[$.repoDir],X=[];for(let U of Z){let J=t1(U,"missions");for(let Y of qU(J)){let W=t1(Y,"mission.json");if(!n6(W))continue;X.push(lU(W))}}return X.sort((U,J)=>J.updatedAt.localeCompare(U.updatedAt))}function OA($,Q,Z){if(!Z.force&&!Q.reports.validation)throw Error("Mission cannot close before a validation report exists. Use --force to override.");return n$($,{...Q,status:d.Closed,blocker:void 0,nextAction:"Mission closed."})}function KA($,Q){let Z=Date.now()-Q.olderThanDays*24*60*60*1000,X=[],U=[];for(let J of L2($,{allRepos:!0})){if(J.status!==d.Closed)continue;let Y=Date.parse(J.updatedAt);if(Number.isNaN(Y)||Y>Z)continue;let W=w1({...$,repoId:J.repoId,repoLabel:J.repoLabel,repoDir:t1($.baseDir,"repos",J.repoId),missionsDir:t1($.baseDir,"repos",J.repoId,"missions")},J.issueKey).missionDir;if(X.push(W),!Q.dryRun)hU(W,{recursive:!0,force:!0}),U.push(W)}return{eligible:X,removed:U}}function dU($){let Q=$.status===d.Closed?d.Closed:HA($),Z=BL({...$,status:Q}),X=Q===d.Closed?"Mission closed.":zA(Z);return{...Z,nextAction:X}}function mU($){if(!n6($.missionJsonPath))return;return lU($.missionJsonPath)}function qA($){return WL(pU($),$)}function lU($){return _L(pU($),$)}function pU($){try{return JSON.parse(gU($,"utf8"))}catch(Q){let Z=Q instanceof Error?Q.message:String(Q);throw Error(`${$} contains invalid JSON: ${Z}`)}}function QQ($,Q){i6(BA($),{recursive:!0});let Z=`${$}.sumr-tmp-${Date.now()}`;KU(Z,`${JSON.stringify(Q,null,2)}
|
|
277
|
+
`,"utf8"),KU($,gU(Z,"utf8"),"utf8"),hU(Z,{force:!0})}function qU($){if(!n6($))return[];return _A($,{withFileTypes:!0}).filter((Q)=>Q.isDirectory()).map((Q)=>t1($,Q.name))}function BA($){return $.slice(0,$.length-GA($).length-1)}function _$($){return YA($.argv.slice(1))}function g($){return y$($,"json")}function h($){ZA(1,`${JSON.stringify($,null,2)}
|
|
278
|
+
`)}function cU($){return!g($)&&l0()}function P1($,Q,Z){if(!Z)return j$("Missing issue key.",`sumr mission ${$.argv[0]??"<command>"} <issueKey>`),{ok:!1,code:1};let X=a(),U=d6({issueKey:Z,prefixes:X.config.issuePrefixes,allowCustomKey:y$(Q,"allow-custom-key")});if(!U.ok)return m(U.message),{ok:!1,code:1};return{ok:!0,issueKey:U.issueKey}}function GQ($,Q){let Z=a(),X=e1(Z,$);if(X)return X;return uU(Z,$,Q??$)}function zQ($){return`${$.issueKey.padEnd(12)} ${$.status.padEnd(12)} ${$.nextAction}`}function LA($,Q={}){let Z=[`Mission: ${$.issueKey}`,`Title: ${$.title}`,`Status: ${$.status}`,`Repo: ${$.repoLabel} (${$.repoId})`,`Next: ${$.nextAction}`];if(AA(Z,$,Q.currentBranch),$.plan)Z.push(`Plan: ${$.plan.latestPath}${$.plan.approved?" (approved)":" (pending approval)"}`);if($.claim)MA(Z,$.claim);if($.blocker)Z.push(`Blocker: ${$.blocker.reason}`);if($.flow)Z.push(`Flow: ${$.flow.preset} (${$.flow.hash})`),Z.push(`Flow steps: ${l6($.flow)}`);return jA(Z,$),TA(Z,$),Z.join(`
|
|
279
|
+
`)}function AA($,Q,Z){if(Z)$.push(`Current branch: ${Z}`);if(Q.branch)$.push(`Mission branch: ${Q.branch}`);if(Q.sourceSha)$.push(`Mission source SHA: ${Q.sourceSha}`);let X=Q.claim?.branch??Q.branch;if(X&&Z&&Z!==X)$.push(`Branch warning: current branch ${Z} does not match mission branch ${X}. Switch to the recorded branch or intentionally reclaim the mission before implementation or PR creation.`)}function MA($,Q){let Z=[`${Q.agent} at ${Q.startedAt}`];if(Q.branch)Z.push(`branch ${Q.branch}`);if(Q.sourceSha)Z.push(`sha ${Q.sourceSha}`);$.push(`Claim: ${Z.join(", ")}`)}function jA($,Q){if(!(Q.pr?.latestPath||Q.pr?.url))return;if($.push("PR:"),Q.pr.latestPath)$.push(` preview: ${Q.pr.latestPath}`);if(Q.pr.url)$.push(` url: ${Q.pr.url}`)}function TA($,Q){let Z=Object.entries(Q.reports);if(Z.length===0)return;$.push("Reports:");for(let[X,U]of Z)$.push(` ${X}: ${U}`)}function j$($,Q){m($,{title:"Usage",details:Q})}function m($,Q={}){L$($,Q)}function EA($){let Q={[d.Blocked]:0,[d.Planning]:1,[d.Planned]:2,[d.InProgress]:3,[d.Review]:4,[d.Validated]:5};return[...$].sort((Z,X)=>{let U=(Q[Z.status]??99)-(Q[X.status]??99);if(U!==0)return U;return X.updatedAt.localeCompare(Z.updatedAt)})[0]}function HQ($,Q){return`${DA()}-${$.issuePathKey}.${Q}.md`}function CA($,Q){return`# Mission Plan: ${$}
|
|
277
280
|
|
|
278
281
|
## Objective
|
|
279
282
|
|
|
@@ -286,7 +289,7 @@ ${Q}
|
|
|
286
289
|
## Verification
|
|
287
290
|
|
|
288
291
|
- TODO: list required checks.
|
|
289
|
-
`}function
|
|
292
|
+
`}function SA($,Q){return`# ${nU($)} Report: ${Q.issueKey}
|
|
290
293
|
|
|
291
294
|
## Summary
|
|
292
295
|
|
|
@@ -300,17 +303,17 @@ TODO: summarize the ${$} result.
|
|
|
300
303
|
## Next Steps
|
|
301
304
|
|
|
302
305
|
- ${Q.nextAction}
|
|
303
|
-
`}function
|
|
304
|
-
`),"Mission Flow");return 0}function
|
|
305
|
-
Allowed: ${
|
|
306
|
-
${
|
|
306
|
+
`}function FA($){for(let Q of[".github/pull_request_template.md",".github/PULL_REQUEST_TEMPLATE.md","pull_request_template.md","PULL_REQUEST_TEMPLATE.md"]){let Z=XA($,Q);if($A(Z))return QA(Z,"utf8")}return}function IA($){return IU.includes($)}function nU($){return`${$.charAt(0).toUpperCase()}${$.slice(1)}`}function DA(){return new Date().toISOString().replace(/[:.]/g,"-")}function RA($){let{positionals:Q,options:Z}=_$($),X=Q[0],U=a();if(!X||X===H2.SHOW)return Promise.resolve(NA(U,Z));if(X===H2.LIST)return Promise.resolve(wA(Z));if(X===H2.VALIDATE)return Promise.resolve(PA(U,Z));if(X===H2.EXPORT)return Promise.resolve(bA(U,Z));if(X===H2.USE)return Promise.resolve(kA(U,Z,Q[1]));return j$(`Unknown flow command: ${X}`,"sumr mission flow <list|show|use|validate|export>"),Promise.resolve(1)}function NA($,Q){let Z=p6($.config.flow);if(Z.length>0){if(g(Q))h({ok:!1,errors:Z});else d$(Z,"Mission flow errors");return 1}let X=m6($.config);if(g(Q))h({ok:!0,preset:X.preset,hash:X.hash,steps:X.steps,errors:Z});else u$([`Preset: ${X.preset}`,`Hash: ${X.hash}`,`Flow: ${l6(X)}`].join(`
|
|
307
|
+
`),"Mission Flow");return 0}function wA($){if(g($))h({ok:!0,presets:K2});else d$(K2,"Mission flow presets");return 0}function PA($,Q){let Z=p6($.config.flow);if(g(Q))h({ok:Z.length===0,errors:Z});else if(Z.length===0)f("Mission flow is valid.");else d$(Z,"Mission flow errors");return Z.length===0?0:1}function bA($,Q){let Z=p6($.config.flow);if(Z.length>0){if(g(Q))h({ok:!1,errors:Z});else d$(Z,"Mission flow errors");return 1}let X=m6($.config);return h({ok:!0,preset:X.preset,hash:X.hash,text:l6(X),steps:X.steps}),0}function kA($,Q,Z){if(!Z||!WQ(Z))return j$("Missing or invalid flow preset.",`sumr mission flow use <preset>
|
|
308
|
+
Allowed: ${K2.join(", ")}`),1;if(!$.sumrConfigPath)return m("No sumr.yaml found. Run Mission inside a SUMR repo to set a repo flow."),1;vU($.sumrConfigPath,Z);let X=a(),U=m6(X.config);if(g(Q))h({ok:!0,preset:U.preset,hash:U.hash,steps:U.steps});else f(`Mission flow set: ${U.preset}`,{title:"Flow",fields:[{label:"Flow",value:l6(U)}]});return 0}function hA($){let Q=$.trim().toLowerCase();return HL(Q)?Q:void 0}function iU($){if(!$)return"not configured";return VQ.find((Q)=>Q.value===$)?.label??$}function rU($){if(!$)return;let Q=$.toLowerCase();if(Q.includes("github.com"))return o.Github;if(Q.includes("gitlab.com"))return o.Gitlab;if(Q.includes("bitbucket.org"))return o.Bitbucket;if(Q.includes("dev.azure.com")||Q.includes("visualstudio.com"))return o.AzureDevops;if(Q.includes("gitea"))return o.Gitea;if(Q.includes("codeberg.org"))return o.Codeberg;return}function oU($){let Q=r6.find((Z)=>Z.value===$);if(!Q)throw Error(`Unsupported mission tracker: ${$}`);return Q}function aU($){let Q=$.trim().toLowerCase();return VL(Q)?Q:void 0}function BU($,Q,Z){let X=uA.exec($);if(!X)return{ok:!1,message:Z};return{ok:!0,issueKey:`${Q}-${X[1]}`}}function LU($,Q){let Z=$.toUpperCase();if(!dA.test(Z))return{ok:!1,message:`Enter a ${Q} like PROJECT-123.`};return{ok:!0,issueKey:Z}}function mA($){let Q=$.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80);if(Q.length<2)return{ok:!1,message:"Enter at least two letters or numbers."};return{ok:!0,issueKey:Q}}function lA($,Q){if($===p.Github)return BU(Q,"GH","Enter a GitHub issue number like 123 or #123.");if($===p.Gitlab)return BU(Q,"GL","Enter a GitLab issue IID like 123 or #123.");if($===p.Jira)return LU(Q,"Jira ticket key");if($===p.Linear)return LU(Q,"Linear issue identifier");if($===p.AzureBoards){let Z=Q.match(/^(?:AB#?|work item\s+)?([0-9]+)$/i);if(Z?.[1])return{ok:!0,issueKey:`AB-${Z[1]}`}}return}function ZQ($,Q){let Z=Q.trim();if(!Z)return{ok:!1,message:"Enter a mission ID."};return lA($,Z)??mA(Z)}async function pA($){let{options:Q}=_$($),Z=a(),X=await $M(Q,Z);if(!X.ok)return X.code;if(Z.sumrConfigPath)cA(Z.sumrConfigPath,X.config);let U=F0(Z);u0("mission",{cwd:Z.cwd});let J=eL(Z),Y=nA(Z,J),W={context:Z,config:X.config,root:U,excludePath:J,excludeUpdated:Y,playbookSyncRecommended:Z.storageScope===C0.Repo};if(g(Q))iA(W);else rA(W);return 0}function cA($,Q){if(Q.tracker)NL($,Q.tracker);if(Q.gitProvider)wL($,Q.gitProvider);if(Q.flowPreset)vU($,Q.flowPreset);if(Q.prefixes.length>0)RL($,Q.prefixes)}function nA($,Q){if(!(Q&&$.storageScope===C0.Repo))return!1;yA(gA(Q),{recursive:!0});let Z=[".sumr-cache/mission/",".sumr-cache/activations.json"],X=fA(Q)?vA(Q,"utf8"):"",U=X.split(/\r?\n/),J=Z.filter((Y)=>!U.includes(Y));if(J.length===0)return!1;return xA(Q,`${X.trimEnd()}
|
|
309
|
+
${J.join(`
|
|
307
310
|
`)}
|
|
308
|
-
`,"utf8"),!0}function
|
|
309
|
-
Allowed: ${
|
|
311
|
+
`,"utf8"),!0}function iA($){let{context:Q,config:Z}=$;h({ok:!0,root:$.root,baseDir:Q.baseDir,excludePath:$.excludePath,excludeUpdated:$.excludeUpdated,tracker:Z.tracker??Q.config.tracker?.provider,gitProvider:Z.gitProvider??Q.config.git?.provider,flowPreset:Z.flowPreset??Q.config.flow?.preset??D$.Basic,issuePrefixes:Z.prefixes.length>0?Z.prefixes:Q.config.issuePrefixes,playbookSyncRecommended:$.playbookSyncRecommended})}function rA($){let{context:Q,config:Z}=$;f("Mission initialized",{title:"Storage",fields:[{label:"Root",value:Q.baseDir},{label:"Repo",value:`${Q.repoLabel} (${Q.repoId})`},{label:"Work item source",value:UM(Z.tracker??Q.config.tracker?.provider)},{label:"Git provider",value:iU(Z.gitProvider??Q.config.git?.provider)},{label:"Flow",value:Z.flowPreset??Q.config.flow?.preset??D$.Basic},{label:"Ticket prefixes",value:JM(Z.prefixes.length>0?Z.prefixes:Q.config.issuePrefixes)},{label:"Git exclude",value:$.excludeUpdated?$.excludePath:void 0},{label:"AI resources",value:$.playbookSyncRecommended?"Run `sumr playbook sync` to install Mission guidance into AI tools":void 0}]})}function oA($){let Q=t($,"tracker")??t($,"provider"),Z=Q?aU(Q):void 0;if(Q&&!Z)return j$(`Unsupported tracker: ${Q}`,`Allowed trackers: ${r6.map((X)=>X.value).join(", ")}`),N1;return Z}function aA($){let Q=t($,"git-provider"),Z=Q?hA(Q):void 0;if(Q&&!Z)return j$(`Unsupported git provider: ${Q}`,`Allowed git providers: ${VQ.map((X)=>X.value).join(", ")}`),N1;return Z}function sA($){let Q=t($,"flow"),Z=K2.find((X)=>X===Q);if(Q&&!Z)return j$(`Unsupported flow preset: ${Q}`,`Allowed flow presets: ${K2.join(", ")}`),N1;return Z}function tA($){let Q=WA($,"prefix");if(Q.length>0){let Z=RU(Q);if(Z.length>0)return m(`Invalid issue prefix${Z.length===1?"":"es"}: ${Z.join(", ")}. Prefixes must start with a letter and contain only letters or numbers.`),N1}return Q}function eA($){let Q=oA($);if(Q===N1)return{error:!0};let Z=aA($);if(Z===N1)return{error:!0};let X=sA($);if(X===N1)return{error:!0};let U=tA($);if(U===N1)return{error:!0};return{tracker:Q,gitProvider:Z,flowPreset:X,prefixes:U}}async function $M($,Q){let Z=eA($);if("error"in Z)return{ok:!1,code:1};if(Z.tracker||Z.gitProvider||Z.flowPreset||Z.prefixes.length>0)return{ok:!0,config:{tracker:Z.tracker,gitProvider:Z.gitProvider,flowPreset:Z.flowPreset,prefixes:u6(Z.prefixes)}};if(!Q.sumrConfigPath||Q.config.tracker?.provider||y$($,"yes")||!cU($))return{ok:!0,config:{prefixes:[]}};return{ok:!0,config:await QM(Q)}}async function QM($){let Q=await a$({message:"Where do this repo's work item IDs usually come from?",options:[...r6.map((J)=>({value:J.value,label:J.label,hint:J.hint})),{value:AU.Skip,label:"Skip for now",hint:"Ask per mission"}],initialValue:p.Github});if(!Q||Q===AU.Skip)return{prefixes:[]};let Z=await ZM($),X=await XM();if(Q!==p.Jira&&Q!==p.Linear)return{tracker:Q,gitProvider:Z,flowPreset:X,prefixes:[]};let U=await G0({message:`${Q===p.Jira?"Jira project":"Linear team"} prefixes`,placeholder:"SUM, ENG, OPS",validate:(J)=>{let Y=MU(J??"");if(Y.length===0)return"Enter at least one prefix, like SUM.";let W=RU(Y);if(W.length>0)return`Invalid prefix${W.length===1?"":"es"}: ${W.join(", ")}`;return}});if(!U)return{tracker:Q,gitProvider:Z,flowPreset:X,prefixes:[]};return{tracker:Q,gitProvider:Z,flowPreset:X,prefixes:u6(MU(U))}}async function ZM($){let Q=rU(JQ($.cwd));return await a$({message:"Which git or PR provider should Mission recognize?",options:VQ.map((Z)=>({value:Z.value,label:Z.label,hint:Z.hint})),initialValue:Q??o.GenericGit})}async function XM(){return await a$({message:"Which Mission flow should this repo use?",options:[{value:D$.StandardDelivery,label:"Standard delivery",hint:"Plan, approval, delivery, validation, PR preview"},{value:D$.PlanningOnly,label:"Planning only",hint:"Stop after a reviewable plan"},{value:D$.Basic,label:"Basic",hint:"Current lightweight Mission lifecycle"},{value:D$.FullDelivery,label:"Full delivery",hint:"Richer flow with research, quality gate, and PR assist"}],initialValue:D$.StandardDelivery})}function UM($){if(!$)return"not configured";return oU($).label}function JM($){if($.length===0)return;return $.join(", ")}function MU($){return $.split(/[,\s]+/).map((Q)=>Q.trim()).filter(Boolean)}function WM($){let{positionals:Q,options:Z}=_$($),X=a();if(F0(X),Q[0]){let J=VA(X,Q[0]);if(!J)return m(`Mission not found: ${Q[0]}`),Promise.resolve(1);if(g(Z))h({ok:!0,mission:J});else u$(LA(J,{currentBranch:UQ(X.cwd)}),"Status");return Promise.resolve(0)}let U=L2(X,{allRepos:!1});if(g(Z))h({ok:!0,storage:X.baseDir,missions:U});else if(o$("Mission workspace",{title:"Storage",fields:[{label:"Root",value:X.baseDir},{label:"Repo",value:`${X.repoLabel} (${X.repoId})`}]}),U.length===0)o$("No missions found.");else d$(U.map(zQ),"Missions");return Promise.resolve(0)}function _M($){let{options:Q}=_$($),Z=a();F0(Z);let X=y$(Q,"all"),U=L2(Z,{allRepos:X});if(g(Q))h({ok:!0,missions:U});else if(U.length===0)o$("No missions found.");else d$(U.map(zQ),X?"All missions":"Missions");return Promise.resolve(0)}function GM($){let{options:Q}=_$($),Z=a();F0(Z);let X=L2(Z,{allRepos:y$(Q,"all")}).filter((J)=>J.status!==d.Closed),U=EA(X);if(g(Q))h({ok:!0,mission:U});else if(!U)o$("No open missions.");else u$(zQ(U),"Next mission");return Promise.resolve(0)}function zM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return Promise.resolve(X.code);let U=a(),J=GQ(X.issueKey),Y=w1(U,X.issueKey),W=q2(Y.missionDir,"plans");tU(W,{recursive:!0});let _=t(Z,"from"),G=q2(W,HQ(J,"plan")),z=_?YM(_,"utf8"):CA(J.issueKey,J.title);eU(G,z,"utf8");let H=y$(Z,"approve"),V=n$(U,{...J,plan:{latestPath:G,approved:H,approvedAt:H?new Date().toISOString():void 0}});if(g(Z))h({ok:!0,mission:V,planPath:G});else f("Plan written",{title:"Plan",fields:[{label:"Path",value:G},{label:"Next",value:V.nextAction}]});return Promise.resolve(0)}function HM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return Promise.resolve(X.code);let U=a(),J=e1(U,X.issueKey);if(!J)return m(`Mission not found: ${X.issueKey}`),Promise.resolve(1);if(!J.plan)return m("Create a plan before approving this mission."),Promise.resolve(1);if(J.plan.approved){if(g(Z))h({ok:!0,mission:J,alreadyApproved:!0});else f(`Plan already approved: ${J.issueKey}`,{title:"Approval",fields:[{label:"Plan",value:J.plan.latestPath},{label:"Next",value:J.nextAction}]});return Promise.resolve(0)}let Y=n$(U,{...J,plan:{...J.plan,approved:!0,approvedAt:new Date().toISOString()}});if(g(Z))h({ok:!0,mission:Y,alreadyApproved:!1});else f(`Plan approved: ${Y.issueKey}`,{title:"Approval",fields:[{label:"Plan",value:Y.plan?.latestPath??J.plan.latestPath},{label:"Next",value:Y.nextAction}]});return Promise.resolve(0)}function VM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return Promise.resolve(X.code);let U=a(),J=e1(U,X.issueKey);if(!J)return m(`Mission not found: ${X.issueKey}`),Promise.resolve(1);if(!J.plan?.approved)return m("Approve a plan before claiming this mission."),Promise.resolve(1);let Y=UQ(U.cwd),W=uB(U.cwd),_=t(Z,"agent")??process.env.USER??"unknown",G=n$(U,{...J,branch:Y,sourceSha:W,claim:{agent:_,startedAt:new Date().toISOString(),branch:Y,sourceSha:W}});if(g(Z))h({ok:!0,mission:G});else f(`Mission claimed: ${G.issueKey}`,{title:"Claim",fields:[{label:"Agent",value:_},{label:"Next",value:G.nextAction}]});return Promise.resolve(0)}function OM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return Promise.resolve(X.code);let U=t(Z,"type");if(!IA(U))return j$("Missing or invalid report type.",`sumr mission report <issueKey> --type <type>
|
|
312
|
+
Allowed: ${IU.join(", ")}`),Promise.resolve(1);let J=a(),Y=GQ(X.issueKey),W=w1(J,X.issueKey),_=AM(U),G=q2(W.missionDir,_);tU(G,{recursive:!0});let z=q2(G,HQ(Y,U));eU(z,SA(U,Y),"utf8");let H=n$(J,{...Y,reports:{...Y.reports,[U]:z}});if(g(Z))h({ok:!0,mission:H,reportPath:z});else f(`${nU(U)} report written`,{title:"Report",fields:[{label:"Path",value:z},{label:"Next",value:H.nextAction}]});return Promise.resolve(0)}function KM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return Promise.resolve(X.code);let U=t(Z,"reason");if(!U)return j$("Missing blocker reason.","sumr mission block <issueKey> --reason <text>"),Promise.resolve(1);let J=a(),Y=GQ(X.issueKey),W=n$(J,{...Y,blocker:{reason:U,blockedAt:new Date().toISOString()}});if(g(Z))h({ok:!0,mission:W});else _0(`Mission blocked: ${W.issueKey}`,{title:"Blocker",fields:[{label:"Reason",value:U},{label:"Next",value:W.nextAction}]});return Promise.resolve(0)}function qM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return Promise.resolve(X.code);let U=a(),J=e1(U,X.issueKey);if(!J)return m(`Mission not found: ${X.issueKey}`),Promise.resolve(1);let Y=n$(U,{...J,blocker:void 0});if(g(Z))h({ok:!0,mission:Y});else f(`Mission unblocked: ${Y.issueKey}`,{title:"Mission",fields:[{label:"Next",value:Y.nextAction}]});return Promise.resolve(0)}function BM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return Promise.resolve(X.code);let U=a(),J=e1(U,X.issueKey);if(!J)return m(`Mission not found: ${X.issueKey}`),Promise.resolve(1);try{let Y=OA(U,J,{force:y$(Z,"force")});if(g(Z))h({ok:!0,mission:Y});else f(`Mission closed: ${Y.issueKey}`);return Promise.resolve(0)}catch(Y){return m(Y instanceof Error?Y.message:String(Y)),Promise.resolve(1)}}function LM($){let{options:Q}=_$($),Z=Number(t(Q,"older-than")??30),X=y$(Q,"dry-run"),U=a();F0(U);let J=KA(U,{olderThanDays:Number.isFinite(Z)?Z:30,dryRun:X});if(g(Q))h({ok:!0,dryRun:X,...J});else{let Y=X?J.eligible.length:J.removed.length,W=X?J.eligible:J.removed;if(f(`${X?"Eligible":"Removed"} closed mission cache directories: ${Y}`),W.length>0)d$(W,X?"Eligible":"Removed")}return Promise.resolve(0)}function AM($){return $===vB.Handoff?"handoffs":q2("reports",$)}async function CM($){let{positionals:Q,options:Z}=_$($),X=P1($,Z,Q[0]);if(!X.ok)return X.code;let U=a();if(U.config.git?.prMode===xB.Disabled)return m("PR assist is disabled for this repo by mission.git.prMode."),1;let J=e1(U,X.issueKey);if(!J)return m(`Mission not found: ${X.issueKey}`),1;let Y=SM(Z),W=FM(U,Z),_=w1(U,X.issueKey),G=jU(_.missionDir,"prs");MM(G,{recursive:!0});let z=jU(G,HQ(J,"pr")),H=NM(U,J,W);TM(z,H,"utf8");let V=n$(U,{...J,pr:{...J.pr,latestPath:z,mode:IM(Y),updatedAt:new Date().toISOString()}});if(Y===k$.Preview)return DM(Z,V,z,H,W),0;let O=await wM(U,V,z,W,Y);if(!O.ok)return O.code;return V=n$(U,{...V,pr:{...V.pr,url:O.url,updatedAt:new Date().toISOString()}}),RM(Z,V,z,O.url),0}function SM($){if(y$($,k$.Create))return k$.Create;if(y$($,k$.CreateDraft))return k$.CreateDraft;return k$.Preview}function FM($,Q){let Z=t(Q,"base")??t(Q,"base-branch");if(Z)return Z;if($.config.git?.baseBranch)return $.config.git.baseBranch;let X=dB($.cwd);if(!X)throw Error("Could not resolve a PR base branch. Pass --base <branch> or configure mission.git.baseBranch.");return X}function IM($){if($===k$.CreateDraft)return s9.Draft;if($===k$.Create)return s9.Ready;return s9.Preview}function DM($,Q,Z,X,U){if(g($)){h({ok:!0,mission:Q,prPath:Z,body:X});return}f("PR preview written",{title:"Pull Request",fields:[{label:"Path",value:Z},{label:"Base branch",value:U},{label:"Next",value:Q.nextAction}]})}function RM($,Q,Z,X){if(g($)){h({ok:!0,mission:Q,prPath:Z,url:X});return}f("Pull request created",{title:"Pull Request",fields:[{label:"URL",value:X},{label:"Preview",value:Z}]})}function NM($,Q,Z){let X=FA($.cwd),U=Q.issueKey.match(/^(?:GH|GL)-(\d+)$/)?.[1],J=U?`Refs #${U}`:`Refs ${Q.issueKey}`;return`## Summary
|
|
310
313
|
- ${Q.title}
|
|
311
314
|
- TODO: summarize the user-facing change.
|
|
312
315
|
- TODO: summarize the main implementation change.
|
|
313
|
-
- ${
|
|
316
|
+
- ${J}
|
|
314
317
|
|
|
315
318
|
## Verification
|
|
316
319
|
- TODO: add commands run and results.
|
|
@@ -336,13 +339,13 @@ ${X?`
|
|
|
336
339
|
|
|
337
340
|
${X.trim()}
|
|
338
341
|
`:""}
|
|
339
|
-
`}async function
|
|
340
|
-
${
|
|
341
|
-
${z.stderr.trim()}`),{ok:!1,code:1};return{ok:!0,url:z.stdout.trim()}}function OM($,Q,Z,X,U){let W=["pr","create","--base",X,"--title",rU(Q),"--body-file",Z];if(U===cU.CreateDraft)W.push("--draft");return G7("gh",W,{cwd:$.cwd,stdio:"pipe",encoding:"utf8"})}function KM($,Q,Z,X,U,W){let J=["mr","create","--base",X,"--source-branch",U,"--title",rU(Q),"--description",ZM(Z,"utf8")];if(W===cU.CreateDraft)J.push("--draft");return G7("glab",J,{cwd:$.cwd,stdio:"pipe",encoding:"utf8"})}async function qM($,Q,Z){if(!u0())return m(`External write blocked. Re-run interactively to approve ${$} from ${Q} to ${Z}.`),!1;return await a$({message:`Push ${Q} and ${$===k$.CreateDraft?"create a draft PR":"create a PR"} into ${Z}?`,options:[{value:w8.No,label:"No",hint:"Keep the PR preview only"},{value:w8.Yes,label:"Yes",hint:"Push branch and create PR"}],initialValue:w8.No})===w8.Yes}function rU($){let Q=`${$.issueKey}: ${$.title}`.replace(/\s+/g," ").trim();return Q.length<=70?Q:`${Q.slice(0,67).trimEnd()}...`}function LM($){return $.claim?.branch??$.branch}function BM($){return UM.some((Q)=>Q===$)}async function AM($){let{positionals:Q,options:Z}=G$($),X=o(),U=hU(Z),W=await MM($,Z,X,Q[0],U);if(!W.ok)return W.code;let J=await jM(Z,W.issueKey,U);if(!J.ok)return J.code;let G=fU(X,W.issueKey,J.title);if(g(Z))h({ok:!0,mission:G});else P(`Mission ready: ${G.issueKey}`,{title:"Mission",fields:[{label:"Title",value:G.title},{label:"Storage",value:w1(X,G.issueKey).missionDir},{label:"Next",value:G.nextAction}]});return 0}async function MM($,Q,Z,X,U){let W=EM(Q,Z,X);if(W)return W;if(!X&&U){let G=await TM(Z);if(!G)return{ok:!1,code:0};return{ok:!0,issueKey:G}}if(!X)return L$("Missing issue key.",`sumr mission ${$.argv[0]??"<command>"} <issueKey>`),{ok:!1,code:1};let J=y8({issueKey:X,prefixes:Z.config.issuePrefixes,allowCustomKey:f$(Q,"allow-custom-key")});if(!J.ok)return m(J.message),{ok:!1,code:1};return{ok:!0,issueKey:J.issueKey}}function EM($,Q,Z){let X=s($,"tracker")??s($,"provider"),U=s($,"issue")??s($,"key");if(!X&&!U)return;if(Z)return L$("Use either a positional issue key or tracker options, not both.","sumr mission start --tracker <tracker> --issue <id> --title <title>"),{ok:!1,code:1};if(!U)return L$("Missing tracker issue parameters.","sumr mission start --tracker <tracker> --issue <id> --title <title>"),{ok:!1,code:1};let W=X?pU(X):Q.config.tracker?.provider;if(!W)return L$(X?`Unsupported tracker: ${X}`:"Missing tracker issue source.","Set one with `sumr mission init --tracker <tracker>` or pass --tracker explicitly."),{ok:!1,code:1};let J=a9(W,U);if(!J.ok)return m(J.message),{ok:!1,code:1};let G=y8({issueKey:J.issueKey,prefixes:Q.config.issuePrefixes,allowCustomKey:!0});if(!G.ok)return m(G.message),{ok:!1,code:1};return{ok:!0,issueKey:G.issueKey}}async function TM($){let Q=await a$({message:"Where is this mission tracked?",options:m8.map((W)=>({value:W.value,label:W.label,hint:W.hint})),initialValue:$.config.tracker?.provider??p.Github});if(!Q)return;let Z=lU(Q),X=await _0({message:Z.inputLabel,placeholder:Z.placeholder,validate:(W)=>{let J=a9(Q,W??"");if(!J.ok)return J.message;let G=y8({issueKey:J.issueKey,prefixes:$.config.issuePrefixes,allowCustomKey:!0});return G.ok?void 0:G.message}});if(!X)return;let U=a9(Q,X);return U.ok?U.issueKey:void 0}async function jM($,Q,Z){let X=s($,"title")??s($,"name");if(X)return{ok:!0,title:X};if(!Z)return L$("Missing title.","sumr mission start <issueKey> --title <title>"),{ok:!1,code:1};let W=(await _0({message:"Mission title",placeholder:`Implement ${Q}`,validate:(J)=>{if(!J?.trim())return"Enter a mission title.";return}}))?.trim();return W?{ok:!0,title:W}:{ok:!1,code:0}}var _2,cq,M0,nq,Y2,iq,V$,rq,I1,oq,E0,aq,S$,sq,U1,tq,b8,eq,n9,$L,k8,QL,ZL,qU,XL,UL,WL,s9,JL,LU,GL,_L,T0,YL,zL,BU,HL,AU,VL,OL,KL,MU,qL,LL,T,P$,C$,BL,A,d,AL,EU,p,r,ML,j0,c9,FL,TU,IL,CU,FU,kL,IU,PL,fL,yL,vL,xL,gL,hL,uL,dL,oL,NU,z2,WB,Z7=30,RB=".sumr",NB=".sumr-cache",wB,bB,uB,G2,J7,m8,jA,SA,VU,k$,cU,w8,Tb,N1,UM,b,SM;var aU=w2(()=>{D();D();D();D();D();D();D();D();_2={Auto:"auto",Ask:"ask",Human:"human",Manual:"manual"},cq=[_2.Auto,_2.Ask,_2.Human,_2.Manual],M0={Pending:"pending",Ready:"ready",Done:"done",Skipped:"skipped",Blocked:"blocked"},nq=[M0.Pending,M0.Ready,M0.Done,M0.Skipped,M0.Blocked],Y2={Basic:"basic",PlanningOnly:"planning-only",StandardDelivery:"standard-delivery",FullDelivery:"full-delivery"},iq=[Y2.Basic,Y2.PlanningOnly,Y2.StandardDelivery,Y2.FullDelivery],V$={IssueSync:"issue.sync",ContextResearch:"context.research",PlanCreate:"plan.create",PlanApprove:"plan.approve",BranchCheck:"branch.check",WorkClaim:"work.claim",ImplementationReport:"implementation.report",ReviewReport:"review.report",ValidationReport:"validation.report",QualityGate:"quality.gate",PrPrepare:"pr.prepare",PrCreate:"pr.create",MissionClose:"mission.close"},rq=[V$.IssueSync,V$.ContextResearch,V$.PlanCreate,V$.PlanApprove,V$.BranchCheck,V$.WorkClaim,V$.ImplementationReport,V$.ReviewReport,V$.ValidationReport,V$.QualityGate,V$.PrPrepare,V$.PrCreate,V$.MissionClose],I1={Planning:"planning",Planned:"planned",InProgress:"in_progress",Review:"review",Validated:"validated",Blocked:"blocked",Closed:"closed"},oq=[I1.Planning,I1.Planned,I1.InProgress,I1.Review,I1.Validated,I1.Blocked,I1.Closed],E0={Implementation:"implementation",Review:"review",Validation:"validation",Quality:"quality",Handoff:"handoff"},aq=[E0.Implementation,E0.Review,E0.Validation,E0.Quality,E0.Handoff],S$={Github:"github",Gitlab:"gitlab",Jira:"jira",Linear:"linear",AzureBoards:"azure-boards",Shortcut:"shortcut",Clickup:"clickup",Asana:"asana",Trello:"trello",Notion:"notion",Custom:"custom"},sq=[S$.Github,S$.Gitlab,S$.Jira,S$.Linear,S$.AzureBoards,S$.Shortcut,S$.Clickup,S$.Asana,S$.Trello,S$.Notion,S$.Custom],U1={Github:"github",Gitlab:"gitlab",Bitbucket:"bitbucket",AzureDevops:"azure-devops",Gitea:"gitea",Codeberg:"codeberg",GenericGit:"generic-git",None:"none"},tq=[U1.Github,U1.Gitlab,U1.Bitbucket,U1.AzureDevops,U1.Gitea,U1.Codeberg,U1.GenericGit,U1.None],b8={Preview:"preview",Ask:"ask",Disabled:"disabled"},eq=[b8.Preview,b8.Ask,b8.Disabled],n9={Repo:"repo",Global:"global"},$L=[n9.Repo,n9.Global],k8={Preview:"preview",Draft:"draft",Ready:"ready"},QL=[k8.Preview,k8.Draft,k8.Ready],ZL=_2,qU=cq,XL=M0,UL=nq,WL=Y2,s9=iq,JL=V$,LU=rq,GL=I1,_L=oq,T0=E0,YL=aq,zL=S$,BU=sq,HL=U1,AU=tq,VL=b8,OL=eq,KL=n9,MU=$L,qL=k8,LL=QL,T=ZL,P$=XL,C$=WL,BL=s9,A=JL,d=GL,AL=T0,EU=YL,p=zL,r=HL,ML=VL,j0=KL,c9=qL;FL=["ISSUE","GH","GL"],TU=/^[A-Z][A-Z0-9]*$/,IL=/^[A-Za-z0-9][A-Za-z0-9._-]{1,80}$/;CU=B.object({provider:B.enum(BU).optional()}).strict(),FU=B.object({provider:B.enum(AU).optional(),baseBranch:B.string().min(1).optional(),prMode:B.enum(OL).optional()}).strict(),kL=B.object({uses:B.string().min(1),enabled:B.boolean().optional(),advance:B.string().min(1).optional()}).strict(),IU=B.object({preset:B.string().min(1).optional(),steps:B.array(kL).optional()}).strict(),PL=B.object({repoId:B.string().min(1).optional(),tracker:CU.optional(),git:FU.optional(),flow:IU.optional(),issuePrefixes:B.array(B.string()),retentionDays:B.number().int().positive()}).strict(),fL=B.object({latestPath:B.string().min(1),approved:B.boolean(),approvedAt:B.string().optional()}).strict(),yL=B.object({agent:B.string().min(1),startedAt:B.string().min(1),branch:B.string().optional(),sourceSha:B.string().optional()}).strict(),vL=B.object({reason:B.string().min(1),blockedAt:B.string().min(1)}).strict(),xL=B.object({implementation:B.string().optional(),review:B.string().optional(),validation:B.string().optional(),quality:B.string().optional(),handoff:B.string().optional()}).strict(),gL=B.object({latestPath:B.string().optional(),url:B.string().optional(),mode:B.enum(LL).optional(),createdAt:B.string().optional(),updatedAt:B.string().optional()}).strict(),hL=B.object({preset:B.enum(s9),hash:B.string().min(1),steps:B.array(B.object({uses:B.enum(LU),enabled:B.boolean(),advance:B.enum(qU),status:B.enum(UL),artifactPath:B.string().optional(),updatedAt:B.string().optional()}).strict())}).strict(),uL=B.object({version:B.literal(1),repoId:B.string().min(1),repoLabel:B.string().min(1),storageScope:B.enum(MU),createdAt:B.string().min(1),updatedAt:B.string().min(1),tracker:CU.optional(),git:FU.optional(),flow:IU.optional(),issuePrefixes:B.array(B.string())}).strict(),dL=B.object({version:B.literal(1),missionId:B.string().min(1),repoId:B.string().min(1),repoLabel:B.string().min(1),issueKey:B.string().min(1),issuePathKey:B.string().min(1),title:B.string().min(1),status:B.enum(_L),storageScope:B.enum(MU),createdAt:B.string().min(1),updatedAt:B.string().min(1),branch:B.string().optional(),sourceSha:B.string().optional(),plan:fL.optional(),claim:yL.optional(),reports:xL,pr:gL.optional(),flow:hL.optional(),blocker:vL.optional(),nextAction:B.string().min(1)}).strict();oL=[{id:A.IssueSync,label:"Sync issue context",nextAction:"Sync or confirm issue context.",externalWrite:!1},{id:A.ContextResearch,label:"Research context",nextAction:"Research code and tracker context.",externalWrite:!1},{id:A.PlanCreate,label:"Create plan",nextAction:"Create and register a Mission plan.",externalWrite:!1},{id:A.PlanApprove,label:"Approve plan",nextAction:"Approve the latest plan.",externalWrite:!1},{id:A.BranchCheck,label:"Check branch",nextAction:"Confirm the implementation branch.",externalWrite:!1},{id:A.WorkClaim,label:"Claim work",nextAction:"Claim the mission for implementation.",externalWrite:!1},{id:A.ImplementationReport,label:"Implementation report",nextAction:"Create an implementation report.",externalWrite:!1},{id:A.ReviewReport,label:"Review report",nextAction:"Create a review report.",externalWrite:!1},{id:A.ValidationReport,label:"Validation report",nextAction:"Create a validation report.",externalWrite:!1},{id:A.QualityGate,label:"Quality gate",nextAction:"Create a quality gate report.",externalWrite:!1},{id:A.PrPrepare,label:"Prepare PR",nextAction:"Prepare a PR preview.",externalWrite:!1},{id:A.PrCreate,label:"Create PR",nextAction:"Ask for approval to create the PR.",externalWrite:!0},{id:A.MissionClose,label:"Close mission",nextAction:"Close the mission.",externalWrite:!1}],NU={[C$.Basic]:[{uses:A.PlanCreate,advance:T.Auto},{uses:A.PlanApprove,advance:T.Human},{uses:A.WorkClaim,advance:T.Auto},{uses:A.ImplementationReport,advance:T.Manual},{uses:A.ReviewReport,advance:T.Manual},{uses:A.ValidationReport,advance:T.Manual},{uses:A.MissionClose,advance:T.Manual}],[C$.PlanningOnly]:[{uses:A.IssueSync,advance:T.Auto},{uses:A.ContextResearch,advance:T.Auto},{uses:A.PlanCreate,advance:T.Auto},{uses:A.PlanApprove,advance:T.Human}],[C$.StandardDelivery]:[{uses:A.IssueSync,advance:T.Auto},{uses:A.ContextResearch,enabled:!1,advance:T.Auto},{uses:A.PlanCreate,advance:T.Auto},{uses:A.PlanApprove,advance:T.Human},{uses:A.BranchCheck,advance:T.Ask},{uses:A.WorkClaim,advance:T.Auto},{uses:A.ImplementationReport,advance:T.Manual},{uses:A.ReviewReport,advance:T.Manual},{uses:A.ValidationReport,advance:T.Manual},{uses:A.QualityGate,advance:T.Manual},{uses:A.PrPrepare,advance:T.Ask},{uses:A.PrCreate,advance:T.Human}],[C$.FullDelivery]:[{uses:A.IssueSync,advance:T.Auto},{uses:A.ContextResearch,advance:T.Auto},{uses:A.PlanCreate,advance:T.Auto},{uses:A.PlanApprove,advance:T.Human},{uses:A.BranchCheck,advance:T.Ask},{uses:A.WorkClaim,advance:T.Auto},{uses:A.ImplementationReport,advance:T.Manual},{uses:A.ReviewReport,advance:T.Manual},{uses:A.ValidationReport,advance:T.Manual},{uses:A.QualityGate,advance:T.Manual},{uses:A.PrPrepare,advance:T.Ask},{uses:A.PrCreate,advance:T.Human},{uses:A.MissionClose,advance:T.Manual}]},z2=[...BL];WB={[A.IssueSync]:($)=>$.issueKey&&$.title,[A.ContextResearch]:($)=>$.reports.handoff,[A.PlanCreate]:($)=>$.plan,[A.PlanApprove]:($)=>$.plan?.approved,[A.BranchCheck]:($)=>$.branch||$.claim?.branch,[A.WorkClaim]:($)=>$.claim,[A.ImplementationReport]:($)=>$.reports.implementation,[A.ReviewReport]:($)=>$.reports.review,[A.ValidationReport]:($)=>$.reports.validation,[A.QualityGate]:($)=>$.reports.quality,[A.PrPrepare]:($)=>$.pr?.latestPath,[A.PrCreate]:($)=>$.pr?.url,[A.MissionClose]:($)=>$.status===d.Closed};wB=["cache","mission"],bB=["mission"];uB=new Set(["agent","from","flow","git-provider","issue","key","name","note","older-than","prefix","provider","reason","repo","title","tracker","type","base","base-branch"]);G2={SHOW:"show",LIST:"list",VALIDATE:"validate",EXPORT:"export",USE:"use"};J7=[{value:r.Github,label:"GitHub",hint:"Create pull requests with gh"},{value:r.Gitlab,label:"GitLab",hint:"Create merge requests with glab later"},{value:r.Bitbucket,label:"Bitbucket",hint:"Recognized; manual PR flow in V1"},{value:r.AzureDevops,label:"Azure DevOps",hint:"Recognized; manual PR flow in V1"},{value:r.Gitea,label:"Gitea",hint:"Recognized; manual PR flow in V1"},{value:r.Codeberg,label:"Codeberg",hint:"Recognized; manual PR flow in V1"},{value:r.GenericGit,label:"Generic Git",hint:"No hosted PR automation"},{value:r.None,label:"None",hint:"Disable PR assistance"}];m8=[{value:p.Github,label:"GitHub",hint:"#123 becomes GH-123",inputLabel:"GitHub issue number",placeholder:"123"},{value:p.Gitlab,label:"GitLab",hint:"#123 becomes GL-123",inputLabel:"GitLab issue IID",placeholder:"123"},{value:p.Jira,label:"Jira",hint:"PROJECT-123",inputLabel:"Jira ticket key",placeholder:"PROJECT-123"},{value:p.Linear,label:"Linear",hint:"TEAM-123",inputLabel:"Linear issue identifier",placeholder:"TEAM-123"},{value:p.AzureBoards,label:"Azure Boards",hint:"AB#123 or work item 123",inputLabel:"Azure Boards work item",placeholder:"AB#123"},{value:p.Shortcut,label:"Shortcut",hint:"Story ID or task URL",inputLabel:"Shortcut story ID",placeholder:"12345"},{value:p.Clickup,label:"ClickUp",hint:"Task ID or task URL",inputLabel:"ClickUp task ID",placeholder:"abc123"},{value:p.Asana,label:"Asana",hint:"Task ID or task URL",inputLabel:"Asana task ID",placeholder:"1200000000000000"},{value:p.Trello,label:"Trello",hint:"Card ID or card URL",inputLabel:"Trello card ID",placeholder:"card-slug-or-id"},{value:p.Notion,label:"Notion",hint:"Task/page ID or title",inputLabel:"Notion task ID or title",placeholder:"release checklist"},{value:p.Custom,label:"Custom ID",hint:"Use any local mission label",inputLabel:"Custom mission ID",placeholder:"checkout race condition"}],jA=/^(?:#|GH-|GL-)?([0-9]+)$/i,SA=/^[A-Z][A-Z0-9]*-[0-9]+$/;VU={Skip:"skip"},k$={Create:"create",CreateDraft:"create-draft",Preview:"preview"},cU={Create:k$.Create,CreateDraft:k$.CreateDraft},w8={Yes:"yes",No:"no"},Tb={Plan:"plan",Implementation:T0.Implementation,Review:T0.Review,Validation:T0.Validation,Quality:T0.Quality,Handoff:T0.Handoff,Pr:"pr"},N1=Symbol("init-option-error");UM=["main","dev","uat","prod"];b={init:{name:"mission init",description:"Initialize Mission state for this repository or global workspace",usage:["sumr mission init","sumr mission init --tracker github --git-provider github --flow standard-delivery","sumr mission init --tracker jira --prefix SMR --prefix OPS --flow planning-only"],options:[{flag:"--tracker <type>",description:"Work source: github, gitlab, jira, linear, azure-boards, shortcut, clickup, asana, trello, notion, custom"},{flag:"--provider <type>",description:"Alias for --tracker"},{flag:"--git-provider <type>",description:"Git/PR provider: github, gitlab, bitbucket, azure-devops, gitea, codeberg, generic-git, none"},{flag:"--flow <preset>",description:"Mission flow: basic, planning-only, standard-delivery, full-delivery"},{flag:"--prefix <value>",description:"Accepted issue key prefix; repeatable"},{flag:"--yes",description:"Use defaults and skip interactive prefix setup"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},start:{name:"mission start",description:"Start or resume a mission",usage:["sumr mission start",'sumr mission start SMR-123 --title "Improve onboarding"','sumr mission start --tracker github --issue 123 --name "Fix checkout flow"'],options:[{flag:"--title <title>",description:"Mission title"},{flag:"--name <title>",description:"Alias for --title, useful for API payloads"},{flag:"--tracker <type>",description:"Tracker: github, gitlab, jira, linear, azure-boards, shortcut, clickup, asana, trello, notion, custom"},{flag:"--provider <type>",description:"Alias for --tracker"},{flag:"--issue <id>",description:"Raw tracker issue number, key, or custom ID"},{flag:"--key <id>",description:"Alias for --issue"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr mission start",'sumr mission start GH-123 --title "Fix checkout flow"','sumr mission start --tracker jira --key SMR-123 --name "Fix checkout flow" --json']},status:{name:"mission status",description:"Show Mission status and next action",usage:["sumr mission status","sumr mission status SMR-123"],options:[{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},next:{name:"mission next",description:"Show the next Mission action",usage:["sumr mission next","sumr mission next --all"],options:[{flag:"--all",description:"Include all repo namespaces in this storage root"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},list:{name:"mission list",description:"List missions",usage:["sumr mission list","sumr mission list --all"],options:[{flag:"--all",description:"Include all repo namespaces in this storage root"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},plan:{name:"mission plan",description:"Create or register a mission plan",usage:["sumr mission plan SMR-123","sumr mission plan SMR-123 --from plan.md","sumr mission plan SMR-123 --from plan.md --approve"],options:[{flag:"--from <file>",description:"Use an existing plan file as source"},{flag:"--approve",description:"Mark the plan approved in the same command"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},approve:{name:"mission approve",description:"Approve the current mission plan for implementation",usage:["sumr mission approve SMR-123"],options:[{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},claim:{name:"mission claim",description:"Claim a mission for implementation",usage:["sumr mission claim SMR-123 --agent codex"],options:[{flag:"--agent <name>",description:"Agent or session name"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},report:{name:"mission report",description:"Create a mission report",usage:["sumr mission report SMR-123 --type validation"],options:[{flag:"--type <kind>",description:"Report type: implementation, review, validation, quality, handoff"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},block:{name:"mission block",description:"Mark a mission as blocked",usage:['sumr mission block SMR-123 --reason "Waiting for design"'],options:[{flag:"--reason <text>",description:"Blocker reason"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},unblock:{name:"mission unblock",description:"Clear a mission blocker",usage:["sumr mission unblock SMR-123"],options:[{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},close:{name:"mission close",description:"Close a completed mission",usage:["sumr mission close SMR-123","sumr mission close SMR-123 --force"],options:[{flag:"--force",description:"Close without a validation report"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},clean:{name:"mission clean",description:"Remove expired closed mission cache",usage:["sumr mission clean --dry-run","sumr mission clean --older-than 30"],options:[{flag:"--older-than <days>",description:"Retention threshold for closed missions"},{flag:"--dry-run",description:"Show eligible cache without deleting"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},flow:{name:"mission flow",description:"Inspect and configure Mission flow presets",usage:["sumr mission flow list","sumr mission flow show","sumr mission flow use standard-delivery","sumr mission flow validate","sumr mission flow export --json"],options:[{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},pr:{name:"mission pr",description:"Prepare or create a pull request from Mission evidence",usage:["sumr mission pr SMR-123 --preview","sumr mission pr SMR-123 --create-draft","sumr mission pr SMR-123 --create"],options:[{flag:"--preview",description:"Write a PR preview artifact without external writes"},{flag:"--create-draft",description:"Ask approval, push branch, and create draft PR"},{flag:"--create",description:"Ask approval, push branch, and create PR"},{flag:"--base <branch>",description:"Target branch override"},{flag:"--base-branch <branch>",description:"Alias for --base"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]}},SM=K1({name:"mission",description:"Track AI-assisted work state and next actions",group:"modules",visibility:"public",commands:[E({name:"init",description:b.init.description,group:"modules",visibility:"public",help:b.init,execute:IA}),E({name:"start",description:b.start.description,group:"modules",visibility:"public",help:b.start,execute:AM}),E({name:"status",description:b.status.description,group:"modules",visibility:"public",help:b.status,execute:lA}),E({name:"next",description:b.next.description,group:"modules",visibility:"public",help:b.next,execute:cA}),E({name:"list",description:b.list.description,group:"modules",visibility:"public",help:b.list,execute:pA}),E({name:"plan",description:b.plan.description,group:"modules",visibility:"public",help:b.plan,execute:nA}),E({name:"approve",description:b.approve.description,group:"modules",visibility:"public",help:b.approve,execute:iA}),E({name:"claim",description:b.claim.description,group:"modules",visibility:"public",help:b.claim,execute:rA}),E({name:"report",description:b.report.description,group:"modules",visibility:"public",help:b.report,execute:oA}),E({name:"block",description:b.block.description,group:"modules",visibility:"public",help:b.block,execute:aA}),E({name:"unblock",description:b.unblock.description,group:"modules",visibility:"public",help:b.unblock,execute:sA}),E({name:"close",description:b.close.description,group:"modules",visibility:"public",help:b.close,execute:tA}),E({name:"clean",description:b.clean.description,group:"modules",visibility:"public",help:b.clean,execute:eA}),E({name:"flow",description:b.flow.description,group:"modules",visibility:"public",help:b.flow,execute:zA}),E({name:"pr",description:b.pr.description,group:"modules",visibility:"public",help:b.pr,execute:WM})]})});var EG={};N2(EG,{validatePlaybookSlice:()=>uW,playbookModule:()=>TR,PlaybookSliceSchema:()=>hW});import{z as I$}from"zod";import{existsSync as dW,mkdirSync as FM,readdirSync as IM,writeFileSync as DM}from"fs";import{join as E7,resolve as mW}from"path";import{existsSync as f7,readFileSync as RM}from"fs";import{join as NM}from"path";import{stdout as sE}from"process";import{log as UT}from"@clack/prompts";import{existsSync as h7,mkdirSync as WT,readdirSync as JT,readFileSync as GT,renameSync as _T,rmSync as j7,statSync as YT,writeFileSync as zT}from"fs";import{dirname as HT,join as u7}from"path";import{existsSync as GJ}from"fs";import{resolve as C7}from"path";import{existsSync as pT,readdirSync as cT,readFileSync as nT,statSync as iT}from"fs";import{basename as ZW,dirname as Y6,join as rT,resolve as oT}from"path";import{existsSync as c7,readdirSync as n7,readFileSync as Fj,statSync as Ij}from"fs";import{homedir as Dj}from"os";import{basename as I7,dirname as b0,join as R$,resolve as y1}from"path";import{fileURLToPath as VJ}from"url";import{existsSync as bj,readFileSync as kj,realpathSync as WW,statSync as Pj}from"fs";import{isAbsolute as V7,join as fj,relative as JW,resolve as yj}from"path";import{existsSync as dj,realpathSync as mj,statSync as lj}from"fs";import{existsSync as PS}from"fs";import{relative as o7,resolve as a7,sep as BJ}from"path";import{sep as XC}from"path";import{existsSync as EJ,readFileSync as TJ,rmSync as OW}from"fs";import{join as S2,relative as jJ,resolve as N7,sep as t7}from"path";import{existsSync as iC,readFileSync as rC}from"fs";import{join as oC}from"path";import{existsSync as kJ,readFileSync as PJ,writeFileSync as fJ}from"fs";import{join as yJ}from"path";import{existsSync as pJ,mkdirSync as LF,readFileSync as BF,writeFileSync as AF}from"fs";import{join as cJ}from"path";import{existsSync as aJ,readdirSync as DF,rmSync as b7}from"fs";import{basename as RF,join as J1}from"path";import{chmodSync as fF,existsSync as O6,readdirSync as K6,readFileSync as q6,rmSync as UQ}from"fs";import{basename as WQ,extname as L6,join as B$}from"path";import{basename as vF,join as NW}from"path";import{existsSync as dF,readFileSync as mF}from"fs";import{join as lF}from"path";import{chmodSync as qI,existsSync as LI,readFileSync as BI}from"fs";import{join as I2}from"path";import{existsSync as AI,readFileSync as MI}from"fs";import{join as EI}from"path";import{existsSync as TI,readFileSync as jI}from"fs";import{basename as SI,join as CI}from"path";import{join as vW}from"path";import{existsSync as xD}from"fs";import{resolve as AG}from"path";import{resolve as QR}from"path";function uW($){let Q=hW.safeParse($);if(Q.success)return{ok:!0,value:Q.data};return{ok:!1,issues:Q.error.issues.map((X)=>{return`${X.path.length>0?X.path.join("."):"(root)"}: ${X.message}`})}}function L2($){return $.playbook.agentsMd??={},$.playbook.agentsMd}function v1($){return $.mission??={},$.mission}function lW($){let Q=v1($);return Q.git??={},Q.git}function uM($){let Q=v1($);return Q.tracker??={},Q.tracker}function r8($){let Q=v1($);return Q.flow??={},Q.flow}function dM($){let Q=r8($);return Q.steps??=[],Q.steps}function mM($){let Q=v1($);return Q.issuePrefixes??=[],Q.issuePrefixes}function lM($){return wM.includes($)}function pM($){return bM.includes($)}function cM($){return kM.includes($)}function nM($){return PM.includes($)}function iM($){return fM.includes($)}function tM($){let Q=[];Q.push("# SUMR per-repo configuration"),Q.push("# Run `sumr playbook config` to update this file."),Q.push(`version: ${$.version}`),Q.push(""),Q.push(...pW($));let Z=$.kontract?.input?.trim(),X=$.kontract?.output?.trim();if(Z||X){if(Q.push(""),Q.push("# Kontract"),Q.push("kontract:"),Z)Q.push(` input: ${Z}`);if(X)Q.push(` output: ${X}`)}return Q.push(""),Q.join(`
|
|
342
|
-
`)}function
|
|
343
|
-
`),X={topSection:
|
|
342
|
+
`}async function wM($,Q,Z,X,U){let J=$.config.git?.provider??rU(JQ($.cwd));if(J!==o.Github&&J!==o.Gitlab)return m(`PR creation is only implemented for GitHub and GitLab in V1. Current provider: ${iU(J)}.`),{ok:!1,code:1};let Y=UQ($.cwd);if(!Y||yM(Y))return m(`Refusing to create a PR from protected or empty branch: ${Y??"(none)"}`),{ok:!1,code:1};let W=fM(Q);if(W&&Y!==W)return m(`Refusing to create a PR from branch ${Y} because mission ${Q.issueKey} is recorded on branch ${W}. Switch to ${W}, or intentionally reclaim the mission on ${Y} before creating the PR.`),{ok:!1,code:1};if(!await kM(U,Y,X))return{ok:!1,code:1};let G=OQ("git",["push","-u","origin",Y],{cwd:$.cwd,stdio:"pipe",encoding:"utf8"});if(G.status!==0)return m(`Could not push branch before PR creation.
|
|
343
|
+
${G.stderr.trim()}`),{ok:!1,code:1};let z=J===o.Github?PM($,Q,Z,X,U):bM($,Q,Z,X,Y,U);if(z.status!==0)return m(`Could not create pull request.
|
|
344
|
+
${z.stderr.trim()}`),{ok:!1,code:1};return{ok:!0,url:z.stdout.trim()}}function PM($,Q,Z,X,U){let J=["pr","create","--base",X,"--title",$J(Q),"--body-file",Z];if(U===sU.CreateDraft)J.push("--draft");return OQ("gh",J,{cwd:$.cwd,stdio:"pipe",encoding:"utf8"})}function bM($,Q,Z,X,U,J){let Y=["mr","create","--base",X,"--source-branch",U,"--title",$J(Q),"--description",jM(Z,"utf8")];if(J===sU.CreateDraft)Y.push("--draft");return OQ("glab",Y,{cwd:$.cwd,stdio:"pipe",encoding:"utf8"})}async function kM($,Q,Z){if(!l0())return m(`External write blocked. Re-run interactively to approve ${$} from ${Q} to ${Z}.`),!1;return await a$({message:`Push ${Q} and ${$===k$.CreateDraft?"create a draft PR":"create a PR"} into ${Z}?`,options:[{value:v6.No,label:"No",hint:"Keep the PR preview only"},{value:v6.Yes,label:"Yes",hint:"Push branch and create PR"}],initialValue:v6.No})===v6.Yes}function $J($){let Q=`${$.issueKey}: ${$.title}`.replace(/\s+/g," ").trim();return Q.length<=70?Q:`${Q.slice(0,67).trimEnd()}...`}function fM($){return $.claim?.branch??$.branch}function yM($){return EM.some((Q)=>Q===$)}async function vM($){let{positionals:Q,options:Z}=_$($),X=a(),U=cU(Z),J=await xM($,Z,X,Q[0],U);if(!J.ok)return J.code;let Y=await uM(Z,J.issueKey,U);if(!Y.ok)return Y.code;let W=uU(X,J.issueKey,Y.title);if(g(Z))h({ok:!0,mission:W});else f(`Mission ready: ${W.issueKey}`,{title:"Mission",fields:[{label:"Title",value:W.title},{label:"Storage",value:w1(X,W.issueKey).missionDir},{label:"Next",value:W.nextAction}]});return 0}async function xM($,Q,Z,X,U){let J=gM(Q,Z,X);if(J)return J;if(!X&&U){let W=await hM(Z);if(!W)return{ok:!1,code:0};return{ok:!0,issueKey:W}}if(!X)return j$("Missing issue key.",`sumr mission ${$.argv[0]??"<command>"} <issueKey>`),{ok:!1,code:1};let Y=d6({issueKey:X,prefixes:Z.config.issuePrefixes,allowCustomKey:y$(Q,"allow-custom-key")});if(!Y.ok)return m(Y.message),{ok:!1,code:1};return{ok:!0,issueKey:Y.issueKey}}function gM($,Q,Z){let X=t($,"tracker")??t($,"provider"),U=t($,"issue")??t($,"key");if(!X&&!U)return;if(Z)return j$("Use either a positional issue key or tracker options, not both.","sumr mission start --tracker <tracker> --issue <id> --title <title>"),{ok:!1,code:1};if(!U)return j$("Missing tracker issue parameters.","sumr mission start --tracker <tracker> --issue <id> --title <title>"),{ok:!1,code:1};let J=X?aU(X):Q.config.tracker?.provider;if(!J)return j$(X?`Unsupported tracker: ${X}`:"Missing tracker issue source.","Set one with `sumr mission init --tracker <tracker>` or pass --tracker explicitly."),{ok:!1,code:1};let Y=ZQ(J,U);if(!Y.ok)return m(Y.message),{ok:!1,code:1};let W=d6({issueKey:Y.issueKey,prefixes:Q.config.issuePrefixes,allowCustomKey:!0});if(!W.ok)return m(W.message),{ok:!1,code:1};return{ok:!0,issueKey:W.issueKey}}async function hM($){let Q=await a$({message:"Where is this mission tracked?",options:r6.map((J)=>({value:J.value,label:J.label,hint:J.hint})),initialValue:$.config.tracker?.provider??p.Github});if(!Q)return;let Z=oU(Q),X=await G0({message:Z.inputLabel,placeholder:Z.placeholder,validate:(J)=>{let Y=ZQ(Q,J??"");if(!Y.ok)return Y.message;let W=d6({issueKey:Y.issueKey,prefixes:$.config.issuePrefixes,allowCustomKey:!0});return W.ok?void 0:W.message}});if(!X)return;let U=ZQ(Q,X);return U.ok?U.issueKey:void 0}async function uM($,Q,Z){let X=t($,"title")??t($,"name");if(X)return{ok:!0,title:X};if(!Z)return j$("Missing title.","sumr mission start <issueKey> --title <title>"),{ok:!1,code:1};let J=(await G0({message:"Mission title",placeholder:`Implement ${Q}`,validate:(Y)=>{if(!Y?.trim())return"Enter a mission title.";return}}))?.trim();return J?{ok:!0,title:J}:{ok:!1,code:0}}var V2,GB,j0,zB,O2,HB,K$,VB,I1,OB,T0,KB,I$,qB,U1,BB,x6,LB,t9,AB,g6,MB,jB,TU,TB,EB,CB,XQ,SB,EU,FB,IB,E0,DB,RB,CU,NB,SU,wB,PB,bB,FU,kB,fB,C,f$,D$,yB,A,d,vB,IU,p,o,xB,C0,s9,lB,DU,pB,wU,PU,aB,bU,sB,tB,eB,$L,QL,ZL,XL,UL,JL,OL,yU,K2,CL,_Q=30,nL=".sumr",iL=".sumr-cache",rL,oL,UA,H2,VQ,r6,uA,dA,AU,k$,sU,v6,Rb,N1,EM,b,dM;var ZJ=v2(()=>{D();D();D();D();D();D();D();D();V2={Auto:"auto",Ask:"ask",Human:"human",Manual:"manual"},GB=[V2.Auto,V2.Ask,V2.Human,V2.Manual],j0={Pending:"pending",Ready:"ready",Done:"done",Skipped:"skipped",Blocked:"blocked"},zB=[j0.Pending,j0.Ready,j0.Done,j0.Skipped,j0.Blocked],O2={Basic:"basic",PlanningOnly:"planning-only",StandardDelivery:"standard-delivery",FullDelivery:"full-delivery"},HB=[O2.Basic,O2.PlanningOnly,O2.StandardDelivery,O2.FullDelivery],K$={IssueSync:"issue.sync",ContextResearch:"context.research",PlanCreate:"plan.create",PlanApprove:"plan.approve",BranchCheck:"branch.check",WorkClaim:"work.claim",ImplementationReport:"implementation.report",ReviewReport:"review.report",ValidationReport:"validation.report",QualityGate:"quality.gate",PrPrepare:"pr.prepare",PrCreate:"pr.create",MissionClose:"mission.close"},VB=[K$.IssueSync,K$.ContextResearch,K$.PlanCreate,K$.PlanApprove,K$.BranchCheck,K$.WorkClaim,K$.ImplementationReport,K$.ReviewReport,K$.ValidationReport,K$.QualityGate,K$.PrPrepare,K$.PrCreate,K$.MissionClose],I1={Planning:"planning",Planned:"planned",InProgress:"in_progress",Review:"review",Validated:"validated",Blocked:"blocked",Closed:"closed"},OB=[I1.Planning,I1.Planned,I1.InProgress,I1.Review,I1.Validated,I1.Blocked,I1.Closed],T0={Implementation:"implementation",Review:"review",Validation:"validation",Quality:"quality",Handoff:"handoff"},KB=[T0.Implementation,T0.Review,T0.Validation,T0.Quality,T0.Handoff],I$={Github:"github",Gitlab:"gitlab",Jira:"jira",Linear:"linear",AzureBoards:"azure-boards",Shortcut:"shortcut",Clickup:"clickup",Asana:"asana",Trello:"trello",Notion:"notion",Custom:"custom"},qB=[I$.Github,I$.Gitlab,I$.Jira,I$.Linear,I$.AzureBoards,I$.Shortcut,I$.Clickup,I$.Asana,I$.Trello,I$.Notion,I$.Custom],U1={Github:"github",Gitlab:"gitlab",Bitbucket:"bitbucket",AzureDevops:"azure-devops",Gitea:"gitea",Codeberg:"codeberg",GenericGit:"generic-git",None:"none"},BB=[U1.Github,U1.Gitlab,U1.Bitbucket,U1.AzureDevops,U1.Gitea,U1.Codeberg,U1.GenericGit,U1.None],x6={Preview:"preview",Ask:"ask",Disabled:"disabled"},LB=[x6.Preview,x6.Ask,x6.Disabled],t9={Repo:"repo",Global:"global"},AB=[t9.Repo,t9.Global],g6={Preview:"preview",Draft:"draft",Ready:"ready"},MB=[g6.Preview,g6.Draft,g6.Ready],jB=V2,TU=GB,TB=j0,EB=zB,CB=O2,XQ=HB,SB=K$,EU=VB,FB=I1,IB=OB,E0=T0,DB=KB,RB=I$,CU=qB,NB=U1,SU=BB,wB=x6,PB=LB,bB=t9,FU=AB,kB=g6,fB=MB,C=jB,f$=TB,D$=CB,yB=XQ,A=SB,d=FB,vB=E0,IU=DB,p=RB,o=NB,xB=wB,C0=bB,s9=kB;lB=["ISSUE","GH","GL"],DU=/^[A-Z][A-Z0-9]*$/,pB=/^[A-Za-z0-9][A-Za-z0-9._-]{1,80}$/;wU=L.object({provider:L.enum(CU).optional()}).strict(),PU=L.object({provider:L.enum(SU).optional(),baseBranch:L.string().min(1).optional(),prMode:L.enum(PB).optional()}).strict(),aB=L.object({uses:L.string().min(1),enabled:L.boolean().optional(),advance:L.string().min(1).optional()}).strict(),bU=L.object({preset:L.string().min(1).optional(),steps:L.array(aB).optional()}).strict(),sB=L.object({repoId:L.string().min(1).optional(),tracker:wU.optional(),git:PU.optional(),flow:bU.optional(),issuePrefixes:L.array(L.string()),retentionDays:L.number().int().positive()}).strict(),tB=L.object({latestPath:L.string().min(1),approved:L.boolean(),approvedAt:L.string().optional()}).strict(),eB=L.object({agent:L.string().min(1),startedAt:L.string().min(1),branch:L.string().optional(),sourceSha:L.string().optional()}).strict(),$L=L.object({reason:L.string().min(1),blockedAt:L.string().min(1)}).strict(),QL=L.object({implementation:L.string().optional(),review:L.string().optional(),validation:L.string().optional(),quality:L.string().optional(),handoff:L.string().optional()}).strict(),ZL=L.object({latestPath:L.string().optional(),url:L.string().optional(),mode:L.enum(fB).optional(),createdAt:L.string().optional(),updatedAt:L.string().optional()}).strict(),XL=L.object({preset:L.enum(XQ),hash:L.string().min(1),steps:L.array(L.object({uses:L.enum(EU),enabled:L.boolean(),advance:L.enum(TU),status:L.enum(EB),artifactPath:L.string().optional(),updatedAt:L.string().optional()}).strict())}).strict(),UL=L.object({version:L.literal(1),repoId:L.string().min(1),repoLabel:L.string().min(1),storageScope:L.enum(FU),createdAt:L.string().min(1),updatedAt:L.string().min(1),tracker:wU.optional(),git:PU.optional(),flow:bU.optional(),issuePrefixes:L.array(L.string())}).strict(),JL=L.object({version:L.literal(1),missionId:L.string().min(1),repoId:L.string().min(1),repoLabel:L.string().min(1),issueKey:L.string().min(1),issuePathKey:L.string().min(1),title:L.string().min(1),status:L.enum(IB),storageScope:L.enum(FU),createdAt:L.string().min(1),updatedAt:L.string().min(1),branch:L.string().optional(),sourceSha:L.string().optional(),plan:tB.optional(),claim:eB.optional(),reports:QL,pr:ZL.optional(),flow:XL.optional(),blocker:$L.optional(),nextAction:L.string().min(1)}).strict();OL=[{id:A.IssueSync,label:"Sync issue context",nextAction:"Sync or confirm issue context.",externalWrite:!1},{id:A.ContextResearch,label:"Research context",nextAction:"Research code and tracker context.",externalWrite:!1},{id:A.PlanCreate,label:"Create plan",nextAction:"Create and register a Mission plan.",externalWrite:!1},{id:A.PlanApprove,label:"Approve plan",nextAction:"Approve the latest plan.",externalWrite:!1},{id:A.BranchCheck,label:"Check branch",nextAction:"Confirm the implementation branch.",externalWrite:!1},{id:A.WorkClaim,label:"Claim work",nextAction:"Claim the mission for implementation.",externalWrite:!1},{id:A.ImplementationReport,label:"Implementation report",nextAction:"Create an implementation report.",externalWrite:!1},{id:A.ReviewReport,label:"Review report",nextAction:"Create a review report.",externalWrite:!1},{id:A.ValidationReport,label:"Validation report",nextAction:"Create a validation report.",externalWrite:!1},{id:A.QualityGate,label:"Quality gate",nextAction:"Create a quality gate report.",externalWrite:!1},{id:A.PrPrepare,label:"Prepare PR",nextAction:"Prepare a PR preview.",externalWrite:!1},{id:A.PrCreate,label:"Create PR",nextAction:"Ask for approval to create the PR.",externalWrite:!0},{id:A.MissionClose,label:"Close mission",nextAction:"Close the mission.",externalWrite:!1}],yU={[D$.Basic]:[{uses:A.PlanCreate,advance:C.Auto},{uses:A.PlanApprove,advance:C.Human},{uses:A.WorkClaim,advance:C.Auto},{uses:A.ImplementationReport,advance:C.Manual},{uses:A.ReviewReport,advance:C.Manual},{uses:A.ValidationReport,advance:C.Manual},{uses:A.MissionClose,advance:C.Manual}],[D$.PlanningOnly]:[{uses:A.IssueSync,advance:C.Auto},{uses:A.ContextResearch,advance:C.Auto},{uses:A.PlanCreate,advance:C.Auto},{uses:A.PlanApprove,advance:C.Human}],[D$.StandardDelivery]:[{uses:A.IssueSync,advance:C.Auto},{uses:A.ContextResearch,enabled:!1,advance:C.Auto},{uses:A.PlanCreate,advance:C.Auto},{uses:A.PlanApprove,advance:C.Human},{uses:A.BranchCheck,advance:C.Ask},{uses:A.WorkClaim,advance:C.Auto},{uses:A.ImplementationReport,advance:C.Manual},{uses:A.ReviewReport,advance:C.Manual},{uses:A.ValidationReport,advance:C.Manual},{uses:A.QualityGate,advance:C.Manual},{uses:A.PrPrepare,advance:C.Ask},{uses:A.PrCreate,advance:C.Human}],[D$.FullDelivery]:[{uses:A.IssueSync,advance:C.Auto},{uses:A.ContextResearch,advance:C.Auto},{uses:A.PlanCreate,advance:C.Auto},{uses:A.PlanApprove,advance:C.Human},{uses:A.BranchCheck,advance:C.Ask},{uses:A.WorkClaim,advance:C.Auto},{uses:A.ImplementationReport,advance:C.Manual},{uses:A.ReviewReport,advance:C.Manual},{uses:A.ValidationReport,advance:C.Manual},{uses:A.QualityGate,advance:C.Manual},{uses:A.PrPrepare,advance:C.Ask},{uses:A.PrCreate,advance:C.Human},{uses:A.MissionClose,advance:C.Manual}]},K2=[...yB];CL={[A.IssueSync]:($)=>$.issueKey&&$.title,[A.ContextResearch]:($)=>$.reports.handoff,[A.PlanCreate]:($)=>$.plan,[A.PlanApprove]:($)=>$.plan?.approved,[A.BranchCheck]:($)=>$.branch||$.claim?.branch,[A.WorkClaim]:($)=>$.claim,[A.ImplementationReport]:($)=>$.reports.implementation,[A.ReviewReport]:($)=>$.reports.review,[A.ValidationReport]:($)=>$.reports.validation,[A.QualityGate]:($)=>$.reports.quality,[A.PrPrepare]:($)=>$.pr?.latestPath,[A.PrCreate]:($)=>$.pr?.url,[A.MissionClose]:($)=>$.status===d.Closed};rL=["cache","mission"],oL=["mission"];UA=new Set(["agent","from","flow","git-provider","issue","key","name","note","older-than","prefix","provider","reason","repo","title","tracker","type","base","base-branch"]);H2={SHOW:"show",LIST:"list",VALIDATE:"validate",EXPORT:"export",USE:"use"};VQ=[{value:o.Github,label:"GitHub",hint:"Create pull requests with gh"},{value:o.Gitlab,label:"GitLab",hint:"Create merge requests with glab later"},{value:o.Bitbucket,label:"Bitbucket",hint:"Recognized; manual PR flow in V1"},{value:o.AzureDevops,label:"Azure DevOps",hint:"Recognized; manual PR flow in V1"},{value:o.Gitea,label:"Gitea",hint:"Recognized; manual PR flow in V1"},{value:o.Codeberg,label:"Codeberg",hint:"Recognized; manual PR flow in V1"},{value:o.GenericGit,label:"Generic Git",hint:"No hosted PR automation"},{value:o.None,label:"None",hint:"Disable PR assistance"}];r6=[{value:p.Github,label:"GitHub",hint:"#123 becomes GH-123",inputLabel:"GitHub issue number",placeholder:"123"},{value:p.Gitlab,label:"GitLab",hint:"#123 becomes GL-123",inputLabel:"GitLab issue IID",placeholder:"123"},{value:p.Jira,label:"Jira",hint:"PROJECT-123",inputLabel:"Jira ticket key",placeholder:"PROJECT-123"},{value:p.Linear,label:"Linear",hint:"TEAM-123",inputLabel:"Linear issue identifier",placeholder:"TEAM-123"},{value:p.AzureBoards,label:"Azure Boards",hint:"AB#123 or work item 123",inputLabel:"Azure Boards work item",placeholder:"AB#123"},{value:p.Shortcut,label:"Shortcut",hint:"Story ID or task URL",inputLabel:"Shortcut story ID",placeholder:"12345"},{value:p.Clickup,label:"ClickUp",hint:"Task ID or task URL",inputLabel:"ClickUp task ID",placeholder:"abc123"},{value:p.Asana,label:"Asana",hint:"Task ID or task URL",inputLabel:"Asana task ID",placeholder:"1200000000000000"},{value:p.Trello,label:"Trello",hint:"Card ID or card URL",inputLabel:"Trello card ID",placeholder:"card-slug-or-id"},{value:p.Notion,label:"Notion",hint:"Task/page ID or title",inputLabel:"Notion task ID or title",placeholder:"release checklist"},{value:p.Custom,label:"Custom ID",hint:"Use any local mission label",inputLabel:"Custom mission ID",placeholder:"checkout race condition"}],uA=/^(?:#|GH-|GL-)?([0-9]+)$/i,dA=/^[A-Z][A-Z0-9]*-[0-9]+$/;AU={Skip:"skip"},k$={Create:"create",CreateDraft:"create-draft",Preview:"preview"},sU={Create:k$.Create,CreateDraft:k$.CreateDraft},v6={Yes:"yes",No:"no"},Rb={Plan:"plan",Implementation:E0.Implementation,Review:E0.Review,Validation:E0.Validation,Quality:E0.Quality,Handoff:E0.Handoff,Pr:"pr"},N1=Symbol("init-option-error");EM=["main","dev","uat","prod"];b={init:{name:"mission init",description:"Initialize Mission state for this repository or global workspace",usage:["sumr mission init","sumr mission init --tracker github --git-provider github --flow standard-delivery","sumr mission init --tracker jira --prefix SMR --prefix OPS --flow planning-only"],options:[{flag:"--tracker <type>",description:"Work source: github, gitlab, jira, linear, azure-boards, shortcut, clickup, asana, trello, notion, custom"},{flag:"--provider <type>",description:"Alias for --tracker"},{flag:"--git-provider <type>",description:"Git/PR provider: github, gitlab, bitbucket, azure-devops, gitea, codeberg, generic-git, none"},{flag:"--flow <preset>",description:"Mission flow: basic, planning-only, standard-delivery, full-delivery"},{flag:"--prefix <value>",description:"Accepted issue key prefix; repeatable"},{flag:"--yes",description:"Use defaults and skip interactive prefix setup"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},start:{name:"mission start",description:"Start or resume a mission",usage:["sumr mission start",'sumr mission start SMR-123 --title "Improve onboarding"','sumr mission start --tracker github --issue 123 --name "Fix checkout flow"'],options:[{flag:"--title <title>",description:"Mission title"},{flag:"--name <title>",description:"Alias for --title, useful for API payloads"},{flag:"--tracker <type>",description:"Tracker: github, gitlab, jira, linear, azure-boards, shortcut, clickup, asana, trello, notion, custom"},{flag:"--provider <type>",description:"Alias for --tracker"},{flag:"--issue <id>",description:"Raw tracker issue number, key, or custom ID"},{flag:"--key <id>",description:"Alias for --issue"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr mission start",'sumr mission start GH-123 --title "Fix checkout flow"','sumr mission start --tracker jira --key SMR-123 --name "Fix checkout flow" --json']},status:{name:"mission status",description:"Show Mission status and next action",usage:["sumr mission status","sumr mission status SMR-123"],options:[{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},next:{name:"mission next",description:"Show the next Mission action",usage:["sumr mission next","sumr mission next --all"],options:[{flag:"--all",description:"Include all repo namespaces in this storage root"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},list:{name:"mission list",description:"List missions",usage:["sumr mission list","sumr mission list --all"],options:[{flag:"--all",description:"Include all repo namespaces in this storage root"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},plan:{name:"mission plan",description:"Create or register a mission plan",usage:["sumr mission plan SMR-123","sumr mission plan SMR-123 --from plan.md","sumr mission plan SMR-123 --from plan.md --approve"],options:[{flag:"--from <file>",description:"Use an existing plan file as source"},{flag:"--approve",description:"Mark the plan approved in the same command"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},approve:{name:"mission approve",description:"Approve the current mission plan for implementation",usage:["sumr mission approve SMR-123"],options:[{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},claim:{name:"mission claim",description:"Claim a mission for implementation",usage:["sumr mission claim SMR-123 --agent codex"],options:[{flag:"--agent <name>",description:"Agent or session name"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},report:{name:"mission report",description:"Create a mission report",usage:["sumr mission report SMR-123 --type validation"],options:[{flag:"--type <kind>",description:"Report type: implementation, review, validation, quality, handoff"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},block:{name:"mission block",description:"Mark a mission as blocked",usage:['sumr mission block SMR-123 --reason "Waiting for design"'],options:[{flag:"--reason <text>",description:"Blocker reason"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},unblock:{name:"mission unblock",description:"Clear a mission blocker",usage:["sumr mission unblock SMR-123"],options:[{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},close:{name:"mission close",description:"Close a completed mission",usage:["sumr mission close SMR-123","sumr mission close SMR-123 --force"],options:[{flag:"--force",description:"Close without a validation report"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},clean:{name:"mission clean",description:"Remove expired closed mission cache",usage:["sumr mission clean --dry-run","sumr mission clean --older-than 30"],options:[{flag:"--older-than <days>",description:"Retention threshold for closed missions"},{flag:"--dry-run",description:"Show eligible cache without deleting"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},flow:{name:"mission flow",description:"Inspect and configure Mission flow presets",usage:["sumr mission flow list","sumr mission flow show","sumr mission flow use standard-delivery","sumr mission flow validate","sumr mission flow export --json"],options:[{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]},pr:{name:"mission pr",description:"Prepare or create a pull request from Mission evidence",usage:["sumr mission pr SMR-123 --preview","sumr mission pr SMR-123 --create-draft","sumr mission pr SMR-123 --create"],options:[{flag:"--preview",description:"Write a PR preview artifact without external writes"},{flag:"--create-draft",description:"Ask approval, push branch, and create draft PR"},{flag:"--create",description:"Ask approval, push branch, and create PR"},{flag:"--base <branch>",description:"Target branch override"},{flag:"--base-branch <branch>",description:"Alias for --base"},{flag:"--allow-custom-key",description:"Allow a non-prefixed slug key"},{flag:"--json",description:"Output machine-readable JSON"},{flag:"--help, -h",description:"Show command help"}]}},dM=K1({name:"mission",description:"Track AI-assisted work state and next actions",group:"modules",visibility:"public",commands:[T({name:"init",description:b.init.description,group:"modules",visibility:"public",help:b.init,execute:pA}),T({name:"start",description:b.start.description,group:"modules",visibility:"public",help:b.start,execute:vM}),T({name:"status",description:b.status.description,group:"modules",visibility:"public",help:b.status,execute:WM}),T({name:"next",description:b.next.description,group:"modules",visibility:"public",help:b.next,execute:GM}),T({name:"list",description:b.list.description,group:"modules",visibility:"public",help:b.list,execute:_M}),T({name:"plan",description:b.plan.description,group:"modules",visibility:"public",help:b.plan,execute:zM}),T({name:"approve",description:b.approve.description,group:"modules",visibility:"public",help:b.approve,execute:HM}),T({name:"claim",description:b.claim.description,group:"modules",visibility:"public",help:b.claim,execute:VM}),T({name:"report",description:b.report.description,group:"modules",visibility:"public",help:b.report,execute:OM}),T({name:"block",description:b.block.description,group:"modules",visibility:"public",help:b.block,execute:KM}),T({name:"unblock",description:b.unblock.description,group:"modules",visibility:"public",help:b.unblock,execute:qM}),T({name:"close",description:b.close.description,group:"modules",visibility:"public",help:b.close,execute:BM}),T({name:"clean",description:b.clean.description,group:"modules",visibility:"public",help:b.clean,execute:LM}),T({name:"flow",description:b.flow.description,group:"modules",visibility:"public",help:b.flow,execute:RA}),T({name:"pr",description:b.pr.description,group:"modules",visibility:"public",help:b.pr,execute:CM})]})});var gW={};y2(gW,{validatePlaybookSlice:()=>rJ,playbookModule:()=>RN,PlaybookSliceSchema:()=>iJ});import{z as N$}from"zod";import{existsSync as oJ,mkdirSync as lM,readdirSync as pM,writeFileSync as cM}from"fs";import{join as IQ,resolve as aJ}from"path";import{existsSync as uQ,readFileSync as nM}from"fs";import{join as iM}from"path";import{stdout as qT}from"process";import{log as ET}from"@clack/prompts";import{existsSync as pQ,mkdirSync as CT,readdirSync as ST,readFileSync as FT,renameSync as IT,rmSync as RQ,statSync as DT,writeFileSync as RT}from"fs";import{dirname as NT,join as cQ}from"path";import{existsSync as BY}from"fs";import{resolve as wQ}from"path";import{existsSync as WE,readdirSync as _E,readFileSync as GE,statSync as zE}from"fs";import{basename as _J,dirname as q8,join as HE,relative as VE,resolve as OE}from"path";import{existsSync as aQ,readdirSync as sQ,readFileSync as aE,statSync as sE}from"fs";import{homedir as tE}from"os";import{basename as bQ,dirname as f0,join as w$,resolve as v1}from"path";import{fileURLToPath as FY}from"url";import{existsSync as ZC,readFileSync as XC,realpathSync as HJ,statSync as UC}from"fs";import{isAbsolute as AQ,join as JC,relative as VJ,resolve as YC}from"path";import{existsSync as VC,realpathSync as OC,statSync as KC}from"fs";import{existsSync as US}from"fs";import{relative as $5,resolve as Q5,sep as wY}from"path";import{sep as RS}from"path";import{existsSync as kY,readFileSync as fY,rmSync as MJ}from"fs";import{join as R2,relative as yY,resolve as yQ,sep as X5}from"path";import{existsSync as AF,readFileSync as MF}from"fs";import{join as jF}from"path";import{existsSync as cY,readFileSync as nY,writeFileSync as iY}from"fs";import{join as rY}from"path";import{existsSync as XW,mkdirSync as dF,readFileSync as mF,writeFileSync as lF}from"fs";import{join as UW}from"path";import{existsSync as GW,readdirSync as tF,rmSync as xQ}from"fs";import{basename as eF,join as Y1}from"path";import{chmodSync as JI,existsSync as M8,readdirSync as j8,readFileSync as T8,rmSync as G5}from"fs";import{basename as z5,extname as E8,join as T$}from"path";import{basename as DI,join as vJ}from"path";import{existsSync as bI,readFileSync as kI}from"fs";import{join as fI}from"path";import{chmodSync as YD,existsSync as WD,readFileSync as _D}from"fs";import{join as b2}from"path";import{existsSync as GD,readFileSync as zD}from"fs";import{join as HD}from"path";import{existsSync as VD,readFileSync as OD}from"fs";import{basename as KD,join as qD}from"path";import{join as lJ}from"path";import{existsSync as RR}from"fs";import{resolve as kW}from"path";import{existsSync as hR}from"fs";import{dirname as uR,resolve as yW}from"path";function rJ($){let Q=iJ.safeParse($);if(Q.success)return{ok:!0,value:Q.data};return{ok:!1,issues:Q.error.issues.map((X)=>{return`${X.path.length>0?X.path.join("."):"(root)"}: ${X.message}`})}}function M2($){return $.playbook.agentsMd??={},$.playbook.agentsMd}function x1($){return $.mission??={},$.mission}function sJ($){let Q=x1($);return Q.git??={},Q.git}function Uj($){let Q=x1($);return Q.tracker??={},Q.tracker}function $8($){let Q=x1($);return Q.flow??={},Q.flow}function Jj($){let Q=$8($);return Q.steps??=[],Q.steps}function Yj($){let Q=x1($);return Q.issuePrefixes??=[],Q.issuePrefixes}function Wj($){return rM.includes($)}function _j($){return oM.includes($)}function Gj($){return aM.includes($)}function zj($){return sM.includes($)}function Hj($){return tM.includes($)}function Bj($){let Q=[];Q.push("# SUMR per-repo configuration"),Q.push("# Run `sumr playbook config` to update this file."),Q.push(`version: ${$.version}`),Q.push(""),Q.push(...tJ($));let Z=$.kontract?.input?.trim(),X=$.kontract?.output?.trim();if(Z||X){if(Q.push(""),Q.push("# Kontract"),Q.push("kontract:"),Z)Q.push(` input: ${Z}`);if(X)Q.push(` output: ${X}`)}return Q.push(""),Q.join(`
|
|
345
|
+
`)}function Lj($,Q){if($.push(" agentsMd:"),Q.enabled!==void 0)$.push(` enabled: ${Q.enabled}`);if(Q.claudeMd!==void 0)$.push(` claudeMd: ${Q.claudeMd}`);let Z=Q.targets??qj;if(Z.length>0){$.push(" targets:");for(let X of Z)$.push(` - ${X===Vj?Oj:X}`)}}function tJ($){let Q=[];Q.push("# Playbook"),Q.push("playbook:"),Q.push(" channels:");for(let[Z,X]of Object.entries($.playbook.channels))Q.push(` ${Z}: ${X}`);Q.push(" sources:");for(let Z of $.playbook.sources)Q.push(` - ${Z}`);if($.playbook.hideGen!==void 0)Q.push(` hideGen: ${$.playbook.hideGen}`);if($.playbook.agentsMd)Lj(Q,$.playbook.agentsMd);return Q}function dQ($){return iM($,Aj)}function N2($){return uQ(dQ($))}function w2($){let Q=dQ($);if(!uQ(Q))throw Error(`No sumr.yaml found in ${$}. Run \`sumr playbook config\` to set up this repo.`);let Z=nM(Q,"utf8");return lj(Z)}function Cj($,Q){let Z=dQ($);if(!uQ(Z)){W0(Z,Bj(Q));return}h1(Z,"playbook",tJ(Q),{sectionComment:Kj})}function Q8($){return Object.entries($.playbook.channels).filter(([,Q])=>Q).map(([Q])=>Q)}function Z8(){return structuredClone(Ej)}function z1($){let Q=$.trim();if(!Q)return;let Z=Q[0],X=Q.at(-1);if((Z===jj||Z===Tj)&&X===Z&&Q.length>=2)return Q.slice(1,-1).trim()||void 0;return Q.replace(/\s+#.*$/,"").trim()||void 0}function Sj($,Q,Z){if(/^ {4}enabled:\s*(true|false)/.test($))return M2(Z).enabled=/true/.test($),!0;if(/^ {4}claudeMd:\s*(true|false)/.test($))return M2(Z).claudeMd=/true/.test($),!0;if(/^ {4}targets:\s*$/.test($))return Q.playbookSection=G$.agentsMdTargets,M2(Z).targets=[],!0;return!1}function Fj($,Q,Z){if(Q.playbookSection===G$.channels){let X=$.match(/^\s{4}(\w+):\s*(true|false)/),U=X?.[1],J=X?.[2];if(U&&J)Z.playbook.channels[U]=J===Mj.TRUE}else if(Q.playbookSection===G$.sources){let U=$.match(/^(?: {2}| {4})-\s+(.+)/)?.[1];if(U)Z.playbook.sources.push(U.trim())}}function Ij($,Q,Z){if(/^ {2}channels:/.test($))return Q.playbookSection=G$.channels,Z.playbook.channels={},!0;if(/^ {2}sources:/.test($))return Q.playbookSection=G$.sources,Z.playbook.sources=[],!0;if(/^ {2}hideGen:\s*(true|false)/.test($))return Z.playbook.hideGen=/true/.test($),Q.playbookSection=G$.none,!0;if(/^ {2}agentsMd:\s*$/.test($))return Q.playbookSection=G$.agentsMd,M2(Z),!0;return!1}function Dj($,Q,Z){if(Q.playbookSection!==G$.agentsMdTargets||!/^ {6}-\s+/.test($))return!1;let U=$.match(/^ {6}-\s+(.+)$/)?.[1];if(U){let J=z1(U);if(J){let Y=M2(Z);Y.targets??=[],Y.targets.push(J)}}return!0}function Rj($,Q,Z){if(Ij($,Q,Z))return!0;if(Q.playbookSection===G$.agentsMd)return Sj($,Q,Z);if(Dj($,Q,Z))return!0;if(/^ {2}[A-Za-z][A-Za-z0-9_-]*:/.test($))return Q.playbookSection=G$.none,!0;return Fj($,Q,Z),!1}function Nj($,Q){let Z=$.match(/^ {4}(provider|baseBranch|prMode):\s*(.+)$/);if(!Z?.[1]||!Z[2])return;let X=Z[1],U=z1(Z[2]),J=sJ(Q);if(X===qQ.PROVIDER&&U&&_j(U))J.provider=U;else if(X===qQ.BASE_BRANCH&&U)J.baseBranch=U;else if(X===qQ.PR_MODE&&U&&Gj(U))J.prMode=U}function wj($,Q,Z){if(/^ {4}preset:\s*(.+)$/.test($)){let X=$.match(/^ {4}preset:\s*(.+)$/)?.[1],U=X?z1(X):void 0;if(U&&zj(U))$8(Z).preset=U;return!0}if(/^ {4}steps:\s*$/.test($))return Q.missionSection=e.flowSteps,Q.currentFlowStepIndex=-1,$8(Z).steps=[],!0;return!1}function Pj($,Q){if(Q)Q.enabled=/^ {8}enabled:\s*true/.test($)}function bj($,Q){let Z=$.match(/^ {8}advance:\s*(.+)$/)?.[1],X=Z?z1(Z):void 0;if(X&&Hj(X)&&Q)Q.advance=X}function kj($,Q,Z){if(/^ {6}-\s+uses:\s*(.+)$/.test($)){let X=$.match(/^ {6}-\s+uses:\s*(.+)$/)?.[1],U=X?z1(X):void 0;if(U){let J=Jj(Z);J.push({uses:U}),Q.currentFlowStepIndex=J.length-1}return!0}if(Q.currentFlowStepIndex>=0&&/^ {8}enabled:\s*(true|false)/.test($))return Pj($,Z.mission?.flow?.steps?.[Q.currentFlowStepIndex]),!0;if(Q.currentFlowStepIndex>=0&&/^ {8}advance:\s*(.+)$/.test($))return bj($,Z.mission?.flow?.steps?.[Q.currentFlowStepIndex]),!0;return!1}function fj($,Q,Z){if(/^ {2}issuePrefixes:\s*$/.test($))return Q.missionSection=e.issuePrefixes,x1(Z).issuePrefixes=[],!0;if(/^ {2}tracker:\s*$/.test($))return Q.missionSection=e.tracker,Uj(Z),!0;if(/^ {2}git:\s*$/.test($))return Q.missionSection=e.git,sJ(Z),!0;if(/^ {2}flow:\s*$/.test($))return Q.missionSection=e.flow,Q.currentFlowStepIndex=-1,$8(Z),!0;return!1}function yj($,Q,Z){let X=$.match(/^ {2}(repoId|retentionDays):\s*(.+)$/);if(!X?.[1]||!X[2])return!1;let U=X[1],J=z1(X[2]),Y=x1(Z);if(Q.missionSection=e.none,U===XJ.REPO_ID&&J)Y.repoId=J;else if(U===XJ.RETENTION_DAYS&&J&&/^\d+$/.test(J))Y.retentionDays=Number(J);return!0}function vj($,Q,Z){if(Q.missionSection!==e.tracker||!/^ {4}provider:\s*(.+)$/.test($))return!1;let X=$.match(/^ {4}provider:\s*(.+)$/)?.[1],U=X?z1(X)?.toLowerCase():void 0;if(U&&Wj(U))x1(Z).tracker={provider:U};return!0}function xj($,Q,Z){if(vj($,Q,Z))return!0;if(Q.missionSection===e.git)return Nj($,Z),!0;if(Q.missionSection===e.flow)return wj($,Q,Z);if(Q.missionSection===e.flowSteps)return kj($,Q,Z);return}function gj($,Q,Z){if(Q.missionSection!==e.issuePrefixes||!/^ {4}-\s+(.+)$/.test($))return;let X=$.match(/^ {4}-\s+(.+)$/)?.[1],U=X?z1(X):void 0;if(U)Yj(Z).push(U.toUpperCase())}function hj($,Q,Z){if(fj($,Q,Z))return!0;let X=xj($,Q,Z);if(X!==void 0)return X;if(yj($,Q,Z))return!0;if(/^ {2}\S/.test($))Q.missionSection=e.none;return gj($,Q,Z),!1}function uj($,Q,Z){if(/^playbook:/.test($))return Q.topSection=W1.playbook,Q.playbookSection=G$.none,Q.missionSection=e.none,!0;if(/^kontract:/.test($))return Q.topSection=W1.kontract,Q.playbookSection=G$.none,Q.missionSection=e.none,Z.kontract??={},!0;if(/^mission:/.test($))return Q.topSection=W1.mission,Q.playbookSection=G$.none,Q.missionSection=e.none,x1(Z),!0;if(/^\w/.test($)&&$!==KQ.PLAYBOOK&&$!==KQ.KONTRACT&&$!==KQ.MISSION)Q.topSection=W1.root,Q.playbookSection=G$.none,Q.missionSection=e.none;return!1}function dj($,Q){let Z=$.match(/^\s{2}(input|output):\s*(.+)$/),X=Z?.[1],U=Z?.[2];if(!X||!U)return;let J=z1(U);if(!J)return;if(Q.kontract??={},X===Xj.INPUT)Q.kontract.input=J;else Q.kontract.output=J}function mj($,Q,Z){if(uj($,Q,Z))return;if(Q.topSection===W1.root){let X=$.match(/^version:\s*(\d+)/);if(X)Z.version=Number(X[1])}else if(Q.topSection===W1.playbook)Rj($,Q,Z);else if(Q.topSection===W1.kontract)dj($,Z);else if(Q.topSection===W1.mission)hj($,Q,Z)}function lj($){let Q=Z8(),Z=$.split(`
|
|
346
|
+
`),X={topSection:W1.root,playbookSection:G$.none,missionSection:e.none,currentFlowStepIndex:-1};for(let U of Z){let J=U.trimEnd();if(!J||J.startsWith("#"))continue;mj(J,X,Q)}return Q}async function P0($,Q,Z="mauve"){let{note:X}=await import("@clack/prompts");X(Q,$,P$(Z))}async function b0($,Q){await P0($,Q,"pink")}function UJ($){return $.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function nj($,Q,Z,X){let U=`name: ${Q}
|
|
344
347
|
title: ${Z}
|
|
345
|
-
description: "${X}"`;if($===
|
|
348
|
+
description: "${X}"`;if($===f1.SKILL)return`---
|
|
346
349
|
${U}
|
|
347
350
|
tags: []
|
|
348
351
|
---
|
|
@@ -354,7 +357,7 @@ tags: []
|
|
|
354
357
|
## Overview
|
|
355
358
|
|
|
356
359
|
TODO: add content.
|
|
357
|
-
`;if($===
|
|
360
|
+
`;if($===f1.TEAM_MEMBER)return`---
|
|
358
361
|
category: team-member
|
|
359
362
|
${U}
|
|
360
363
|
modelTier: coding
|
|
@@ -388,7 +391,7 @@ TODO: describe the team-member role and responsibilities.
|
|
|
388
391
|
## Instructions
|
|
389
392
|
|
|
390
393
|
TODO: add instructions.
|
|
391
|
-
`;if($===
|
|
394
|
+
`;if($===f1.WORKFLOW)return`---
|
|
392
395
|
category: workflow
|
|
393
396
|
${U}
|
|
394
397
|
target: ${Q}.md
|
|
@@ -405,7 +408,7 @@ TODO: describe when the AI should run this user-invoked workflow.
|
|
|
405
408
|
## Instructions
|
|
406
409
|
|
|
407
410
|
TODO: write the reusable prompt or procedure.
|
|
408
|
-
`;if($===
|
|
411
|
+
`;if($===f1.LIFECYCLE)return`---
|
|
409
412
|
category: lifecycle
|
|
410
413
|
${U}
|
|
411
414
|
event: SessionStart
|
|
@@ -433,12 +436,12 @@ order: 10
|
|
|
433
436
|
## Overview
|
|
434
437
|
|
|
435
438
|
TODO: add reference content.
|
|
436
|
-
`}function
|
|
439
|
+
`}function ij($){if($===f1.TEAM_MEMBER)return".tm.md";if($===f1.WORKFLOW)return".wf.md";if($===f1.LIFECYCLE)return".lc.md";if($===f1.REFERENCE)return".rf.md";return".md"}function rj($,Q){let Z=new Set;for(let X of $){let U=aJ(Q,X);if(!oJ(U))continue;Z.add(X);try{for(let J of pM(U,{withFileTypes:!0}))if(J.isDirectory()&&!J.name.startsWith("."))Z.add(IQ(X,J.name))}catch{}}return[...Z].sort()}async function oj($,Q,Z){let X=await $({message:"Topic type",options:[{value:"skill",label:"Skill",hint:"How-to guide or standards doc (.md)"},{value:"team-member",label:"Team member",hint:"Delegated AI role (.tm.md)"},{value:"workflow",label:"Workflow",hint:"User-invoked AI workflow (.wf.md)"},{value:"lifecycle",label:"Lifecycle",hint:"AI lifecycle automation (.lc.md)"},{value:"reference",label:"Reference",hint:"Supporting detail for a skill (.rf.md)"}]});if(Q(X))return Z("Cancelled"),null;return X}async function aj($,Q,Z){let X=await $({message:"Name (kebab-case identifier)",placeholder:"my-topic",validate(U){let J=UJ(U??pj);if(!J)return"Name cannot be empty";if(J.startsWith("sumr-"))return'The "sumr-" prefix is reserved for SUMR core resources';return}});if(Q(X))return Z("Cancelled"),null;return UJ(X)}async function sj($,Q,Z){let X=await $({message:"Title (human-readable)",placeholder:"My Topic",validate(U){if(!U.trim())return"Title cannot be empty";return}});if(Q(X))return Z("Cancelled"),null;return X.trim()}async function tj($,Q,Z){let X=await $({message:"Description (what + when)",placeholder:"Covers X, Y, and Z. Use when doing X.",validate(U){if(!U.trim())return"Description cannot be empty";return}});if(Q(X))return Z("Cancelled"),null;return X.trim()}async function ej($,Q,Z,X,U,J){if(typeof Z==="string")return Z;let W=rj($,Q).map((G)=>({value:G,label:G})),_=await X({message:"Destination folder",options:W.length>0?W:[{value:$[0]??"docs",label:$[0]??"docs"}]});if(U(_))return J("Cancelled"),null;return _}async function $T($){let{extras:Q}=$.args,Z=process.cwd(),{intro:X,outro:U,select:J,text:Y,isCancel:W}=await import("@clack/prompts");X("Playbook \u2014 scaffold new doc");let _=N2(Z)?w2(Z).playbook.sources:["docs"],G=await oj(J,W,U);if(!G)return 0;let z=await aj(Y,W,U);if(!z)return 0;let H=await sj(Y,W,U);if(!H)return 0;let V=await tj(Y,W,U);if(!V)return 0;let O=await ej(_,Z,Q.source,J,W,U);if(!O)return 0;let K=ij(G),q=`${z}${K}`,B=aJ(Z,O),S=IQ(B,q);if(oJ(S))return await b0("File already exists",`${S}
|
|
437
440
|
|
|
438
|
-
Choose a different name or folder.`),1;try{
|
|
439
|
-
`)}function
|
|
440
|
-
`),"",
|
|
441
|
-
`)}function
|
|
441
|
+
Choose a different name or folder.`),1;try{lM(B,{recursive:!0}),cM(S,nj(G,z,H,V),"utf8")}catch(M){return await b0("Could not write file",M instanceof Error?M.message:String(M)),1}return U(`Created ${IQ(O,q)} \uD83C\uDF89`),0}function zT($){return mQ.includes($)}function HT($){return lQ.includes($)}function x$($,Q){let Z=Q.includes("```")?"````":"```";return[`${Z}${$}`,Q,Z].join(`
|
|
442
|
+
`)}function $Y($){let Q=["## Frontmatter Fields","","| Field | Required | Applies To | Rule |","|---|---:|---|---|"];for(let Z of $.fieldRules)Q.push(`| \`${Z.name}\` | ${Z.required?"yes":"no"} | ${Z.appliesTo} | ${Z.description} |`);return[Q.join(`
|
|
443
|
+
`),"",VT()].join(`
|
|
444
|
+
`)}function VT(){return["## Native Channel Props","","Use top-level channel blocks for AI-tool-specific features. Add a short comment above every block so the YAML is easy to scan. These comments are authoring guidance only; Playbook does not parse or require them.","",x$("yaml",`---
|
|
442
445
|
category: team-member
|
|
443
446
|
name: codebase-reviewer
|
|
444
447
|
title: Codebase Reviewer
|
|
@@ -472,10 +475,10 @@ gemini:
|
|
|
472
475
|
opencode:
|
|
473
476
|
mode: subagent
|
|
474
477
|
---`),"","Prefer `codex:`, `claude:`, `cursor:`, `copilot:`, `gemini:`, and `opencode:` for new docs. `channels:` remains supported as a legacy-compatible alias.","","## Team-Member Role Archetypes","","- `orchestrator`: coordinates mission state and handoffs.","- `product-owner`: clarifies problem, scope, and acceptance criteria.","- `researcher`: explores code/docs and reports evidence.","- `planner`: turns validated intent into an implementation plan.","- `implementer`: edits code according to an approved plan.","- `reviewer`: checks correctness, risks, and test gaps.","- `validator`: runs verification and records outcome.","","These archetypes are naming and authoring guidance, not a required `roleType` field."].join(`
|
|
475
|
-
`)}function
|
|
476
|
-
`)}function
|
|
477
|
-
`)}function
|
|
478
|
-
`)}function
|
|
478
|
+
`)}function OT($){let Q=["## Categories","","| Value | Purpose | Required fields |","|---|---|---|"];for(let Z of $.categories)Q.push(`| \`${Z.value}\` | ${Z.purpose} | ${Z.requiredFields.map((X)=>`\`${X}\``).join(", ")} |`);return Q.join(`
|
|
479
|
+
`)}function QY($){return["## Folder Structure","","Use one folder per topic/domain. References live beside the main doc. When splitting an existing file, choose the owning context folder before creating files.","","```text",$.folderStructure.pattern,"```","",`- ${$.folderStructure.mainDoc}`,`- ${$.folderStructure.references}`,"","Microconcept split example:","","```text",$.folderStructure.microconceptPattern,"```","","Context rules:",...$.folderStructure.contextRules.map((Q)=>`- ${Q}`),"","Split flow:",...$.folderStructure.splitFlow.map((Q,Z)=>`${Z+1}. ${Q}`),"","Do not:",...$.folderStructure.forbidden.map((Q)=>`- ${Q}`)].join(`
|
|
480
|
+
`)}function ZY($){return["## Extraction Markers","","Use extraction markers for dedicated examples, samples, templates, and long reusable blocks.","",x$("markdown",$.extraction.markerSyntax),"",$.extraction.generatedFile,"","Mandatory default: dedicated `## Examples` sections must be wrapped unless the snippet is truly inline and central to the instruction flow. Marker examples inside fenced code blocks are documentation and must not be extracted.","","Use extraction for:",...$.extraction.whenToUse.map((Q)=>`- ${Q}`),"","Keep inline:",...$.extraction.keepInline.map((Q)=>`- ${Q}`)].join(`
|
|
481
|
+
`)}function XY($){return["## Flow Documentation","",$.sections.flows,"","Use a one-line arrow flow when the process is mostly linear:","",x$("text","\uD83D\uDD50 intake -> [researcher] -> \uD83D\uDCDD draft -> \u23F8 HUMAN APPROVES -> \u2705 ready -> [implementer] -> review -> done"),"","Use Mermaid when the process branches, loops, or has failure paths:","",x$("mermaid",`flowchart LR
|
|
479
482
|
intake["intake"] --> research["researcher"]
|
|
480
483
|
research --> draft["draft plan"]
|
|
481
484
|
draft --> approval{"Human approves?"}
|
|
@@ -484,7 +487,7 @@ opencode:
|
|
|
484
487
|
ready --> implement["implementer"]
|
|
485
488
|
implement --> review["review"]
|
|
486
489
|
review --> done["done"]`),"","Rules:","- Keep state names short and concrete.","- Use `[role-or-agent]` for the actor responsible for a transition.","- Label human decision gates explicitly, for example `\u23F8 HUMAN APPROVES`.","- Keep emojis optional and functional; use them for state scanning, not decoration.","- Add transition rules below the diagram when an AI must know what is forbidden."].join(`
|
|
487
|
-
`)}function
|
|
490
|
+
`)}function UY($){return["## AI Resources For Channel Output","",$.sections.codex,"","Canonical docs can live in the same domain folders as the rest of the Playbook:","","```text",`docs/
|
|
488
491
|
-- team-members/
|
|
489
492
|
|-- reviewer.tm.md
|
|
490
493
|
-- docs-researcher.tm.md
|
|
@@ -492,7 +495,7 @@ opencode:
|
|
|
492
495
|
-- ui-review.wf.md
|
|
493
496
|
-- lifecycle/
|
|
494
497
|
|-- pre-tool-use-policy.lc.md
|
|
495
|
-
-- session-start-context.lc.md`,"```","","The Codex renderer updates .codex/config.toml automatically when lifecycle or team-member docs exist, writes a generated .codex/AGENTS.md startup guide for agent routing, and preserves unrelated settings. Claude renders workflow docs to .claude/commands. Gemini, OpenCode, and Copilot render team-member docs to their native agent profile folders.","","### Lifecycle","",
|
|
498
|
+
-- session-start-context.lc.md`,"```","","The Codex renderer updates .codex/config.toml automatically when lifecycle or team-member docs exist, writes a generated .codex/AGENTS.md startup guide for agent routing, and preserves unrelated settings. Claude renders workflow docs to .claude/commands. Gemini, OpenCode, and Copilot render team-member docs to their native agent profile folders.","",'When a user says "hook", "hooks", "run this when the AI stops", "after tool use", "before shell execution", "quality gate", or asks for automatic AI-tool behavior, start from a `category: lifecycle` source doc in `docs/lifecycle/`. Treat `.claude/hooks/*`, `.claude/settings.json` hook entries, `.codex/hooks.json`, and `.codex/hooks/*` as generated AI Channel output.',"","### Lifecycle","",x$("markdown",`---
|
|
496
499
|
name: session-start-context
|
|
497
500
|
title: Session Start Context Lifecycle
|
|
498
501
|
description: "Adds repository startup context to Codex sessions."
|
|
@@ -514,7 +517,7 @@ print(json.dumps({
|
|
|
514
517
|
"additionalContext": "Load repository context before non-trivial work."
|
|
515
518
|
}
|
|
516
519
|
}))
|
|
517
|
-
\`\`\``),"","### Workflow","",
|
|
520
|
+
\`\`\``),"","### Workflow","",x$("markdown",`---
|
|
518
521
|
name: ui-review
|
|
519
522
|
title: UI Review Workflow
|
|
520
523
|
description: "Runs browser UI review and reports pass/fail evidence."
|
|
@@ -536,7 +539,7 @@ Run browser UI review for selected user stories.
|
|
|
536
539
|
- Discover relevant user story files.
|
|
537
540
|
- Execute each story with browser automation.
|
|
538
541
|
- Save screenshots under a gitignored run folder.
|
|
539
|
-
- Report pass, fail, blocked, and untested steps explicitly.`),"","### Team Member","",
|
|
542
|
+
- Report pass, fail, blocked, and untested steps explicitly.`),"","### Team Member","",x$("markdown",`---
|
|
540
543
|
name: reviewer
|
|
541
544
|
title: Reviewer Team Member
|
|
542
545
|
description: "Read-only reviewer focused on correctness, security, and missing tests."
|
|
@@ -566,13 +569,13 @@ opencode:
|
|
|
566
569
|
|
|
567
570
|
Review code like an owner.
|
|
568
571
|
Prioritize correctness, security, behavior regressions, and missing test coverage.
|
|
569
|
-
Return findings first with file and line references.`),"","Rules:","- Keep canonical source docs in domain-oriented folders, not in generated output folders.","- The Codex renderer writes hook commands rooted through git rev-parse --show-toplevel.","- Do not hand-edit generated .codex/hooks.json, .codex/hooks/*, .codex/agents/*.toml, .gemini/agents/*.md, .opencode/agents/*.md, or .github/agents/*.md."].join(`
|
|
570
|
-
`)}function
|
|
571
|
-
`)}function
|
|
572
|
-
`);return["## Examples","","### overview.md","",
|
|
573
|
-
`)}function
|
|
574
|
-
`);if(Q===
|
|
575
|
-
`);if(Q===
|
|
572
|
+
Return findings first with file and line references.`),"","Rules:","- Keep canonical source docs in domain-oriented folders, not in generated output folders.","- Use lifecycle docs as the source of truth for hooks and automatic AI-session guardrails.","- The Codex renderer writes hook commands rooted through git rev-parse --show-toplevel.","- Do not hand-edit generated .codex/hooks.json, .codex/hooks/*, .codex/agents/*.toml, .gemini/agents/*.md, .opencode/agents/*.md, or .github/agents/*.md."].join(`
|
|
573
|
+
`)}function JY($){return["## Checklist","",...$.checklist.map((Q)=>`- [ ] ${Q}`)].join(`
|
|
574
|
+
`)}function YJ($,Q){if(Q)return[`## Example: ${Q}`,"",x$("markdown",$.examples[Q])].join(`
|
|
575
|
+
`);return["## Examples","","### overview.md","",x$("markdown",$.examples.overview),"","### Reference File","",x$("markdown",$.examples.reference),"","### Folder","",x$("text",$.examples.folder)].join(`
|
|
576
|
+
`)}function BQ($,Q){if(Q===v$.OVERVIEW)return["# SUMR Playbook Authoring","",$.sections.overview,"","## Source of Truth","",`- Local mode: ${$.sourceOfTruth.localMode}`,`- Cloud mode: ${$.sourceOfTruth.cloudMode}`,`- Generated output: ${$.sourceOfTruth.generatedOutput}`].join(`
|
|
577
|
+
`);if(Q===v$.FRONTMATTER)return[$Y($),"",OT($)].join(`
|
|
578
|
+
`);if(Q===v$.STRUCTURE)return QY($);if(Q===v$.REFERENCES)return["## References","",$.sections.references,"","Reference file frontmatter:","","```yaml",`---
|
|
576
579
|
category: reference
|
|
577
580
|
name: my-topic-detail
|
|
578
581
|
title: Detail Section Title
|
|
@@ -581,62 +584,62 @@ label: Detail
|
|
|
581
584
|
when: Doing X, reviewing Y, adding Z
|
|
582
585
|
order: 10
|
|
583
586
|
---`,"```","","Rules:","- References live in the same folder as the main doc.","- Do not create a references/ folder.","- Do not add a references frontmatter field."].join(`
|
|
584
|
-
`);if(Q===
|
|
585
|
-
`);return
|
|
586
|
-
`)}function
|
|
587
|
-
`)}function
|
|
588
|
-
`),0}function
|
|
589
|
-
`),
|
|
590
|
-
## `,_),z=
|
|
591
|
-
`)}function
|
|
587
|
+
`);if(Q===v$.EXTRACTION)return ZY($);if(Q===v$.FLOWS)return XY($);if(Q===v$.CODEX)return UY($);if(Q===v$.MODULE_RESOURCES)return["## Module AI Resources","",$.sections.moduleResources].join(`
|
|
588
|
+
`);return JY($)}function YY($={}){let Q=eJ;if($.example)return YJ(Q,$.example);if($.section)return BQ(Q,$.section);return[BQ(Q,v$.OVERVIEW),"",$Y(Q),"",QY(Q),"",ZY(Q),"",XY(Q),"",UY(Q),"",BQ(Q,v$.MODULE_RESOURCES),"",YJ(Q),"",JY(Q)].join(`
|
|
589
|
+
`)}function KT($={}){return{contract:eJ,selection:$,markdown:YY($)}}function _1($,Q,Z,X,U){return{version:1,ok:Q,command:$,data:Z,warnings:X,error:U}}function S2($){qT.write($)}function G1($){S2(`${JSON.stringify($,null,2)}
|
|
590
|
+
`)}function AT($){return $.args.positionals.find((Q)=>Q!==BT)}function MT($){let{extras:Q}=$.args,Z=AT($),X=typeof Q.example==="string"?Q.example:void 0,U=typeof Q.section==="string"?Q.section:X?void 0:Z,J,Y;if(U!==void 0){if(!zT(U))return{selection:{},error:{code:"INVALID_SECTION",message:`Unknown authoring section "${U}". Valid sections: ${mQ.join(", ")}`}};J=U}if(X!==void 0){if(!HT(X))return{selection:{},error:{code:"INVALID_EXAMPLE",message:`Unknown authoring example "${X}". Valid examples: ${lQ.join(", ")}`}};Y=X}if(J&&Y)return{selection:{},error:{code:"CONFLICTING_SELECTION",message:"Choose either --section or --example, not both."}};return{selection:{section:J,example:Y},error:null}}async function jT($){let Q=$.args.extras.json===!0,{selection:Z,error:X}=MT($);if(X){if(Q)G1(_1("playbook authoring",!1,null,[],X));else await b0("Invalid Playbook authoring request",X.message);return 1}if(Q)return G1(_1("playbook authoring",!0,KT(Z),[],null)),0;return S2(`${YY(Z)}
|
|
591
|
+
`),0}function V8($){return E$.find((Q)=>Q.id===$)}function Q0($,Q){let Z=$;for(let[X,U]of Object.entries(wT)){let J=Q[X];if(J!==void 0)Z=Z.replaceAll(U,J)}return Z}function WY($){return PT[$]??"Team member"}function t6($,Q){return Q0($,{TEAM_MEMBER:WY(Q)})}function HY($){return $.source!==z$.LOCAL}function h$($){if(!HY($))return $.name;if($.name.startsWith(LQ))return $.name;if($.module)return`${LQ}${$.module}${GY}${$.name}`;return`${LQ}${$.name}`}function U0($){return h$($).replace(GY,"-")}function bT($){return HY($)?"core":"local"}function nQ($){let Q={"created-by":zY,"content-source":bT($),"canonical-name":h$($)};if($.module)Q.module=$.module;if($.insight?.length)Q.insight=$.insight;if($.teamMembers?.length)Q["team-member"]=$.teamMembers.map((Z)=>h$({name:Z,source:$.source,module:$.module}));if($.review===!0)Q.review=!0;return Q}function VY($,Q){if(!$)throw Error(`Channel definition for "${Q}" not found`);return $}function g$($,Q){if(!Q)CT($,{recursive:!0})}function s($,Q,Z){if(Z)return;let X=`${$}.sumr-tmp-${Date.now()}`;try{g$(NT($),!1),RT(X,Q,"utf8"),IT(X,$)}finally{if(pQ(X))try{RQ(X,{force:!0})}catch{}}}function kT($,Q,Z,X,U){let J=cQ($,Q),Y;try{Y=DT(J)}catch{return}if(!Z.test(Q)&&!fT(J,Y.isDirectory()))return;if(U.push(J),X)return;try{if(Y.isDirectory())RQ(J,{recursive:!0,force:!0});else RQ(J,{force:!0})}catch{}}function F2($,Q,Z,X){if(!pQ($))return[];let U;try{U=ST($)}catch{return[]}let J=[];for(let Y of U){if(Q.has(Y))continue;kT($,Y,Z,X,J)}return J}function fT($,Q){let Z=Q?cQ($,"SKILL.md"):$;if(!pQ(Z))return!1;try{let X=FT(Z,"utf8");return yT(X)}catch{return!1}}function yT($){let Q=$.match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1];if(!Q)return!1;return new RegExp(`^\\s{2}created-by:\\s*${O8(zY)}\\s*$`,"m").test(Q)}function O8($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function OY($,Q,Z){if(!$.teamMembers?.length)return Q;let X=$.teamMembers.map((H)=>`\`${h$({name:H,source:$.source,module:$.module})}\``),U=X.length===1?X[0]:`${X.slice(0,-1).join(", ")} and ${X.at(-1)}`,J=vT(WY(Z)),Y=["","","## Agent Delegation","",`This workflow is a delegation trigger for ${U} when the current runtime exposes delegation tools.`,`For user prompts that match this workflow, treat the request as authorization to use the listed generated ${J}; do not require a longer prompt.`,"If delegation is unavailable, state the reason explicitly and apply the same role checklists locally.",""].join(`
|
|
592
|
+
`),W=Q.match(/## When to Use\b/i);if(!W||W.index===void 0)return`${Q.trimEnd()}${Y}`;let _=W.index+W[0].length,G=Q.indexOf(`
|
|
593
|
+
## `,_),z=G===-1?Q.length:G;return`${Q.slice(0,z).trimEnd()}${Y}${Q.slice(z)}`}function vT($){if($==="Team member")return"team members";return`${$.toLowerCase()}s`}function x0($,Q){return{...$,description:t6($.description,Q),when:$.when?t6($.when,Q):$.when,body:t6($.body,Q),channels:xT($.channels,Q),references:$.references.map((Z)=>x0(Z,Q))}}function xT($,Q){if(!$)return $;return Object.fromEntries(Object.entries($).map(([Z,X])=>[Z,Z===Q?NQ(X,Q):X]))}function NQ($,Q){if(typeof $==="string")return t6($,Q);if(Array.isArray($))return $.map((Z)=>NQ(Z,Q));if(typeof $==="object"&&$!==null)return Object.fromEntries(Object.entries($).map(([Z,X])=>[Z,NQ(X,Q)]));return $}function gT($,Q,Z){if(Z.length===0){$.push(`${Q}: []`);return}$.push(`${Q}:`);for(let X of Z)$.push(` - ${X8(X)}`)}function hT($,Q,Z){$.push(`${Q}:`);for(let[X,U]of Object.entries(Z))if(Array.isArray(U)){$.push(` ${X}:`);for(let J of U)$.push(` - ${X8(J)}`)}else $.push(` ${X}: ${X8(U)}`)}function K8($){let Q=["---"];for(let[Z,X]of Object.entries($))if(typeof X==="boolean")Q.push(`${Z}: ${X}`);else if(Array.isArray(X))gT(Q,Z,X);else if(typeof X==="object")hT(Q,Z,X);else Q.push(`${Z}: ${X8(X)}`);return Q.push("---"),Q.join(`
|
|
594
|
+
`)}function X8($){if(typeof $==="boolean"||typeof $==="number")return String($);return/[:#{}[\],&*?|<>=!%@`]/.test($)||$.trim()!==$?`"${$.replace(/"/g,"\\\"")}"`:$}function KY($,Q={}){let Z=lT($),X=[],U=$;for(let Y of $.matchAll(uT)){if(Y.index===void 0||pT(Y.index,Z))continue;let[,W,_]=Y;if(!W||_===void 0)continue;X.push({name:W,content:_.trim()}),U=U.replace(Y[0],"")}let J=cT(X);if(U=U.trim(),Q.addResourceLinks&&J.length>0)U=`${U}
|
|
592
595
|
|
|
593
|
-
${
|
|
596
|
+
${nT(J)}`.trim();return{mainContent:U,sections:J}}function lT($){return Array.from($.matchAll(dT),(Q)=>({start:Q.index??0,end:(Q.index??0)+Q[0].length}))}function pT($,Q){return Q.some((Z)=>$>=Z.start&&$<Z.end)}function cT($){let Q=new Map;for(let Z of $){let X=Q.get(Z.name);if(X)X.push(Z.content);else Q.set(Z.name,[Z.content])}return Array.from(Q.entries(),([Z,X])=>({name:Z,content:X.join(`
|
|
594
597
|
|
|
595
598
|
---
|
|
596
599
|
|
|
597
|
-
`)}))}function
|
|
600
|
+
`)}))}function nT($){return`## Additional resources
|
|
598
601
|
|
|
599
|
-
${$.map((Z)=>{let X=`${Z.name}.md`;return`- For ${
|
|
600
|
-
`)}`}function
|
|
601
|
-
`)}async function
|
|
602
|
-
`));return 1}let U=X?
|
|
603
|
-
${
|
|
604
|
-
${
|
|
602
|
+
${$.map((Z)=>{let X=`${Z.name}.md`;return`- For ${iT(Z.name)}, see [${X}](${X})`}).join(`
|
|
603
|
+
`)}`}function iT($){return $.replace(/[-_]+/g," ").toLowerCase()}function rT($,Q,Z){return F2(cQ(process.cwd(),$),new Set,Q,Z)}function oT($){return[$.outputDir,...aT($)]}function aT($){return $.legacyOutputDirs??mT}function iQ($,Q){let Z=[];for(let X of $)for(let U of oT(X))Z.push(...rT(U,X.filePattern,Q));return Z}function qY($){if($.length===0)return"";let Q=["","","## References","","| Topic | When |","|-------|------|"];for(let Z of $){let X=Z.label??Z.title,U=Z.when??Z.description;Q.push(`| **${X}** | ${U} |`)}return Q.join(`
|
|
604
|
+
`)}async function tT($){let{extras:Q}=$.args,Z=Q.json===!0,X=typeof Q.channel==="string"?Q.channel:void 0;if(X!==void 0&&!r$.includes(X)){let z=`Unknown channel: "${X}". Valid channels: ${r$.join(", ")}`;if(Z)G1(_1("playbook clean",!1,null,[],{code:"INVALID_CHANNEL",message:z}));else await b0("Invalid Playbook channel",[`Requested: ${X}`,"",`Valid channels: ${r$.join(", ")}`].join(`
|
|
605
|
+
`));return 1}let U=X?E$.filter((z)=>z.id===X):E$,J=iQ(U,Q["dry-run"]===!0),Y={channelsCleaned:U.map((z)=>z.id),filesRemoved:J};if(Z)return G1(_1("playbook clean",!0,Y,[],null)),0;let W=Q["dry-run"]===!0?" (dry run)":"",_=U.length===1?"":"s",G=J.length===1?"":"s";return ET.success(`Cleaned ${U.length} channel${_}${W}: ${J.length} file${G} removed \uD83C\uDF89`),0}function $E($,Q,Z){return[...$.map((X)=>({value:X.key,label:X.label,hint:X.hint()})),{value:U8.SAVE,label:Q?"Save & exit *":"Save & exit",hint:Z?"creates config":"updates config"},{value:U8.DISCARD,label:"Exit without saving",hint:Q?"changes will be lost":""}]}async function QE($,Q,Z,X,U,J,Y,W){let{outro:_,log:G,isCancel:z}=Y;if(z($))return _("Cancelled \u2014 no changes saved."),0;if($===U8.DISCARD){if(J.value)G.warn("Changes discarded.",W("warn"));return _("Exited without saving."),0}if($===U8.SAVE){let V=X(Z);return G.success(V,W("success")),_(`${U??"Done."} \uD83C\uDF89`),0}let H=Q.find((V)=>V.key===$);if(H){if(await H.run()!==!1)J.value=!0}return}async function ZE($){let{title:Q,items:Z,onSave:X,isNew:U,outroAfterSave:J}=$,Y=await import("@clack/prompts"),{brandLogOptions:W}=await Promise.resolve().then(() => (D(),p0)),{intro:_,select:G,log:z}=Y;if(_(Q),!U)z.info("Editing existing config \u2014 choose what to change.",W("info"));let H={value:!1};for(;;){let V=$E(Z,H.value,U),O=await G({message:"What do you want to configure?",options:V}),K=await QE(O,Z,U,X,J,H,Y,W);if(K!==void 0)return K}}function UE($){let Q=Object.entries($).filter(([,Z])=>Z).map(([Z])=>Z);return Q.length===0?"none":Q.join(", ")}function WJ($){return $.length===0?"none":$.join(", ")}async function JE($){let Q=process.cwd(),Z=!N2(Q),X;try{X=Z?Z8():w2(Q)}catch{X=Z8()}let{multiselect:U,text:J,isCancel:Y}=await import("@clack/prompts");return ZE({title:"Playbook config",isNew:Z,items:[{key:"channels",label:"AI channels",hint:()=>UE(X.playbook.channels),run:async()=>{let W=Q8(X).filter((z)=>r$.includes(z)),_=await U({message:"Select AI assistants to enable in this repo:",options:E$.map((z)=>({value:z.id,label:z.displayName,hint:z.id})),initialValues:W});if(Y(_))return!1;let G={};for(let z of r$)G[z]=_.includes(z);X={...X,playbook:{...X.playbook,channels:G}}}},{key:"sources",label:"Source paths",hint:()=>WJ(X.playbook.sources),run:async()=>{let W=await J({message:"Source paths to scan for Playbook .md files (comma-separated):",placeholder:"docs",initialValue:X.playbook.sources.join(", ")||"docs",validate:(_)=>{if(!_?.trim())return"At least one source path is required."}});if(Y(W))return!1;X={...X,playbook:{...X.playbook,sources:String(W).split(",").map((_)=>_.trim()).filter(Boolean)}}}}],onSave:()=>{Cj(Q,X);let W=Q8(X);return`sumr.yaml ${Z?"created":"updated"} \u2014 ${W.length} channel${W.length===1?"":"s"} enabled, sources: ${WJ(X.playbook.sources)}`},outroAfterSave:"Run `sumr playbook sync` to generate AI tool files."})}function AE($){let Q=BE.exec($);if(!Q)return{meta:{},body:$.trim()};let[,Z="",X=""]=Q;return{meta:RE(Z),body:X.trim()}}function TE($,Q){let Z=[],X=Q;while(X<$.length){let J=rQ($,X).trim();if(!J.startsWith("-"))break;Z.push(J.slice(1).trim()),X+=1}return{items:Z,next:X}}function EE($,Q,Z,X,U){let J=DE(Q);if(Z.startsWith("["))return $[J]=AY(Z),U;let{items:Y,next:W}=TE(X,U);return $[J]=Y,W}function LY($,Q){let Z=[],X=Q;while(X<$.length){let U=rQ($,X);if(!U.trim()){X+=1;continue}if(!U.match(/^\s+/))break;let J=U.trim();if(J.startsWith("#")){X+=1;continue}let Y=J.indexOf(":");if(Y===-1){X+=1;continue}Z.push({key:J.slice(0,Y).trim(),value:J.slice(Y+1).trim(),indent:U.match(/^(\s+)/)?.[1]?.length??0}),X+=1}return{entries:Z,next:X}}function CE($,Q,Z){let{entries:X,next:U}=LY(Q,Z),J="";for(let{key:Y,value:W,indent:_}of X)if(_<=2)J=Y,$[J]={};else if(J){let G=$[J];if(G)G[Y]=MY(W)}return U}function SE($,Q,Z,X){let U={};$[Q]=U;let{entries:J,next:Y}=LY(Z,X);for(let W of J)U[W.key]=MY(W.value);return Y}function FE($,Q,Z){let X=Object.keys(Q).length>0,U=Object.keys(Z).length>0;if(!X&&!U)return;let J={...Q};for(let[Y,W]of Object.entries(Z))J[Y]={...NE(J,Y),...W};$.channels=J}function IE($,Q,Z,X,U){let{result:J,legacyChannels:Y,nativeChannels:W}=$;if(ME.has(Q))return EE(J,Q,Z,X,U);if(Q===N0.REVIEW)return J.review=Z===PQ.TRUE,U;if(Q===N0.CHANNELS)return CE(Y,X,U);if(qE.has(Q))return SE(W,Q,X,U);if(Q===N0.ORDER||Q===N0.TIMEOUT){let _=Number(Z);if(!Number.isNaN(_))J[Q]=_;return U}if(jE.has(Q))J[Q]=oQ(Z);return U}function DE($){if($===N0.TEAM_MEMBER)return b1.TEAM_MEMBERS;return $}function RE($){let Q={result:{},legacyChannels:{},nativeChannels:{}},Z=$.split(/\r?\n/),X=0;while(X<Z.length){let U=rQ(Z,X);if(X+=1,!U.trim()||U.trimStart().startsWith("#"))continue;let J=U.indexOf(":");if(J===-1)continue;let Y=U.slice(0,J).trim(),W=U.slice(J+1).trim();X=IE(Q,Y,W,Z,X)}return FE(Q.result,Q.legacyChannels,Q.nativeChannels),Q.result}function AY($){return($.match(/^\[(.*?)\]/)?.[1]??$.replace(/^\[/,"").replace(/\]$/,"")).split(",").map((Z)=>oQ(Z.trim())).filter(Boolean)}function rQ($,Q){let Z=$[Q];if(Z===void 0)return LE;return Z}function NE($,Q){let Z=$[Q];if(Z===void 0)return{};return Z}function MY($){if($.startsWith("["))return AY($);if($===PQ.TRUE)return!0;if($===PQ.FALSE)return!1;let Q=Number($);if($!==""&&!Number.isNaN(Q))return Q;return oQ($)}function oQ($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function yE($){if($&&jY.has($))return $;return}function vE($){if($&&TY.has($))return $;return}function xE($){if($&&EY.has($))return $;return}function gE($){if(!$?.length)return;let Q=$.filter((Z)=>CY.has(Z));return Q.length>0?Q:void 0}function hE($){let Q=[];if($.modelTier&&!jY.has($.modelTier))Q.push({field:"modelTier",value:$.modelTier,allowed:wE});if($.effort&&!TY.has($.effort))Q.push({field:"effort",value:$.effort,allowed:PE});if($.access&&!EY.has($.access))Q.push({field:"access",value:$.access,allowed:bE});for(let Z of $.tools??[])if(!CY.has(Z))Q.push({field:"tools",value:Z,allowed:kE});return Q}function mE($){for(let[Q,Z]of Object.entries(dE))if($.endsWith(Q))return Z;return}function lE($,Q){let Z=[];for(let X of $){let U=OE(X);if(!WE(U)){Q.push(`Source path not found, skipping: ${Z0(U)}`);continue}SY(U,Z,Q)}return Z}function pE($,Q,Z,X,U){return{name:$.name,title:$.title,description:$.description,category:$.category??mE(Z),framework:$.framework,tech:$.tech,guide:$.guide,insight:$.insight,topic:$.topic,teamMembers:$.teamMembers,review:$.review,target:$.target,event:$.event,matcher:$.matcher,statusMessage:$.statusMessage,label:$.label,when:$.when,order:$.order,timeout:$.timeout,modelTier:yE($.modelTier),effort:vE($.effort),access:xE($.access),tools:gE($.tools),invalidAgentFields:hE($),tags:$.tags??fE,channels:$.channels,body:Q,sourcePath:Z,source:X,module:U,references:[]}}function cE($,Q,Z,X){let U=new Map,J=[];for(let Y of $){let W;try{W=GE(Y,"utf8")}catch(O){X.push(`Could not read file, skipping: ${Z0(Y)} \u2014 ${O instanceof Error?O.message:String(O)}`);continue}let{meta:_,body:G}=AE(W);if(!oE(_))continue;let z=_.name,H=Buffer.byteLength(G,"utf8");if(H>uE)X.push(`Topic "${z}" exceeds recommended 64 KB (${Math.round(H/1024)} KB) \u2014 consider splitting it`);let V=U.get(z);if(V)throw Error(`Duplicate topic name "${z}" found:
|
|
606
|
+
${Z0(V)}
|
|
607
|
+
${Z0(Y)}
|
|
605
608
|
|
|
606
|
-
Rename one of them or set a unique "name:" in frontmatter.`);U.set(H,G),W.push(Mj(Y,z,G,Q,Z))}if(J>0)X.push(`Skipped ${J} Markdown file${J===1?"":"s"} without Playbook frontmatter (name, title, description).`);return W}function Tj($){let Q=new Map;for(let Z of $){let X=Y6(Z.sourcePath),U=Q.get(X);if(U){U.push(Z);continue}Q.set(X,[Z])}return Q}function jj($,Q){let Z=new Map;for(let X of $){let U=Y6(X.sourcePath);if(!Q.has(U))continue;let W=Z.get(U);if(!W)Z.set(U,X.sourcePath);else{let J=ZW(W);if(ZW(X.sourcePath)===UW&&J!==UW)Z.set(U,X.sourcePath)}}return Z}function Sj($,Q,Z){for(let[X,U]of $)if(!Q.some((J)=>Y6(J.sourcePath)===X))for(let J of U)Z.push(`Orphan reference "${J.name}" in ${X} \u2014 no main doc found, skipped`)}function w0($,Q={}){let Z=[],X=Q.source??r$.LOCAL,U=Aj($,Z),W=Ej(U,X,Q.module,Z),J=W.filter((H)=>H.category===XW),G=W.filter((H)=>H.category!==XW),_=Tj(J),Y=jj(G,_),z=G.map((H)=>{let V=Y6(H.sourcePath);if(Y.get(V)!==H.sourcePath)return H;let O=_.get(V);if(!O||O.length===0)return H;let K=[...O].sort((L,q)=>(L.order??Number.MAX_SAFE_INTEGER)-(q.order??Number.MAX_SAFE_INTEGER));return{...H,references:K}});return Sj(_,G,Z),z.sort((H,V)=>H.name.localeCompare(V.name)),{topics:z,warnings:Z}}function HJ($,Q,Z){let X;try{X=cT($)}catch(U){Z.push(`Could not read directory ${$}: ${U instanceof Error?U.message:String(U)}`);return}for(let U of X){let W=rT($,U),J;try{J=iT(W)}catch{Z.push(`Could not stat file, skipping: ${W}`);continue}if(J.isDirectory())HJ(W,Q,Z);else if(J.isFile()&&U.endsWith(".md"))Q.push(W)}}function Cj($){return Boolean($.name?.trim()&&$.title?.trim()&&$.description?.trim())}function KJ($,Q=[]){if(!bj($))return;try{let Z=JSON.parse(kj($,"utf8"));if(!i7(Z)){Q.push(`Ignoring invalid package.json at ${$}: expected a JSON object.`);return}return{name:typeof Z.name==="string"?Z.name:void 0,sumr:Z.sumr}}catch(Z){let X=Z instanceof Error?Z.message:"unknown parse error";Q.push(`Ignoring invalid package.json at ${$}: ${X}`);return}}function vj($){return $?.startsWith("@sumr/")===!0}function i7($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function xj($,Q,Z,X){if($===void 0)return[];if(!Array.isArray($)||$.some((U)=>typeof U!=="string"))return X.push(`Ignoring invalid packages filter for playbook resource "${Z}" in ${Q}.`),null;return $}function gj($,Q,Z,X){if(V7(Q)){X.push(`Ignoring unsafe absolute playbook resource path in ${Z}: ${Q}`);return}let U=yj($,Q),W=JW($,U);if(W===GW||W.startsWith(_W)||V7(W)){X.push(`Ignoring unsafe playbook resource path in ${Z}: ${Q}`);return}try{if(!Pj(U).isDirectory()){X.push(`Ignoring missing playbook resource directory in ${Z}: ${Q}`);return}let J=WW($),G=WW(U),_=JW(J,G);if(_===GW||_.startsWith(_W)||V7(_)){X.push(`Ignoring unsafe playbook resource path in ${Z}: ${Q}`);return}return G}catch{X.push(`Ignoring missing playbook resource directory in ${Z}: ${Q}`);return}}function hj($,Q){if($.length===0)return!0;if(!Q)return!1;return $.includes(Q)}function uj($,Q,Z,X,U,W){if(!i7($)){W.push(`Ignoring invalid playbook resource entry in ${Z}.`);return}let J=typeof $.label==="string"?$.label.trim():"",G=typeof $.path==="string"?$.path.trim():"";if(!J||!G){W.push(`Ignoring invalid playbook resource entry in ${Z}.`);return}let _=xj($.packages,Z,J,W);if(_===null||!hj(_,X))return;let Y=gj(Q,G,Z,W);if(Y)U.push({label:J,root:Y,packageName:Z})}function qJ($,Q){let Z=[],X=KJ(fj($,"package.json"),Z);if(!X||typeof X.name!=="string"||!vj(X.name))return{roots:[],warnings:Z};let U=X.name;if(!i7(X.sumr))return{roots:[],warnings:Z};let W=X.sumr.playbookResources;if(W===void 0)return{roots:[],warnings:Z};if(!Array.isArray(W))return{roots:[],warnings:[...Z,`Ignoring invalid playbookResources metadata in ${U}.`]};let J=[];for(let G of W)uj(G,$,U,Q,J,Z);return{roots:J,warnings:Z}}function e8($){if(!$||!dj($))return;try{return lj($).isDirectory()?mj($):void 0}catch{return}}function D7($){let Q=e8($.root);return Q?{...$,root:Q}:void 0}function pj($){if($.packageName)return`${$.packageName}:${$.label??$.root}`;let Q=e8($.root);return Q?`path:${Q}`:void 0}function sj(){let $=process.env[nj]?.trim();if($)return y1($);return R$(Dj(),".sumr","resources","playbook")}function tj(){return R$(sj(),"current")}function ej(){let $=b0(VJ(import.meta.url));return[{label:"playbook",root:y1($,"..","..","resources")},{label:"playbook",root:y1($,"resources")}]}function $S($){let Q=y1($);for(;;){if(c7(R$(Q,"package.json")))return Q;let Z=b0(Q);if(Z===Q)return;Q=Z}}function QS($){return $.length-$.trimStart().length}function Z0($){let Q=$.trim();if(Q.startsWith('"')&&Q.endsWith('"')||Q.startsWith("'")&&Q.endsWith("'"))return Q.slice(1,-1);return Q}function z6($){return aj.map((Q)=>R$($,Q)).find((Q)=>c7(Q))}function ZS($,Q){let Z=/^name:\s*(.+)$/.exec($);if(Z?.[1]){Q.name=Z0(Z[1]);return}let X=/^package:\s*(.+)$/.exec($);if(X?.[1])Q.packageName=Z0(X[1])}function XS($,Q,Z,X){if(/^resources:\s*\[\]\s*$/.test($)){Z.section=n.exports;return}if($===f1.RESOURCES){Z.section=n.resources;return}if(Z.section===n.resources){let U=/^-\s+(.+)$/.exec($);if(U?.[1]){X.legacyResources.push(Z0(U[1]));return}Z.section=n.exports}if($===f1.AI_RESOURCES)Z.ai={roots:[],activationMode:B2.always},X.aiResources=Z.ai,Z.section=n.aiResources,Z.aiBaseIndent=Q}function US($,Q,Z){let X=/^mode:\s*(.+)$/.exec($);if(X?.[1]){let W=Z0(X[1]);return Q.activationMode=W===B2.command?B2.command:B2.always,!0}let U=/^key:\s*(.+)$/.exec($);if(U?.[1])return Q.activationKey=Z0(U[1]),!0;if(/^initCommand:\s*(.+)$/.exec($))return!0;return Z.section=n.aiResources,!1}function WS($,Q,Z,X){if(Q<=Z.aiBaseIndent){if(Z.section=$===f1.AI_RESOURCES?n.aiResources:n.exports,$===f1.RESOURCES)Z.section=n.resources;return}if(Z.section===n.aiActivation){if(US($,X,Z))return}let U=/^module:\s*(.+)$/.exec($);if(U?.[1]){X.module=Z0(U[1]);return}if($===f1.ROOTS)return;let W=/^-\s+(.+)$/.exec($);if(W?.[1]){X.roots.push(Z0(W[1]));return}if($===f1.ACTIVATION)Z.section=n.aiActivation}function JS($,Q,Z,X){if(Q===0){Z.section=$===f1.METADATA?n.metadata:n.none;return}if(Z.section===n.metadata){ZS($,X);return}if($===f1.EXPORTS){Z.section=n.exports;return}if(Z.section===n.exports||Z.section===n.resources){XS($,Q,Z,X);return}if((Z.section===n.aiResources||Z.section===n.aiActivation)&&Z.ai)WS($,Q,Z,Z.ai)}function GS($){let Q=z6($);if(!Q)return;let Z=Fj(Q,"utf8").split(/\r?\n/),X={legacyResources:[]},U={section:n.none,aiBaseIndent:0,ai:void 0};for(let W of Z){let J=W.trim();if(!J||J.startsWith("#"))continue;JS(J,QS(W),U,X)}return X}function _S($,Q,Z){if($.activationMode===B2.always)return!0;let X=$.activationKey??$.module??Q;return S6(X,{cwd:Z})}function YS($,Q){let Z=GS($);if(!Z)return[];if(Z.aiResources&&Z.aiResources.roots.length>0){let U=Z.aiResources,W=U.module??Z.name??I7($);if(!_S(U,W,Q))return[];return U.roots.flatMap((J)=>{let G=D7({label:W,root:y1($,J),packageName:Z.packageName,module:W});return G?[G]:[]})}if((Z.packageName===ij||Z.name===rj)&&Z.legacyResources.length>0){let U=Z.name??I7($);return Z.legacyResources.flatMap((W)=>{let J=D7({label:U,root:y1($,W),packageName:Z.packageName});return J?[J]:[]})}return[]}function H6($){try{return Ij($).isDirectory()}catch{return!1}}function zS($){let Q=b0($),Z=I7(Q).startsWith("@")?new Set([Q]):new Set([Q,b0(Q)]),X=new Set;for(let U of Z){let W;try{W=n7(U)}catch{continue}for(let J of W){let G=R$(U,J);if(H6(G)&&z6(G))X.add(G)}}return[...X]}function HS($){let Q=R$($,"ai","modules"),Z;try{Z=n7(Q)}catch{return[]}return Z.map((X)=>R$(Q,X)).filter((X)=>H6(X)&&z6(X))}function VS($){let Q=R$($,"node_modules","@sumr"),Z;try{Z=n7(Q)}catch{return[]}return Z.map((X)=>R$(Q,X)).filter((X)=>H6(X)&&z6(X))}function OS($,Q){let Z=Q.split("/"),X=y1($);for(;;){let U=R$(X,"node_modules",...Z);if(H6(U)&&c7(R$(U,"package.json")))return U;let W=b0(X);if(W===X)return;X=W}}function KS($){return KJ(R$($,"package.json"))?.name}function $6($,Q,Z){if(!$||Q.has($.root))return;let X=pj($);if(X&&Z.has(X))return;if(Q.set($.root,$),X)Z.add(X)}function O7($,Q,Z,X){for(let U of $)for(let W of YS(U,Q))$6(W,Z,X)}function qS($,Q,Z,X){let U=qJ($,Q);for(let W of U.roots)$6(W,Z,X);return U.warnings}function LS($){let Q=b0(VJ(import.meta.url)),Z=$S(Q),X=KS($),U=new Map,W=new Set,J=[];if(Z)J.push(...qS(Z,X,U,W)),O7(HS(Z),$,U,W),O7([Z,...zS(Z)],$,U,W);O7(VS($),$,U,W);let G=OS($,oj);if(G){let Y=qJ(G,X);for(let z of Y.roots)$6(z,U,W);J.push(...Y.warnings)}for(let Y of ej())$6(D7(Y),U,W);return{roots:[...U.values()].sort((Y,z)=>Y.label.localeCompare(z.label)),warnings:J}}function r7($=process.cwd()){let Q=process.env[cj]?.trim(),Z=e8(Q);if(Z)return{root:Z,roots:[{label:"override",root:Z}],source:K2.dev,warnings:[]};if(Q)return{roots:[],source:K2.missing,warnings:[`SUMR Playbook resources override not found, skipping: ${y1(Q)}`]};let X=e8(tj());if(X)return{root:X,roots:[{label:"cache",root:X}],source:K2.cache,warnings:[]};let U=LS($),W=U.roots;if(W.length>0)return{root:W[0]?.root,roots:W,source:K2.bundled,warnings:U.warnings};return{roots:[],source:K2.missing,warnings:[...U.warnings,"SUMR Playbook resources were not found in cache or bundled resources."]}}function AS($,Q){let Z=[];for(let X of $.playbook.sources){let U=C7(Q,X),W=GJ(U),J=0,G=[];if(W){let _=w0([U],{source:r$.LOCAL});J=_.topics.length,G.push(..._.warnings)}Z.push({path:X,exists:W,topics:J,warnings:G})}return Z}function MS(){let $=r7(),Q=0;for(let Z of $.roots){let X=w0([Z.root],{source:r$.CORE,module:Z.module});Q+=X.topics.length}return Q}function ES($,Q,Z){let X=[];X.push(`Config: ${$.configFound?$.configPath:"not found \u2014 defaults used"}`),X.push(""),X.push("Channels:");for(let U of Q){let W=U.enabled?"enabled ":"disabled",J=U.outputExists?U.outputDir:`${U.outputDir} (not yet created)`;X.push(` ${W} ${U.displayName.padEnd(12)} ${J}`)}X.push(""),X.push("Sources:");for(let U of Z){let W=U.exists?"":" (not found)";X.push(` ${U.path}${W} \u2014 ${U.topics} local topic${U.topics===1?"":"s"}`)}if(X.push(""),X.push(`Topics: ${$.localTopics} local + ${$.coreTopics} SUMR core = ${$.totalTopics} total`),$.hideGen)X.push(""),X.push("VS Code hideGen: enabled \u2014 generated dirs added to files.exclude");return X}async function TS($){let{extras:Q}=$.args,Z=Q.json===!0,X=process.cwd(),U=C2(X),W=U?F2(X):a8(),J=o8(W),G=A$.map((K)=>({id:K.id,displayName:K.displayName,enabled:J.includes(K.id),outputDir:K.outputDir,outputExists:GJ(C7(X,K.outputDir))})),_=AS(W,X),Y=MS(),z=_.reduce((K,L)=>K+L.topics,0),H=Y+z,V={configFound:U,configPath:C7(X,"sumr.yaml"),channels:G,sources:_,coreTopics:Y,localTopics:z,totalTopics:H,hideGen:W.playbook.hideGen??!1};if(Z)return Y1(_1("playbook status",!0,V,[],null)),0;let O=ES(V,G,_);return await R0("Playbook status",O.join(`
|
|
607
|
-
`),"mauve"),0}function
|
|
609
|
+
Rename one of them or set a unique "name:" in frontmatter.`);U.set(z,Y),J.push(pE(_,G,Y,Q,Z))}return J}function nE($){let Q=new Map;for(let Z of $){let X=q8(Z.sourcePath),U=Q.get(X);if(U){U.push(Z);continue}Q.set(X,[Z])}return Q}function iE($,Q){let Z=new Map;for(let X of $){let U=q8(X.sourcePath);if(!Q.has(U))continue;let J=Z.get(U);if(!J)Z.set(U,X.sourcePath);else{let Y=_J(J);if(_J(X.sourcePath)===zJ&&Y!==zJ)Z.set(U,X.sourcePath)}}return Z}function Z0($){let Q=VE(process.cwd(),$);return Q&&!Q.startsWith("..")?Q:$}function rE($,Q,Z){for(let[X,U]of $)if(!Q.some((Y)=>q8(Y.sourcePath)===X))for(let Y of U)Z.push(`Orphan reference "${Y.name}" in ${Z0(X)} \u2014 no main doc found, skipped`)}function k0($,Q={}){let Z=[],X=Q.source??z$.LOCAL,U=lE($,Z),J=cE(U,X,Q.module,Z),Y=J.filter((H)=>H.category===GJ),W=J.filter((H)=>H.category!==GJ),_=nE(Y),G=iE(W,_),z=W.map((H)=>{let V=q8(H.sourcePath);if(G.get(V)!==H.sourcePath)return H;let O=_.get(V);if(!O||O.length===0)return H;let K=[...O].sort((q,B)=>(q.order??Number.MAX_SAFE_INTEGER)-(B.order??Number.MAX_SAFE_INTEGER));return{...H,references:K}});return rE(_,W,Z),z.sort((H,V)=>H.name.localeCompare(V.name)),{topics:z,warnings:Z}}function SY($,Q,Z){let X;try{X=_E($)}catch(U){Z.push(`Could not read directory ${Z0($)}: ${U instanceof Error?U.message:String(U)}`);return}for(let U of X){let J=HE($,U),Y;try{Y=zE(J)}catch{Z.push(`Could not stat file, skipping: ${Z0(J)}`);continue}if(Y.isDirectory())SY(J,Q,Z);else if(Y.isFile()&&U.endsWith(".md"))Q.push(J)}}function oE($){return Boolean($.name?.trim()&&$.title?.trim()&&$.description?.trim())}function DY($,Q=[]){if(!ZC($))return;try{let Z=JSON.parse(XC($,"utf8"));if(!tQ(Z)){Q.push(`Ignoring invalid package.json at ${$}: expected a JSON object.`);return}return{name:typeof Z.name==="string"?Z.name:void 0,sumr:Z.sumr}}catch(Z){let X=Z instanceof Error?Z.message:"unknown parse error";Q.push(`Ignoring invalid package.json at ${$}: ${X}`);return}}function WC($){return $?.startsWith("@sumr/")===!0}function tQ($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function _C($,Q,Z,X){if($===void 0)return[];if(!Array.isArray($)||$.some((U)=>typeof U!=="string"))return X.push(`Ignoring invalid packages filter for playbook resource "${Z}" in ${Q}.`),null;return $}function GC($,Q,Z,X){if(AQ(Q)){X.push(`Ignoring unsafe absolute playbook resource path in ${Z}: ${Q}`);return}let U=YC($,Q),J=VJ($,U);if(J===OJ||J.startsWith(KJ)||AQ(J)){X.push(`Ignoring unsafe playbook resource path in ${Z}: ${Q}`);return}try{if(!UC(U).isDirectory()){X.push(`Ignoring missing playbook resource directory in ${Z}: ${Q}`);return}let Y=HJ($),W=HJ(U),_=VJ(Y,W);if(_===OJ||_.startsWith(KJ)||AQ(_)){X.push(`Ignoring unsafe playbook resource path in ${Z}: ${Q}`);return}return W}catch{X.push(`Ignoring missing playbook resource directory in ${Z}: ${Q}`);return}}function zC($,Q){if($.length===0)return!0;if(!Q)return!1;return $.includes(Q)}function HC($,Q,Z,X,U,J){if(!tQ($)){J.push(`Ignoring invalid playbook resource entry in ${Z}.`);return}let Y=typeof $.label==="string"?$.label.trim():"",W=typeof $.path==="string"?$.path.trim():"";if(!Y||!W){J.push(`Ignoring invalid playbook resource entry in ${Z}.`);return}let _=_C($.packages,Z,Y,J);if(_===null||!zC(_,X))return;let G=GC(Q,W,Z,J);if(G)U.push({label:Y,root:G,packageName:Z})}function RY($,Q){let Z=[],X=DY(JC($,"package.json"),Z);if(!X||typeof X.name!=="string"||!WC(X.name))return{roots:[],warnings:Z};let U=X.name;if(!tQ(X.sumr))return{roots:[],warnings:Z};let J=X.sumr.playbookResources;if(J===void 0)return{roots:[],warnings:Z};if(!Array.isArray(J))return{roots:[],warnings:[...Z,`Ignoring invalid playbookResources metadata in ${U}.`]};let Y=[];for(let W of J)HC(W,$,U,Q,Y,Z);return{roots:Y,warnings:Z}}function J8($){if(!$||!VC($))return;try{return KC($).isDirectory()?OC($):void 0}catch{return}}function kQ($){let Q=J8($.root);return Q?{...$,root:Q}:void 0}function qC($){if($.packageName)return`${$.packageName}:${$.label??$.root}`;let Q=J8($.root);return Q?`path:${Q}`:void 0}function EC(){let $=process.env[LC]?.trim();if($)return v1($);return w$(tE(),".sumr","resources","playbook")}function CC(){return w$(EC(),"current")}function SC(){let $=f0(FY(import.meta.url));return[{label:"playbook",root:v1($,"..","..","resources")},{label:"playbook",root:v1($,"resources")}]}function FC($){let Q=v1($);for(;;){if(aQ(w$(Q,"package.json")))return Q;let Z=f0(Q);if(Z===Q)return;Q=Z}}function IC($){return $.length-$.trimStart().length}function X0($){let Q=$.trim();if(Q.startsWith('"')&&Q.endsWith('"')||Q.startsWith("'")&&Q.endsWith("'"))return Q.slice(1,-1);return Q}function B8($){return TC.map((Q)=>w$($,Q)).find((Q)=>aQ(Q))}function DC($,Q){let Z=/^name:\s*(.+)$/.exec($);if(Z?.[1]){Q.name=X0(Z[1]);return}let X=/^package:\s*(.+)$/.exec($);if(X?.[1])Q.packageName=X0(X[1])}function RC($,Q,Z,X){if(/^resources:\s*\[\]\s*$/.test($)){Z.section=n.exports;return}if($===y1.RESOURCES){Z.section=n.resources;return}if(Z.section===n.resources){let U=/^-\s+(.+)$/.exec($);if(U?.[1]){X.legacyResources.push(X0(U[1]));return}Z.section=n.exports}if($===y1.AI_RESOURCES)Z.ai={roots:[],activationMode:T2.always},X.aiResources=Z.ai,Z.section=n.aiResources,Z.aiBaseIndent=Q}function NC($,Q,Z){let X=/^mode:\s*(.+)$/.exec($);if(X?.[1]){let J=X0(X[1]);return Q.activationMode=J===T2.command?T2.command:T2.always,!0}let U=/^key:\s*(.+)$/.exec($);if(U?.[1])return Q.activationKey=X0(U[1]),!0;if(/^initCommand:\s*(.+)$/.exec($))return!0;return Z.section=n.aiResources,!1}function wC($,Q,Z,X){if(Q<=Z.aiBaseIndent){if(Z.section=$===y1.AI_RESOURCES?n.aiResources:n.exports,$===y1.RESOURCES)Z.section=n.resources;return}if(Z.section===n.aiActivation){if(NC($,X,Z))return}let U=/^module:\s*(.+)$/.exec($);if(U?.[1]){X.module=X0(U[1]);return}if($===y1.ROOTS)return;let J=/^-\s+(.+)$/.exec($);if(J?.[1]){X.roots.push(X0(J[1]));return}if($===y1.ACTIVATION)Z.section=n.aiActivation}function PC($,Q,Z,X){if(Q===0){Z.section=$===y1.METADATA?n.metadata:n.none;return}if(Z.section===n.metadata){DC($,X);return}if($===y1.EXPORTS){Z.section=n.exports;return}if(Z.section===n.exports||Z.section===n.resources){RC($,Q,Z,X);return}if((Z.section===n.aiResources||Z.section===n.aiActivation)&&Z.ai)wC($,Q,Z,Z.ai)}function bC($){let Q=B8($);if(!Q)return;let Z=aE(Q,"utf8").split(/\r?\n/),X={legacyResources:[]},U={section:n.none,aiBaseIndent:0,ai:void 0};for(let J of Z){let Y=J.trim();if(!Y||Y.startsWith("#"))continue;PC(Y,IC(J),U,X)}return X}function kC($,Q,Z){if($.activationMode===T2.always)return!0;let X=$.activationKey??$.module??Q;return w8(X,{cwd:Z})}function fC($,Q){let Z=bC($);if(!Z)return[];if(Z.aiResources&&Z.aiResources.roots.length>0){let U=Z.aiResources,J=U.module??Z.name??bQ($);if(!kC(U,J,Q))return[];return U.roots.flatMap((Y)=>{let W=kQ({label:J,root:v1($,Y),packageName:Z.packageName,module:J});return W?[W]:[]})}if((Z.packageName===AC||Z.name===MC)&&Z.legacyResources.length>0){let U=Z.name??bQ($);return Z.legacyResources.flatMap((J)=>{let Y=kQ({label:U,root:v1($,J),packageName:Z.packageName});return Y?[Y]:[]})}return[]}function L8($){try{return sE($).isDirectory()}catch{return!1}}function yC($){let Q=f0($),Z=bQ(Q).startsWith("@")?new Set([Q]):new Set([Q,f0(Q)]),X=new Set;for(let U of Z){let J;try{J=sQ(U)}catch{continue}for(let Y of J){let W=w$(U,Y);if(L8(W)&&B8(W))X.add(W)}}return[...X]}function vC($){let Q=w$($,"ai","modules"),Z;try{Z=sQ(Q)}catch{return[]}return Z.map((X)=>w$(Q,X)).filter((X)=>L8(X)&&B8(X))}function xC($){let Q=w$($,"node_modules","@sumr"),Z;try{Z=sQ(Q)}catch{return[]}return Z.map((X)=>w$(Q,X)).filter((X)=>L8(X)&&B8(X))}function gC($,Q){let Z=Q.split("/"),X=v1($);for(;;){let U=w$(X,"node_modules",...Z);if(L8(U)&&aQ(w$(U,"package.json")))return U;let J=f0(X);if(J===X)return;X=J}}function hC($){return DY(w$($,"package.json"))?.name}function Y8($,Q,Z){if(!$||Q.has($.root))return;let X=qC($);if(X&&Z.has(X))return;if(Q.set($.root,$),X)Z.add(X)}function MQ($,Q,Z,X){for(let U of $)for(let J of fC(U,Q))Y8(J,Z,X)}function uC($,Q,Z,X){let U=RY($,Q);for(let J of U.roots)Y8(J,Z,X);return U.warnings}function dC($){let Q=f0(FY(import.meta.url)),Z=FC(Q),X=hC($),U=new Map,J=new Set,Y=[];if(Z)Y.push(...uC(Z,X,U,J)),MQ(vC(Z),$,U,J),MQ([Z,...yC(Z)],$,U,J);MQ(xC($),$,U,J);let W=gC($,jC);if(W){let G=RY(W,X);for(let z of G.roots)Y8(z,U,J);Y.push(...G.warnings)}for(let G of SC())Y8(kQ(G),U,J);return{roots:[...U.values()].sort((G,z)=>G.label.localeCompare(z.label)),warnings:Y}}function eQ($=process.cwd()){let Q=process.env[BC]?.trim(),Z=J8(Q);if(Z)return{root:Z,roots:[{label:"override",root:Z}],source:A2.dev,warnings:[]};if(Q)return{roots:[],source:A2.missing,warnings:[`SUMR Playbook resources override not found, skipping: ${v1(Q)}`]};let X=J8(CC());if(X)return{root:X,roots:[{label:"cache",root:X}],source:A2.cache,warnings:[]};let U=dC($),J=U.roots;if(J.length>0)return{root:J[0]?.root,roots:J,source:A2.bundled,warnings:U.warnings};return{roots:[],source:A2.missing,warnings:[...U.warnings,"SUMR Playbook resources were not found in cache or bundled resources."]}}function lC($,Q){let Z=[];for(let X of $.playbook.sources){let U=wQ(Q,X),J=BY(U),Y=0,W=[];if(J){let _=k0([U],{source:z$.LOCAL});Y=_.topics.length,W.push(..._.warnings)}Z.push({path:X,exists:J,topics:Y,warnings:W})}return Z}function pC(){let $=eQ(),Q=0;for(let Z of $.roots){let X=k0([Z.root],{source:z$.CORE,module:Z.module});Q+=X.topics.length}return Q}function cC($,Q,Z){let X=[];X.push(`Config: ${$.configFound?$.configPath:"not found \u2014 defaults used"}`),X.push(""),X.push("Channels:");for(let U of Q){let J=U.enabled?"enabled ":"disabled",Y=U.outputExists?U.outputDir:`${U.outputDir} (not yet created)`;X.push(` ${J} ${U.displayName.padEnd(12)} ${Y}`)}X.push(""),X.push("Sources:");for(let U of Z){let J=U.exists?"":" (not found)";X.push(` ${U.path}${J} \u2014 ${U.topics} local topic${U.topics===1?"":"s"}`)}if(X.push(""),X.push(`Topics: ${$.localTopics} local + ${$.coreTopics} SUMR core = ${$.totalTopics} total`),$.hideGen)X.push(""),X.push("VS Code hideGen: enabled \u2014 generated dirs added to files.exclude");return X}async function nC($){let{extras:Q}=$.args,Z=Q.json===!0,X=process.cwd(),U=N2(X),J=U?w2(X):Z8(),Y=Q8(J),W=E$.map((K)=>({id:K.id,displayName:K.displayName,enabled:Y.includes(K.id),outputDir:K.outputDir,outputExists:BY(wQ(X,K.outputDir))})),_=lC(J,X),G=pC(),z=_.reduce((K,q)=>K+q.topics,0),H=G+z,V={configFound:U,configPath:wQ(X,"sumr.yaml"),channels:W,sources:_,coreTopics:G,localTopics:z,totalTopics:H,hideGen:J.playbook.hideGen??!1};if(Z)return G1(_1("playbook status",!0,V,[],null)),0;let O=cC(V,W,_);return await P0("Playbook status",O.join(`
|
|
610
|
+
`),"mauve"),0}function tC($){let Q=$.split("-").map((Z)=>`${Z.charAt(0).toUpperCase()}${Z.slice(1)}`).join(" ");return{tracker:$,label:Q,softwareNames:[Q],nouns:["task","ticket","work item","card"],defaultPrefix:"TASK",rawIssueExample:"123",normalizedIssueKey:`${$}-123`,normalizedKeyPattern:"<local-label>",referenceExamples:[`${Q} task 123`,`${$}-123`],sourceGuidance:"This tracker is recognized by Mission, but V1 treats it as a manual work source unless a native adapter is added later.",apiGuidance:`When an MCP/API gives a ${Q} ID, pass it with \`--tracker ${$} --issue <id>\`.`}}class NY{create($){let Q=$.mission?.tracker?.provider,Z=XS($.mission?.issuePrefixes??sC);if(!Q)return this.createUnconfiguredProfile(Z);let X=rC[Q]??tC(Q);return{tracker:Q,label:X.label,prefixes:Z,triggerHints:this.triggerHints(X,Z),identifierGuidance:this.identifierGuidance(X,Z),startExamples:this.startExamples(X,Z)}}createUnconfiguredProfile($){let Q=LJ($),Z=BJ($),X=oC.join(", ");return{label:"Unconfigured",prefixes:[...$],triggerHints:AJ(["tickets","issues","ticket keys","issue numbers",Q,"GitHub","GitLab","Jira","Linear","Azure DevOps","ClickUp","Asana","Trello","Notion"]),identifierGuidance:["This repo has no `mission.tracker.provider` configured.","If the user says `issue 4501`, do not assume GitHub, GitLab, Jira, Linear, or another tool. Ask for the tracker/source before creating Mission state.","If the user gives a full key such as `GH-4501`, `GL-4501`, or `PROJECT-123`, use that key directly.",`For non-native systems such as ${X}, ask for the canonical work item ID and use \`--tracker custom\` unless the repo adds a native Mission adapter later.`,Z].join(`
|
|
608
611
|
|
|
609
612
|
`),startExamples:['sumr mission start --tracker github --issue 4501 --name "Fix checkout flow"',`sumr mission start --tracker jira --issue ${$[0]??"PROJECT"}-123 --name "Add mission playbook resources"`,'sumr mission start --tracker custom --issue "release-notes-pass" --name "Prepare release notes"'].join(`
|
|
610
|
-
`)}}triggerHints($,Q){return
|
|
611
|
-
|
|
612
|
-
`)}startExamples($,Q){let Z=this.effectiveRawIssueExample($,Q),X=this.effectiveIssueKey($,Q),U=[`sumr mission start --tracker ${$.tracker} --issue ${Z} --name "Fix checkout flow"`,`sumr mission status ${X}`],
|
|
613
|
-
`)}referenceExamples($,Q){if(!
|
|
614
|
-
`),prMode:$.mission?.git?.prMode??
|
|
615
|
-
`)}function
|
|
616
|
-
`)}function
|
|
617
|
-
legacy cleanup: ${
|
|
618
|
-
resources: ${
|
|
619
|
-
`)}function
|
|
620
|
-
`)}function
|
|
621
|
-
`)}function
|
|
613
|
+
`)}}triggerHints($,Q){return AJ([...$.softwareNames,...$.nouns,...this.referenceExamples($,Q),LJ(Q)])}identifierGuidance($,Q){let Z=this.effectiveIssueKey($,Q),X=this.referenceExamples($,Q),U=ZS(Q,$.defaultPrefix),J=$.tracker===w0.CUSTOM?`Recognize these custom work references as Mission IDs or custom ID candidates: ${W8(X)}.`:`Recognize these ${$.label} references as Mission issue key \`${Z}\`: ${W8(X)}.`,Y=$.tracker===w0.CUSTOM?`${$.apiGuidance} Mission normalizes it into a safe local slug.`:`${$.apiGuidance} Mission normalizes it to \`${$.normalizedKeyPattern}\`.`;return[`This repo is configured with \`mission.tracker.provider: ${$.tracker}\` (${$.label}).`,J,$.sourceGuidance,Y,"Use the normalized key in later `status`, `plan`, `claim`, `report`, `block`, `unblock`, `close`, worktree, and branch commands.",U,BJ(Q)].join(`
|
|
614
|
+
|
|
615
|
+
`)}startExamples($,Q){let Z=this.effectiveRawIssueExample($,Q),X=this.effectiveIssueKey($,Q),U=[`sumr mission start --tracker ${$.tracker} --issue ${Z} --name "Fix checkout flow"`,`sumr mission status ${X}`],J=I2(Q)[0];if(J&&J!==X)U.push(`sumr mission start ${J} --title "Fix checkout flow"`),U.push(`sumr mission status ${J}`);return U.join(`
|
|
616
|
+
`)}referenceExamples($,Q){if(!jQ($.tracker))return $.referenceExamples;let Z=this.effectiveIssueKey($,Q),X=I2(Q).filter((J)=>J!==Z),U=$.tracker===w0.JIRA?"ticket":"issue";return[Z,...X,`${$.label} ${U} ${Z}`,$.tracker===w0.JIRA?`story ${Z}`:`cycle issue ${Z}`]}effectiveRawIssueExample($,Q){if(jQ($.tracker)&&Q[0])return`${Q[0]}-123`;return $.rawIssueExample}effectiveIssueKey($,Q){if(jQ($.tracker)&&Q[0])return`${Q[0]}-123`;return $.normalizedIssueKey}}function eC($){let Q=new NY().create($),Z=$S($);return{MISSION_TRIGGER_HINTS:Q.triggerHints,MISSION_IDENTIFIER_GUIDANCE:Q.identifierGuidance,MISSION_START_EXAMPLES:Q.startExamples,MISSION_FLOW_PRESET:Z.preset,MISSION_FLOW_TEXT:Z.text,MISSION_FLOW_STEPS:Z.steps,MISSION_PR_MODE:Z.prMode}}function $S($){let Q=$.mission?.flow?.preset??I0.BASIC,Z=$.mission?.flow?.steps??QS(Q),X=Z.map((U)=>{let J=[];if(U.enabled===!1)J.push("skipped");if(U.advance&&U.advance!==x.AUTO)J.push(U.advance);return J.length>0?`${U.uses}(${J.join(", ")})`:U.uses}).join(" -> ");return{preset:Q,text:X,steps:Z.map((U,J)=>`${J+1}. \`${U.uses}\`${U.enabled===!1?" (disabled)":""}${U.advance?` \u2014 ${U.advance}`:""}`).join(`
|
|
617
|
+
`),prMode:$.mission?.git?.prMode??aC}}function QS($){if($===I0.PLANNING_ONLY)return[{uses:u.ISSUE_SYNC,advance:x.AUTO},{uses:u.CONTEXT_RESEARCH,advance:x.AUTO},{uses:u.PLAN_CREATE,advance:x.AUTO},{uses:u.PLAN_APPROVE,advance:x.HUMAN}];if($===I0.STANDARD_DELIVERY||$===I0.FULL_DELIVERY){let Q=[{uses:u.ISSUE_SYNC,advance:x.AUTO},{uses:u.CONTEXT_RESEARCH,enabled:$===I0.STANDARD_DELIVERY?!1:void 0,advance:x.AUTO},{uses:u.PLAN_CREATE,advance:x.AUTO},{uses:u.PLAN_APPROVE,advance:x.HUMAN},{uses:u.BRANCH_CHECK,advance:x.ASK},{uses:u.WORK_CLAIM,advance:x.AUTO},{uses:u.IMPLEMENTATION_REPORT,advance:x.MANUAL},{uses:u.REVIEW_REPORT,advance:x.MANUAL},{uses:u.VALIDATION_REPORT,advance:x.MANUAL},{uses:u.QUALITY_GATE,advance:x.MANUAL},{uses:u.PR_PREPARE,advance:x.ASK},{uses:u.PR_CREATE,advance:x.HUMAN}];if($===I0.FULL_DELIVERY)Q.push({uses:u.MISSION_CLOSE,advance:x.MANUAL});return Q}return[{uses:u.PLAN_CREATE,advance:x.AUTO},{uses:u.PLAN_APPROVE,advance:x.HUMAN},{uses:u.WORK_CLAIM,advance:x.AUTO},{uses:u.IMPLEMENTATION_REPORT,advance:x.MANUAL},{uses:u.REVIEW_REPORT,advance:x.MANUAL},{uses:u.VALIDATION_REPORT,advance:x.MANUAL},{uses:u.MISSION_CLOSE,advance:x.MANUAL}]}function jQ($){return $===w0.JIRA||$===w0.LINEAR}function BJ($){if($.length===0)return"No repo-specific ticket prefixes are configured.";let Q=W8(I2($));return[`Repo ticket prefixes configured in \`sumr.yaml\`: ${$.map((Z)=>`\`${Z}\``).join(", ")}.`,`Treat these as immediate Mission trigger examples: ${Q}.`].join(" ")}function ZS($,Q){let Z=$.filter((X)=>X!==Q);if(Z.length===0)return"If the user gives a full explicit key, keep that key; do not rewrite a project/team key into another tracker namespace.";return`If the user gives a configured full key such as ${W8(I2(Z))}, keep that explicit key; do not rewrite it into the configured tracker namespace.`}function LJ($){if($.length===0)return;return`configured ticket keys ${I2($).join(", ")}`}function I2($){return $.slice(0,4).map((Q)=>`${Q}-123`)}function W8($){return $.map((Q)=>`\`${Q}\``).join(", ")}function AJ($){return $.map((Q)=>Q?.trim()).filter((Q,Z,X)=>Boolean(Q)&&X.indexOf(Q)===Z).join(", ")}function XS($){return $.map((Q)=>Q.trim().toUpperCase()).filter((Q,Z,X)=>Q.length>0&&X.indexOf(Q)===Z)}function JS($,Q){if($.length===0)return"- none";return $.map((Z)=>`- ${Z5(Z,Q)}`).join(`
|
|
618
|
+
`)}function YS($){if($.length===0)return"";return["Warnings:",...$.map((Q)=>`- ${Q}`)].join(`
|
|
619
|
+
`)}function WS($,Q,Z=[],X=[]){return $.map((U)=>V8(U)).filter((U)=>U!==void 0).map((U)=>{let J=LS(U,Q,Z),Y=J.length>0?`
|
|
620
|
+
legacy cleanup: ${J.join(", ")}`:"",W=BS(U.id,Q,X,Z),_=W.length>0?`
|
|
621
|
+
resources: ${W.join(", ")}`:"";return`- ${U.displayName}: ${U.outputDir}${_}${Y}`}).join(`
|
|
622
|
+
`)}function _S($){return`${$.length} warning${$.length===1?"":"s"}. Run with --verbose to see details.`}function GS($,Q,Z){return`Synced ${`${$} topic${$===1?"":"s"}`} across ${Q} channel${Q===1?"":"s"}${Z?" (dry run)":""} \uD83C\uDF89`}function qS($){return zS[$]??PY}function BS($,Q,Z,X){let U=[...Z,...X].map((Y)=>D2($5(Q,Q5(Q,Y)))),J=new Set;for(let Y of qS($)){let W=D2(Y);if(U.some((_)=>_===W||_.startsWith(`${W}/`)))J.add(Y)}return[...J]}function LS($,Q,Z){return AS($).filter((X)=>{let U=Q5(Q,X);return US(U)||Z.some((J)=>J===U||J.startsWith(`${U}${wY}`))})}function AS($){return $.legacyOutputDirs??PY}function MS($,Q,Z){let X=YS(Z);return["No Markdown files with Playbook frontmatter were found in the configured sources.","","Sources checked:",JS($,Q),"","Playbook topics require this frontmatter:","","---","name: my-topic","title: My Topic",'description: "What this topic covers. Use when doing X."',"---","","Reference files stay beside the main doc and set category: reference.","","Useful commands:","sumr playbook authoring --section structure","sumr playbook authoring --example overview","sumr playbook sync --dry-run",...X?["",X]:[]].join(`
|
|
623
|
+
`)}function jS($,Q){let Z=$.local.paths.length===0?"none":$.local.paths.map((U)=>Z5(U,Q)).join(", "),X=TS($.core,Q);return[`- Local docs: ${$.local.topics} topic${$.local.topics===1?"":"s"}; paths: ${Z}`,`- SUMR resources: ${$.core.topics} topic${$.core.topics===1?"":"s"}; source: ${X}`].join(`
|
|
624
|
+
`)}function TS($,Q){if($.source===TQ.bundled){let Z=ES($);if(Z.length<=1)return"bundled core resources";return`bundled core resources (${Z.map((U)=>`${U.label}: ${U.topics}`).join(", ")})`}if($.source===TQ.cache)return"local cache";if($.source===TQ.dev)return $.path?`dev override (${Z5($.path,Q)})`:"dev override";return"missing"}function ES($){return $.providers?.filter((Q)=>Q.topics>0)??HS}function Z5($,Q){let Z=D2($5(Q,Q5(Q,$)));return Z===""?KS:Z}function bY($,Q){let Z=new Map,X=new Set;for(let J of Q){let Y=D2($5($,J));if(Y===VS||Y.startsWith(OS)){X.add(Y);continue}let W=CS(Y);if(W){let G=Z.get(W.outputDir)??new Set;G.add(W.name),Z.set(W.outputDir,G);continue}let _=SS(Y);if(_){let G=Z.get(_.outputDir)??new Set;G.add(_.name),Z.set(_.outputDir,G)}}let U=[...X];for(let[J,Y]of Z)U.push(...FS(J,[...Y]));return U}function CS($){for(let Q of[".codex/agents",".claude/agents",".claude/hooks",".claude/commands",".opencode/agents"]){if(!$.startsWith(`${Q}/`))continue;let Z=$.slice(Q.length+1).split("/")[0];if(!Z||Z.startsWith("sumr-"))return null;return{outputDir:Q,name:Z}}return null}function SS($){for(let Q of E$){let Z=D2(Q.outputDir);if(!$.startsWith(`${Z}/`))continue;let X=$.slice(Z.length+1).split("/")[0];if(!X||Q.filePattern.test(X))return null;return{outputDir:Z,name:X}}return null}function FS($,Q){let Z=[];for(let[X,U]of DS(Q)){let J=IS(U);if(U.length>1){let Y=/\.[A-Za-z0-9]+$/.test(J);Z.push(`${$}/${X}*${Y?"":"/"}`)}else{let Y=/\.[A-Za-z0-9]+$/.test(J);Z.push(`${$}/${J}${Y?"":"/"}`)}}return Z}function IS($){let Q=$[0];if(Q===void 0)throw Error("Cannot generate wildcard patterns for an empty name group.");return Q}function DS($){let Q=new Map;for(let Z of $){let X=Z.indexOf("-"),U=X>=0?Z.slice(0,X+1):Z,J=Q.get(U);if(J){J.push(Z);continue}Q.set(U,[Z])}return Q}function D2($){return $.split(wY).join("/")}function wS($,Q,Z,X){let U=vY($,["cmd","use"]);if(!U)return X.push({code:"AGENTSMD_MALFORMED_COMMAND",message:`command snippet in ${Z} is missing required labels "cmd:" or "use:"; skipped.`,sourcePath:Z}),null;let J={cmd:C2(U,"cmd"),use:C2(U,"use")};return{section:I.COMMAND,body:$,attributes:Q,sourcePath:Z,command:J}}function PS($,Q,Z,X){let U=vY($,["path","purpose","when"]);if(!U)return X.push({code:"AGENTSMD_MALFORMED_MAP",message:`map snippet in ${Z} is missing required labels "path:", "purpose:", or "when:"; skipped.`,sourcePath:Z}),null;let J={path:C2(U,"path"),purpose:C2(U,"purpose"),when:C2(U,"when")};return{section:I.MAP,body:$,attributes:Q,sourcePath:Z,map:J}}function bS($,Q,Z,X,U){if($===I.COMMAND)return wS(Q,Z,X,U);if($===I.MAP)return PS(Q,Z,X,U);return{section:$,body:Q,attributes:Z,sourcePath:X}}function TJ($,Q){let Z=[],X=[],U;vQ.lastIndex=0;while((U=vQ.exec($))!==null){let J=EQ(U,1).toLowerCase(),Y=EQ(U,2),W=EQ(U,3).trim();if(!kS(J)){X.push({code:"AGENTSMD_UNKNOWN_SECTION",message:`Unknown agents-md section "${J}" \u2014 must be one of: ${U5.join(", ")}.`,sourcePath:Q});continue}let{attributes:_,attrWarnings:G}=yS(Y,Q);X.push(...G);let z=bS(J,W,_,Q,X);if(z)Z.push(z)}return{snippets:Z,warnings:X}}function kS($){return U5.includes($)}function EQ($,Q){let Z=$[Q];if(Z===void 0)return"";return Z}function C2($,Q){let Z=$[Q];if(Z===void 0)throw Error(`Missing required agents-md field "${Q}".`);return Z}function fS($,Q,Z,X){let U=$.indexOf("=");if(U===-1){X.push({code:"AGENTSMD_UNKNOWN_ATTRIBUTE",message:`Malformed attribute "${$}" in ${Z}; ignored.`,sourcePath:Z});return}let J=$.slice(0,U).toLowerCase(),Y=$.slice(U+1);if(!jJ.has(J)){X.push({code:"AGENTSMD_UNKNOWN_ATTRIBUTE",message:`Unknown attribute "${J}" in ${Z}; ignored. Supported: ${[...jJ].join(", ")}.`,sourcePath:Z});return}if(J===e6.SCOPE){if(Y)Q.scopes.push(Y);return}if(J===e6.ORDER){let W=Number(Y);if(Number.isFinite(W))Q.order=W;return}if(J===e6.ID&&Y)Q.id=Y}function yS($,Q){let Z={scopes:[],order:100},X=[],U=$.trim();if(!U)return{attributes:{scopes:Z.scopes,order:Z.order},attrWarnings:X};for(let Y of U.split(/\s+/))fS(Y,Z,Q,X);return{attributes:{scopes:Z.scopes,order:Z.order,id:Z.id},attrWarnings:X}}function vY($,Q){let Z={};for(let X of $.split(/\r?\n/)){let U=X.trim();if(!U)continue;let J=U.indexOf(":");if(J===-1)continue;let Y=U.slice(0,J).trim().toLowerCase(),W=U.slice(J+1).trim();if(Y&&!Z[Y])Z[Y]=W;else if(Y&&Z[Y])Z[Y]=`${Z[Y]} ${W}`.trim()}for(let X of Q)if(!Z[X])return null;return Z}function xY($){return $.replace(vQ,"")}function gS($,Q,Z){$.push(A8);let X=[...Z].sort();if(X.length===0)$.push("<!-- DO NOT EDIT \u2014 assembled by `bun run sync`. -->");else{$.push("<!-- DO NOT EDIT \u2014 assembled by `bun run sync` from:");for(let U of X)$.push(` - ${U}`);$.push("-->")}$.push(""),$.push(Q.path===vS?"# AGENTS.md":`# AGENTS.md \u2014 ${Q.path}`),$.push("")}function EJ($,Q,Z){if(!Q)return;$.push(Z),$.push(""),$.push(Q.body),$.push("")}function CJ($,Q,Z){if(Q.length===0)return;$.push(Z),$.push(""),Q.forEach((X,U)=>{$.push(`${U+1}. ${X.body.replace(/\n/g," ").trim()}`)}),$.push("")}function CQ($,Q,Z){if(Q.length===0)return;$.push(Z),$.push("");for(let X of Q)$.push(`- ${X.body.replace(/\n/g," ").trim()}`);$.push("")}function hS($,Q){if(Q.length===0)return;$.push("## 2. Repo map"),$.push(""),$.push("| Path | Purpose | When to read |"),$.push("|------|---------|--------------|");for(let Z of Q){let X=Z.map??{path:"",purpose:"",when:""};$.push(`| \`${X.path}\` | ${X.purpose} | ${X.when} |`)}$.push("")}function uS($,Q){if(Q.length===0)return;$.push("## 4. Common commands"),$.push(""),$.push("| Command | Use |"),$.push("|---------|-----|");for(let Z of Q){let X=Z.command??{cmd:"",use:""};$.push(`| \`${X.cmd}\` | ${X.use} |`)}$.push("")}function dS($,Q,Z){let X=[];return gS(X,$,Z),EJ(X,SJ(Q.get(I.OVERVIEW)),"## Purpose"),CJ(X,$0(Q,I.STARTUP),"## 1. Before you start (mandatory)"),hS(X,$0(Q,I.MAP)),CQ(X,$0(Q,I.RULE),"## 3. Hard rules (non-negotiable)"),uS(X,$0(Q,I.COMMAND)),CQ(X,$0(Q,I.CONVENTION),"## 5. Code conventions"),CQ(X,$0(Q,I.SECURITY),"## 6. Security"),CJ(X,$0(Q,I.CLOSEOUT),"## 7. Closeout"),EJ(X,SJ(Q.get(I.STUCK)),"## 8. If you're stuck"),`${X.join(`
|
|
622
625
|
`).trimEnd()}
|
|
623
|
-
`}function
|
|
626
|
+
`}function mS($,Q="AGENTS.md"){let Z=["<!-- DO NOT EDIT \u2014 assembled by `bun run sync`. See AGENTS.md banner for sources. -->",A8,`@${Q}`];if($.length>0){Z.push(""),Z.push("<!-- Claude-specific additions below. -->"),Z.push("");for(let X of $)Z.push(`- ${X.body.replace(/\n/g," ").trim()}`)}return`${Z.join(`
|
|
624
627
|
`).trimEnd()}
|
|
625
|
-
`}function
|
|
626
|
-
`).length}); consider splitting or pruning.`);let
|
|
627
|
-
`).length>200}function
|
|
628
|
+
`}function $0($,Q){return $.get(Q)??xS}function SJ($){if(!$||$.length===0)return;return $[0]}function hY($,Q,Z){let X={filesWritten:[],filesRemoved:[],warnings:[]},U=uY($,Q);if(X.warnings.push(...U.warnings),!U.enabled)return X;let J=U.config.targets.filter((G)=>G!==k1),Y={...U.config,targets:J},W=new Set,_=new Set;for(let G of J){let z=U.targets.get(G);if(!z)continue;let H=R2(process.cwd(),G,"AGENTS.md"),V=R2(process.cwd(),G,"CLAUDE.md");if(IJ(H,X.warnings))s(H,z.agentsMdContent,Z.dryRun),X.filesWritten.push(H),W.add(H);if(U.config.claudeMd){let O=FJ(z.sections,I.CLAUDE_ONLY),K=mS(O,"AGENTS.md");if(IJ(V,X.warnings))s(V,K,Z.dryRun),X.filesWritten.push(V),_.add(V)}else if(FJ(z.sections,I.CLAUDE_ONLY).length>0)X.warnings.push(`AGENTSMD_CLAUDE_ONLY_DROPPED: target "${G}" has claude-only snippets but claudeMd is false.`)}return X.filesRemoved.push(...WF(Y,W,_,Z.dryRun)),X}function iS($,Q){let Z=[];for(let X of $){let U=TJ(X.body,X.sourcePath);Q.push(...U.warnings),Z.push(...U.snippets);for(let J of X.references){let Y=TJ(J.body,J.sourcePath);Q.push(...Y.warnings),Z.push(...Y.snippets)}}return Z}function rS($,Q,Z){let X=new Map,U=new Map;for(let J of Q.targets)X.set(J,new Map),U.set(J,new Set);for(let J of $){let Y=ZF(J,Q,Z);if(Y.length===0){Z.push(`AGENTSMD_UNROUTABLE: snippet at ${J.sourcePath} routes to zero targets; consider adding 'scope=.' or a root '.' target.`);continue}for(let W of Y){let _=X.get(W),G=U.get(W);if(!_||!G)continue;let z=_.get(J.section);if(z)z.push(J);else _.set(J.section,[J]);G.add(J.sourcePath)}}return{snippetsByTarget:X,sourcesByTarget:U}}function aS($){for(let Q of oS){let Z=$.get(Q);if(Z)Z.sort((X,U)=>(X.attributes.order??100)-(U.attributes.order??100))}}function sS($,Q,Z){let X=Q.snippetsByTarget.get($)??new Map,U=Q.sourcesByTarget.get($)??new Set;if(U.size===0){Z.warnings.push(`AGENTSMD_EMPTY_TARGET: target "${$}" has zero snippets.`);return}if(aS(X),JF($,X,Z.warnings),!X.has(I.OVERVIEW))Z.warnings.push(`AGENTSMD_NO_OVERVIEW: target "${$}" has no overview snippet.`);let J=new Set([...U].map(UF)),Y=dS({path:$},X,J);if(YF(Y))Z.warnings.push(`AGENTSMD_LINE_BUDGET: ${R2($,"AGENTS.md")} exceeds 200 lines (${Y.split(`
|
|
629
|
+
`).length}); consider splitting or pruning.`);let W=X.get(I.STARTUP)?.length??0;if(W>5)Z.warnings.push(`AGENTSMD_STARTUP_OVERFLOW: target "${$}" has ${W} startup steps; Anthropic recommends \u2264 5.`);Z.targets.set($,{target:$,sections:X,sources:U,agentsMdContent:Y})}function uY($,Q){let Z=tS(Q),X={enabled:Z.enabled,config:Z,targets:new Map,warnings:[]};if(!Z.enabled)return X;let U=[],J=iS($,U);if(X.warnings.push(...U.map((W)=>`${W.code}: ${W.message}`)),J.length===0)return X;let Y=rS(J,Z,X.warnings);for(let W of Z.targets)sS(W,Y,X);return X}function tS($){let Q=$.playbook.agentsMd??eS,Z=Q.enabled??!0,X=Q.targets&&Q.targets.length>0?Q.targets:[k1],U=Q.claudeMd??!0,J=$.playbook.sources.length>0?$.playbook.sources:[pS];return{enabled:Z,targets:X,claudeMd:U,sources:J}}function FJ($,Q){return $.get(Q)??nS}function $F($,Q,Z){let X=new Set;for(let U of $.attributes.scopes){if(U===lS){for(let J of Q.targets)X.add(J);continue}if(!Q.targets.includes(U)){Z.push(`AGENTSMD_INVALID_SCOPE: scope="${U}" on snippet in ${$.sourcePath} is not a configured target (${Q.targets.join(", ")}); skipped for this scope.`);continue}X.add(U)}return[...X]}function QF($,Q){let Z=XF($.sourcePath,Q.sources);if(!Z)return Q.targets.includes(k1)?[k1]:[];let X;for(let U of Q.targets){if(U===k1)continue;let J=U.replace(/\/$/,""),Y=`${J}${X5}`;if(Z===J||Z.startsWith(Y)){if(!X||U.length>X.length)X=U}}if(X)return[X];return Q.targets.includes(k1)?[k1]:[]}function ZF($,Q,Z){if($.attributes.scopes.length>0)return $F($,Q,Z);return QF($,Q)}function XF($,Q){let Z=process.cwd(),X=yQ($);for(let U of Q){let J=yQ(Z,U),Y=yY(J,X);if(!Y.startsWith(cS)&&!Y.startsWith(X5)&&Y!==gY)return Y}return}function UF($){let Q=yY(process.cwd(),yQ(process.cwd(),$));if(Q===gY)return k1;return Q.split(X5).join("/")}function JF($,Q,Z){for(let X of U5){if(!NS.has(X))continue;let U=Q.get(X)?.length??0;if(U<=1)continue;if(X===I.OVERVIEW)Z.push(`AGENTSMD_DUPLICATE_OVERVIEW: target "${$}" has ${U} overview snippets; the first one wins.`);else if(X===I.STUCK)Z.push(`AGENTSMD_DUPLICATE_STUCK: target "${$}" has ${U} stuck snippets; the first one wins.`)}}function YF($){return $.split(`
|
|
630
|
+
`).length>200}function IJ($,Q){if(!kY($))return!0;let Z;try{Z=fY($,"utf8").slice(0,300)}catch{return!0}if(Z.includes(A8))return!0;return Q.push(`AGENTSMD_UNMANAGED_EXISTS: ${$} exists but lacks the "sumr-playbook:managed" marker; leaving in place. Rename or delete it to let sumr-playbook take over.`),!1}function WF($,Q,Z,X){let U=[];for(let J of $.targets){let Y=R2(process.cwd(),J,"AGENTS.md"),W=R2(process.cwd(),J,"CLAUDE.md");if(!Q.has(Y)&&DJ(Y)){if(U.push(Y),!X)MJ(Y,{force:!0})}if(!Z.has(W)&&DJ(W)){if(U.push(W),!X)MJ(W,{force:!0})}}return U}function DJ($){if(!kY($))return!1;try{return fY($,"utf8").slice(0,300).includes(A8)}catch{return!1}}function _F($,Q){let Z=new Map(Q.map((X)=>[X.id,X]));return{id:$.id,channelIds:$.channelIds,targetPath:$.targetPath,title:$.title,createItems:(X)=>GF(X,$,Z)}}function GF($,Q,Z){if(Q.appliesTo&&!Q.appliesTo($))return[];let X=[];for(let U of Q.sectionIds){let J=Z.get(U);if(!J)continue;if(J.appliesTo&&!J.appliesTo($,Q))continue;let Y=RJ(J.suggestedMarkdown,$,Q);if(!Y?.trim())continue;let W=J.exampleMarkdown?RJ(J.exampleMarkdown,$,Q):Y;X.push({id:J.id,title:J.title,detectionPatterns:[...zF(J.detectionPatterns,$,Q)],suggestedMarkdown:Y,exampleMarkdown:W?.trim()?W:Y})}return X}function RJ($,Q,Z){if(typeof $==="function")return $(Q,Z);return $}function zF($,Q,Z){if(typeof $==="function")return $(Q,Z);return $}function mY($,Q){return{topics:$,config:Q,agentsMdTargets:uY($,Q).targets}}function lY(){let $=KF();return OF.map((Q)=>_F(Q,$))}function KF(){return[i$({id:"purpose",title:"Purpose / project AI guidance",sourceSection:"overview",detectionPatterns:["## Purpose","project ai guidance","quick reference","# AGENTS.md","# CLAUDE.md"],suggestedMarkdown:R$("Purpose",["This file is starter project guidance for AI assistants working in this repository.","Keep it concise, repo-specific, and aligned with the source docs, scripts, and team practices that are current here."].join(`
|
|
628
631
|
|
|
629
|
-
`))}),
|
|
632
|
+
`))}),i$({id:"before-you-start",title:"Before you start",sourceSection:"startup",detectionPatterns:["## Before You Start","before you start","run git status --short"],suggestedMarkdown:R$("Before You Start",bJ(["Check repository status and treat existing changes as user-owned unless told otherwise.","Review the current task, nearby code, and relevant project docs before planning non-trivial changes.","Run the project setup or context command when this repository defines one.","Work on one user goal at a time and document blockers instead of guessing."]))}),{id:"mission-issue-routing",title:"Mission issue routing",appliesTo:qF,detectionPatterns:["## Mission Issue Routing","sumr mission status","sumr-mission-workflow",/Mission issue routing/i],suggestedMarkdown:R$("Mission Issue Routing",["When the user mentions an issue, ticket, work item, tracker URL, or phrase like `issue 336`, apply the generated `sumr-mission-workflow` skill before repo-specific planning docs.","Normalize the work item through this repo's `sumr.yaml` Mission config, then run `sumr mission status <issueKey>` before creating plans or editing code.",'If no Mission state exists and planning is requested, start the mission with tracker-aware input such as `sumr mission start --issue <number> --name "<title>"`, then create the durable plan with `sumr mission plan <issueKey> --from <file>` and stop for human approval unless explicitly authorized to run `sumr mission approve <issueKey>`.',"For new issue work, use Mission plan/report state instead of creating repo-local scratch planning artifacts."].join(`
|
|
630
633
|
|
|
631
|
-
`)),exampleMarkdown:
|
|
634
|
+
`)),exampleMarkdown:R$("Mission Issue Routing",["For `issue 336` in a GitHub-default repo, infer `GH-336`, run `sumr mission status GH-336`, then create or update Mission state before implementation."].join(`
|
|
632
635
|
|
|
633
|
-
`))},
|
|
634
|
-
`))}),
|
|
635
|
-
`))}),
|
|
636
|
+
`))},i$({id:"repo-map",title:"Repo map / project structure",sourceSection:"map",detectionPatterns:["## Repo Map","repo map","project structure","backend/"],suggestedMarkdown:R$("Repo Map",["Use this starter table to document the main folders and source-of-truth docs an AI assistant should check before changing them.","","| Path | Purpose | When to read |","|------|---------|--------------|","| `docs/` | Project standards, architecture notes, and product guidance. | Before planning non-trivial changes. |","| `src/` | Application or package source code. | Before editing behavior. |","| `tests/` | Regression and behavior coverage. | Before changing tested flows. |"].join(`
|
|
637
|
+
`))}),i$({id:"hard-rules",title:"Hard rules",sourceSection:"rule",detectionPatterns:["## Hard Rules","hard rules","what not to do","preserve user changes"],suggestedMarkdown:R$("Hard Rules",o6(["Preserve user-owned changes and avoid destructive file operations unless explicitly requested.","Prefer the repository patterns, helpers, and conventions already in place.","Keep generated or tool-owned files separate from hand-authored source files.","Do not invent APIs, paths, product status, or commands; verify them locally."]))}),i$({id:"common-commands",title:"Common commands",sourceSection:"command",detectionPatterns:["## Common Commands","common commands","key commands"],suggestedMarkdown:R$("Common Commands",["Document the exact commands an AI assistant should run in this repository.","Fill in the real command for each role \u2014 do not leave placeholder text in this file:","","- **Install** \u2014 the dependency install command for this repo.","- **Test** \u2014 the focused test command for changed behavior.","- **Quality gate** \u2014 the lint, format, or typecheck command to run before closeout."].join(`
|
|
638
|
+
`))}),i$({id:"code-conventions",title:"Code conventions",sourceSection:"convention",detectionPatterns:["## Code Conventions","code conventions","linting formatting","runtime and build"],suggestedMarkdown:R$("Code Conventions",o6(["Follow the style and architecture already used by the touched package or app.","Keep edits scoped to the user request and avoid opportunistic rewrites.","Use structured parsers or project utilities when they exist instead of brittle string handling.","Add or update focused tests when behavior, contracts, or generated output changes."]))}),i$({id:"security",title:"Security",sourceSection:"security",detectionPatterns:["## Security","security","never commit secrets","do not commit env files or secrets"],suggestedMarkdown:R$("Security",o6(["Do not commit secrets, tokens, credentials, local environment files, or private machine paths.","Validate file and path handling before writing, deleting, or moving user-owned content.","Avoid broad permissions, unsafe shell behavior, and unreviewed network calls.","Call out security-sensitive assumptions in the final handoff."]))}),i$({id:"closeout",title:"Closeout",sourceSection:"closeout",detectionPatterns:["## Closeout","closeout","before finishing","run relevant tests before committing"],suggestedMarkdown:R$("Closeout",bJ(["Run the relevant focused checks for the files or behavior changed.","Summarize what changed, where it changed, and which validation ran.","Mention any skipped checks, residual risk, or follow-up work clearly.","Leave unrelated user changes untouched."]))}),i$({id:"if-stuck",title:"If you're stuck",sourceSection:"stuck",detectionPatterns:["## If You're Stuck","if you're stuck","error handling","debugging posture"],suggestedMarkdown:R$("If You're Stuck","State the blocker, what you tried, and the exact error or missing context. Prefer a small question or documented assumption over guessing.")}),i$({id:"claude-specific",title:"Claude-specific additions",sourceSection:"claude-only",detectionPatterns:["## Claude Code","claude-specific","plan mode"],suggestedMarkdown:R$("Claude Code",o6(["Keep root `CLAUDE.md` concise and stable; put detailed generated resources in their channel folders.","Use Claude project memory for durable repository guidance, not temporary task status.","Avoid duplicating generated Playbook skills, agents, hooks, or commands in this file."]))})]}function i$($){return{id:$.id,title:$.title,appliesTo:(Q)=>PJ(Q,$.sourceSection).length>0,detectionPatterns:(Q)=>[...$.detectionPatterns,...LF(PJ(Q,$.sourceSection))],suggestedMarkdown:$.suggestedMarkdown,exampleMarkdown:$.suggestedMarkdown}}function wJ($){return $.agentsMdTargets.has(dY)}function qF($){return $.topics.some((Q)=>Q.name===HF)}function PJ($,Q){return $.agentsMdTargets.get(dY)?.sections.get(Q)??VF}function R$($,Q){return`## ${$}
|
|
636
639
|
|
|
637
|
-
${Q.trim()}`}function
|
|
638
|
-
`)}function
|
|
639
|
-
`)}function
|
|
640
|
+
${Q.trim()}`}function bJ($){return $.map((Q,Z)=>`${Z+1}. ${Q}`).join(`
|
|
641
|
+
`)}function o6($){return $.map((Q)=>`- ${Q}`).join(`
|
|
642
|
+
`)}function BF($){return $.body.replace(/\n/g," ").trim()}function LF($){return $.map((Q)=>BF(Q).slice(0,100)).filter((Q)=>Q.length>=20)}async function pY($){let Q={filesWritten:[],warnings:[],missing:[],accepted:[],skipped:[]},Z=CF($.specs,$.channelIds);for(let X of Z)await TF(X,$,Q);return Q}async function TF($,Q,Z){let X=jF(Q.cwd,$.targetPath),U=AF(X)?MF(X,"utf8"):"",J=$.createItems(Q.context).filter((G)=>G.suggestedMarkdown.trim().length>0),Y=SF(U,J);if(Y.length===0)return;for(let G of Y)Z.missing.push({specId:$.id,itemId:G.id,targetPath:X});if(Q.dryRun||!Q.interactive){Z.warnings.push(RF($,Y));return}let W=[];for(let G of Y)await EF(G,$,X,Q,Z,W);if(W.length===0)return;let _=DF(U,W);s(X,_,!1),Z.filesWritten.push(X)}async function EF($,Q,Z,X,U,J){let Y=FF($,await(X.confirmItem??NF)({spec:Q,item:$,targetPath:Z}));if(Y.action===q$.APPEND)J.push(Y.markdown),U.accepted.push({specId:Q.id,itemId:$.id,targetPath:Z,source:Y.source});else if(U.skipped.push({specId:Q.id,itemId:$.id,targetPath:Z}),Y.action===q$.CANCEL)U.warnings.push(`ADVISORY_FILE_CANCELLED: skipped ${$.title} for ${Q.targetPath}.`)}function CF($,Q){let Z=new Set(Q);return $.filter((X)=>X.channelIds.some((U)=>Z.has(U)))}function SF($,Q){return Q.filter((Z)=>!IF($,Z))}function FF($,Q){if(Q===!0)return{action:q$.APPEND,markdown:$.suggestedMarkdown,source:"suggested"};if(Q===!1)return{action:q$.SKIP};if(Q===q$.CANCEL)return{action:q$.CANCEL};if(Q.action===q$.APPEND){let Z=(Q.markdown??$.suggestedMarkdown).trim();if(!Z)return{action:q$.SKIP};return{action:q$.APPEND,markdown:Z,source:Q.source??(Q.markdown?"custom":"suggested")}}return{action:Q.action}}function IF($,Q){let Z=kJ($);return Q.detectionPatterns.some((X)=>{if(typeof X==="string")return Z.includes(kJ(X));return X.lastIndex=0,X.test($)})}function DF($,Q){let Z=Q.map((U)=>U.trim()).filter(Boolean).join(`
|
|
640
643
|
|
|
641
644
|
`);if(!Z)return $;if(!$)return`${Z}
|
|
642
645
|
`;let X=$.endsWith(`
|
|
@@ -646,89 +649,93 @@ ${Q.trim()}`}function IW($){return $.map((Q,Z)=>`${Z+1}. ${Q}`).join(`
|
|
|
646
649
|
`:`
|
|
647
650
|
|
|
648
651
|
`;return`${$}${X}${Z}
|
|
649
|
-
`}function
|
|
652
|
+
`}function RF($,Q){let Z=Q.map((X)=>X.title).join(", ");return`ADVISORY_FILE_MISSING: ${$.targetPath} is missing ${Q.length} suggested item${Q.length===1?"":"s"}: ${Z}. Run interactively to add accepted suggestions.`}async function NF($){let{isCancel:Q,note:Z,select:X,text:U}=await import("@clack/prompts");Z(`Example suggestion. You can append it, write your own content, or skip it.
|
|
650
653
|
|
|
651
|
-
${
|
|
654
|
+
${wF($.item.exampleMarkdown??$.item.suggestedMarkdown)}`,`Suggested ${$.spec.title}: ${$.item.title}`);let J=await X({message:`How should ${$.item.title} be handled in ${$.spec.targetPath}?`,initialValue:"skip",options:[{value:"append",label:"Append suggested content",hint:"Use the suggested Markdown exactly."},{value:"custom",label:"Write my own text",hint:"Append custom Markdown for this section."},{value:"skip",label:"Skip",hint:"Leave this file unchanged."}]});if(Q(J))return q$.CANCEL;if(J===q$.SKIP)return{action:q$.SKIP};if(J===q$.APPEND)return{action:q$.APPEND,source:"suggested"};let Y=await U({message:`Markdown to append to ${$.spec.targetPath}:`,placeholder:$.item.suggestedMarkdown,validate:(W)=>{if(!W?.trim())return"Enter Markdown to append, or cancel to skip.";return}});if(Q(Y))return"cancel";return{action:"append",markdown:Y.trim(),source:"custom"}}function wF($){let Q=$.trim().split(`
|
|
652
655
|
`);if(Q.length<=18)return $.trim();return[...Q.slice(0,18),"..."].join(`
|
|
653
|
-
`)}function
|
|
656
|
+
`)}function kJ($){return $.toLowerCase().replace(/<!--[\s\S]*?-->/g," ").replace(/[`*_>#|[\]{}()"']/g," ").replace(/[.,:;!?]/g," ").replace(/\s+/g," ").trim()}function J5($=[]){let Q=new Set,Z=[];for(let X of[...E$.flatMap((U)=>U.gitignorePatterns),...$]){if(Q.has(X))continue;Q.add(X),Z.push(X)}return Z}function eY($,Q,Z=[],X=".gitignore"){let U=rY($,X),J=J5(Z),Y=cY(U)?nY(U,"utf8"):"",W=ZW(Y,J),_=W!==Y;if(_&&!Q)iY(U,W,"utf8");return{path:U,updated:_,entries:J}}function $W($,Q,Z=[],X=[]){let U=new Map,J=vF(X,Z);if(J.length>0)U.set(PF,J);for(let Y of fF){if(!X.includes(Y.channelId))continue;let W=yF(U,Y.file);W.push(...gF(Y,Z)),U.set(Y.file,Y5(W))}return[...U].map(([Y,W])=>hF($,Q,W,Y))}function yF($,Q){let Z=$.get(Q);if(Z===void 0)return[];return[...Z]}function vF($,Q){if($.length===0)return[];let Z=J5(Q);return Y5([...tY,...$.flatMap(xF),...Z.flatMap(QW)])}function xF($){return kF[$]??bF}function QW($){let Q=$.trim();if(!Q||Q.startsWith("#"))return[];let Z=Q.startsWith("!")?Q.slice(1):Q,U=(Z.endsWith("/")?Z.slice(0,-1):Z).split("/").filter(Boolean);if(U.length<=1)return[fJ(Z)];let J=[];for(let Y=1;Y<U.length;Y+=1)J.push(`!${U.slice(0,Y).join("/")}/`);return[...J,fJ(Z)]}function gF($,Q){return Y5([...tY,...$.allowEntries,...J5(Q).filter((Z)=>$.extraEntryPrefixes.some((X)=>Z.startsWith(X))).flatMap(QW)])}function fJ($){return $.startsWith("!")?$:`!${$}`}function hF($,Q,Z,X){let U=rY($,X),J=cY(U)?nY(U,"utf8"):"",Y=ZW(J,[...Z]),W=Y!==J;if(W&&!Q)iY(U,Y,"utf8");return{path:U,updated:W,entries:[...Z]}}function ZW($,Q){let Z=uF(Q),X=new RegExp(`${SQ(oY)}\\n${SQ(aY)}[\\s\\S]*?${SQ(sY)}\\n?`,"m");if(X.test($))return $.replace(X,Z);let U=$===""||$.endsWith(`
|
|
654
657
|
`)?"":`
|
|
655
|
-
`;return`${$}${U}${Z}`}function
|
|
656
|
-
`)}function
|
|
657
|
-
`);try{let
|
|
658
|
-
`:""}`,"utf8")}function
|
|
658
|
+
`;return`${$}${U}${Z}`}function uF($){return[oY,aY,...$,sY,""].join(`
|
|
659
|
+
`)}function Y5($){let Q=new Set,Z=[];for(let X of $){if(Q.has(X))continue;Q.add(X),Z.push(X)}return Z}function SQ($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function JW($){let Q=UW($,pF);if(!XW(Q))return{path:Q,indent:2,trailingNewline:!0};let Z=mF(Q,"utf8"),X=nF(Z),U=Z.endsWith(`
|
|
660
|
+
`);try{let J=JSON.parse(Z);if(typeof J!=="object"||J===null||Array.isArray(J))return{path:Q,indent:X,trailingNewline:U};return{path:Q,settings:J,indent:X,trailingNewline:U}}catch{return{path:Q,indent:X,trailingNewline:U}}}function nF($){for(let Q of $.split(/\r?\n/)){let Z=/^(\s+)"/.exec(Q);if(Z?.[1])return Z[1].length}return 2}function YW($,Q,Z,X){lF($,`${JSON.stringify(Q,null,Z)}${X?`
|
|
661
|
+
`:""}`,"utf8")}function iF($,Q,Z){let X=!1;for(let U of Q)if(!$[U])$[U]=!0,Z.push(U),X=!0;return X}function rF($,Q,Z){let X=!1;for(let U of Q)if(U in $)delete $[U],Z.push(U),X=!0;return X}function oF($){let{path:Q,settings:Z,indent:X,trailingNewline:U}=JW($);if(!Z&&XW(Q))return;let J=aF(Z),Y=J["files.exclude"],W=Object.hasOwn(J,"files.exclude");if(W&&(typeof Y!=="object"||Y===null||Array.isArray(Y)))return;return{settingsPath:Q,nextSettings:J,existing:W?Y:{},indent:X,trailingNewline:U}}function aF($){if($===void 0)return{};return $}function sF($,Q,Z,X,U){if(Q){if(!iF($.existing,Z,X))return!1;return $.nextSettings["files.exclude"]=$.existing,!0}if(!rF($.existing,Z,U))return!1;if(Object.keys($.existing).length===0)delete $.nextSettings["files.exclude"];else $.nextSettings["files.exclude"]=$.existing;return!0}function WW($,Q,Z,X){let U=[],J=[],Y=Q.map((_)=>_.vscodeExcludePattern).filter((_)=>typeof _==="string");if(Y.length===0)return{patternsAdded:U,patternsRemoved:J};let W=oF($);if(!W)return{patternsAdded:U,patternsRemoved:J};if(!sF(W,Z,Y,U,J))return{patternsAdded:U,patternsRemoved:J};if(!X)dF(UW($,".vscode"),{recursive:!0}),YW(W.settingsPath,W.nextSettings,W.indent,W.trailingNewline);return{patternsAdded:U,patternsRemoved:J}}function _W($,Q){let{path:Z,settings:X,indent:U,trailingNewline:J}=JW($);if(!X)return{associationsAdded:[]};let Y=X["material-icon-theme.files.associations"],W=Object.hasOwn(X,"material-icon-theme.files.associations");if(W&&(typeof Y!=="object"||Y===null||Array.isArray(Y)))return{associationsAdded:[]};let _=W?Y:{},G=[];for(let[z,H]of Object.entries(cF)){if(z in _)continue;_[z]=H,G.push(z)}if(G.length===0)return{associationsAdded:G};if(!Q)X["material-icon-theme.files.associations"]=_,YW(Z,X,U,J);return{associationsAdded:G}}function QI($){return $I.includes($)}function OW($){return QI($.category)}function _8($){return zW.includes($.category)}function G8($){return HW.includes($.category)}function KW($){return VW.includes($.category)}function W5($){return!OW($)}function _5($,Q,Z){let X=VY(V8($),$),{dryRun:U}=Z,J=Y1(process.cwd(),X.outputDir),Y=[],W=[],_=[];g$(J,U);let G=new Set;for(let z of Q.filter(W5)){let H=x0(z,$),V=U0(H);G.add(V);let O=Y1(J,V);g$(O,U);let K=xY(H.body),{mainContent:q,sections:B}=KY(OY(H,K,$),{addResourceLinks:!0}),S=qY(H.references),R=`${K8({name:h$(H),description:H.description||H.title,metadata:nQ(H)})}
|
|
659
662
|
|
|
660
|
-
${
|
|
661
|
-
`,
|
|
662
|
-
`,U),
|
|
663
|
-
`,U),
|
|
663
|
+
${q}${S}
|
|
664
|
+
`,w=Y1(O,gQ);s(w,R,U),Y.push(w);let P=new Set([gQ]);for(let l of B){let v=`${l.name}.md`;P.add(v);let C$=Y1(O,v);s(C$,`${l.content}
|
|
665
|
+
`,U),Y.push(C$)}if(H.references.length>0){let l=Y1(O,z8);g$(l,U);for(let v of H.references){let C$=`${eF(v.sourcePath,H8)}${H8}`;P.add(`${z8}/${C$}`);let f2=Y1(l,C$);s(f2,`${v.body}
|
|
666
|
+
`,U),Y.push(f2)}}W.push(...XI(O,P,U))}W.push(...F2(J,G,X.filePattern,U));for(let z of X.legacyOutputDirs??ZI)W.push(...F2(Y1(process.cwd(),z),new Set,X.filePattern,U));return{filesWritten:Y,filesRemoved:W,warnings:_}}function XI($,Q,Z){if(!GW($))return[];let X=[];for(let U of qW($)){if(U===gQ)continue;let J=Y1($,U);if(U===z8){X.push(...UI(J,Q,Z));continue}if(!U.endsWith(H8))continue;if(Q.has(U))continue;if(X.push(J),!Z)xQ(J,{force:!0})}return X}function UI($,Q,Z){if(!GW($))return[];let X=[],U=[],J=qW($);for(let Y of J){let W=`${z8}/${Y}`,_=Y1($,Y);if(!Y.endsWith(H8)||Q.has(W)){U.push(Y);continue}if(X.push(_),!Z)xQ(_,{force:!0})}if(U.length===0){if(X.push($),!Z)xQ($,{recursive:!0,force:!0})}return X}function qW($){try{return tF($)}catch{return[]}}function C8($){return YI[$]}function BW($,Q){return C8($)?.features[Q]??!1}function VI($,Q){let Z=process.env[`SUMR_MODEL_${$.toUpperCase()}_${Q.toUpperCase()}`];return Z?.trim()?Z.trim():void 0}function H5($,Q){if(!$)return;let Z=C8(Q);if(!Z?.features.model)return;return VI(Q,$)??Z.models[$]}function OI($,Q=[]){let Z=Q.filter((U)=>$.has(U)),X=[...$].filter((U)=>!Q.includes(U)).sort();return[...Z,...X]}function KI($,Q){let Z=Q??[];return[...$&&$!==P2.FULL?GI[$]??[]:[],...Z]}function qI($,Q,Z){let X=Z??[];if(!$?.toolMap||!$.toolFormat)return!1;if(!Q&&X.length===0)return!1;if(Q===P2.FULL&&X.length===0)return!1;return!0}function BI($,Q){let Z=new Set;for(let X of Q)for(let U of $.toolMap?.[X]??[])Z.add(U);return Z}function LI($,Q){let Z={};for(let X of _I)if($.has(X))Z[X]="allow";else if(Q&&Q!==P2.FULL)Z[X]="deny";return{permission:Z}}function AI($,Q){if(Q==="claude")return[...WI];return Object.values($.toolMap??{}).flat()}function LW($,Q,Z){let X=C8($);if(!qI(X,Q,Z))return{};let U=BI(X,KI(Q,Z));if(U.size===0)return{};if(X.toolFormat==="permission")return LI(U,Q);let J=OI(U,AI(X,$));if(X.toolFormat==="array")return{tools:J};return{tools:J.join(", ")}}function MI($,Q){let Z=LW("claude",$,Q).tools;return typeof Z==="string"?Z:void 0}function jI($,Q){if(!$||!BW(Q,"sandbox"))return;return zI[$]}function TI($,Q,Z){if(!BW(Z,"reasoningEffort"))return;return $??(Q?HI[Q]:void 0)}function EI($,Q){let Z=C8($);if(!Z)return[];let X=[];for(let U of Object.keys(yJ)){if(Z.features[U])continue;for(let J of yJ[U])if(J in Q)X.push(J)}return X}function CI($){let Q={},Z=H5($.modelTier,"claude");if(Z)Q.model=Z;let X=MI($.access,$.tools);if(X)Q.tools=X;return Q}function SI($){let Q={},Z=H5($.modelTier,"codex");if(Z)Q.model=Z;let X=TI($.effort,$.modelTier,"codex");if(X)Q.model_reasoning_effort=X;let U=jI($.access,"codex");if(U)Q.sandbox_mode=U;return Q}function FI($,Q){let Z={},X=H5($.modelTier,Q);if(X)Z.model=X;return Object.assign(Z,LW(Q,$.access,$.tools)),Z}function a6($){return typeof $==="string"||typeof $==="boolean"||typeof $==="number"}function wI($){if(a6($))return!0;if(Array.isArray($))return $.every(a6);if(typeof $==="object"&&$!==null)return Object.values($).every((Q)=>a6(Q)||Array.isArray(Q)&&Q.every(a6));return!1}function MW($,Q){let Z={},X=$.channels?.[Q]??AW;for(let[U,J]of Object.entries(X)){if(U===NI)continue;if(wI(J))Z[U]=J}return Z}function PI($,Q,Z){let X=$.target?.trim()||U0($),U=DI(X),Y=`${U.replace(/\.(toml|md|yaml|yml)$/i,"")}.md`;if(X!==U)Z.push(`${Q} agent "${$.name}" target was normalized to "${Y}".`);return Y}function V5($,Q,Z){let X={filesWritten:[],filesRemoved:[],warnings:[]},U=Q.filter(_8),J=vJ(process.cwd(),$.outputDir),Y=new Set;if(U.length>0)g$(J,Z.dryRun);for(let W of U){let _=x0(W,$.channelId),G=PI(_,$.channelId,X.warnings);Y.add(G);let z=MW(_,$.channelId),H={name:h$(_),description:_.description,...$.defaultProps??AW,...FI(_,$.channelId),...z,metadata:nQ(_)},V=`${K8(H)}
|
|
664
667
|
|
|
665
|
-
${
|
|
668
|
+
${RI}
|
|
666
669
|
|
|
667
670
|
${_.body.trim()}
|
|
668
|
-
`,O=
|
|
669
|
-
`,Z.dryRun),X.filesWritten.push(U);return}let _={...
|
|
670
|
-
`,Z.dryRun),X.filesWritten.push(U)}function
|
|
671
|
-
`),U=X===-1?Z:Z.slice(0,X),
|
|
671
|
+
`,O=vJ(J,G);s(O,V,Z.dryRun),X.filesWritten.push(O)}return X.filesRemoved.push(...F2(J,Y,$.generatedFilePattern,Z.dryRun)),X}function O5(...$){return{filesWritten:$.flatMap((Q)=>Q.filesWritten),filesRemoved:$.flatMap((Q)=>Q.filesRemoved),warnings:$.flatMap((Q)=>Q.warnings)}}function yI($){return`"$CLAUDE_PROJECT_DIR"/.claude/hooks/${$}`}function xJ($){let Q={type:"command",command:yI($.fileName)};if($.topic.timeout!==void 0)Q.timeout=$.topic.timeout;if($.topic.statusMessage)Q.statusMessage=$.topic.statusMessage;let Z={hooks:[Q]};if($.topic.matcher)Z.matcher=$.topic.matcher;return Z}function vI($,Q){if(!bI($))return{};try{let Z=JSON.parse(kI($,"utf8"));if(typeof Z==="object"&&Z!==null&&!Array.isArray(Z))return Z;Q.warnings.push(".claude/settings.json is not a JSON object; preserving the file and skipping generated hook settings.");return}catch{Q.warnings.push(".claude/settings.json could not be parsed as JSON; preserving the file and skipping generated hook settings.")}return}function xI($,Q){let Z=hI($.hooks)?$.hooks:{},X={};for(let[U,J]of Object.entries(Z)){if(!Array.isArray(J))continue;let Y=[];for(let W of J){if(!K5(W))continue;let _=uI(W,Q);if(_)Y.push(_)}if(Y.length>0)X[U]=Y}return X}function gI($,Q,Z,X){let U=fI(process.cwd(),".claude","settings.json"),J=vI(U,X);if(!J)return;let Y=new Set([...Q,...$.map((G)=>G.fileName)]),W=xI(J,Y);for(let G of $){let z=W[G.event];if(z)z.push(xJ(G));else W[G.event]=[xJ(G)]}if(Object.keys(W).length===0){if("hooks"in J)delete J.hooks,s(U,`${JSON.stringify(J,null,4)}
|
|
672
|
+
`,Z.dryRun),X.filesWritten.push(U);return}let _={...J,hooks:W};s(U,`${JSON.stringify(_,null,4)}
|
|
673
|
+
`,Z.dryRun),X.filesWritten.push(U)}function K5($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function hI($){return K5($)}function uI($,Q){if(!Array.isArray($.hooks))return;let Z=$.hooks.filter((X)=>{if(!K5(X))return!0;let U=X.command;if(typeof U!=="string")return!0;return!dI(U,Q)});if(Z.length===0)return;return{...$,hooks:Z}}function dI($,Q){for(let Z of Q)if($.includes(`.claude/hooks/${Z}`))return!0;return/[./]\.claude\/hooks\/[^"'\s]+/.test($)}function iI($,Q){let Z=/```([A-Za-z0-9_-]*)\r?\n([\s\S]*?)\r?\n```/g;for(let X of $.matchAll(Z)){let U=hJ(X,1).toLowerCase();if(Q.includes(U))return{lang:U,content:hJ(X,2).trim()}}return null}function hJ($,Q){let Z=$[Q];if(Z===void 0)return"";return Z}function rI($,Q,Z){let X=`${U0($)}.${Q}`,U=$.target?.trim()||X,J=z5(U);if(J!==U)Z.push(`Claude hook "${$.name}" target was normalized to "${J}" to keep output inside the managed directory.`);return J.endsWith(`.${Q}`)?J:`${J}.${Q}`}function oI($,Q){let Z=$.trim();if(Z.startsWith("#!")){let X=Z.indexOf(`
|
|
674
|
+
`),U=X===-1?Z:Z.slice(0,X),J=X===-1?"":Z.slice(X+1).trimStart();if(J.startsWith("# Generated by SUMR Playbook"))return`${Z}
|
|
672
675
|
`;return`${U}
|
|
673
|
-
${
|
|
676
|
+
${gJ}${J}${J.endsWith(`
|
|
674
677
|
`)?"":`
|
|
675
678
|
`}`}return`${Q}
|
|
676
|
-
${
|
|
677
|
-
`}function
|
|
679
|
+
${gJ}${Z}
|
|
680
|
+
`}function CW($){return/^#!.*\r?\n# Generated by SUMR Playbook/.test($)}function aI($,Q,Z){if(!M8($))return[];let X=[];for(let U of j8($,{withFileTypes:!0})){if(!U.isFile())continue;if(Q.has(U.name))continue;let J=E8(U.name);if(!EW.has(J))continue;let Y=T$($,U.name),W;try{W=T8(Y,"utf8")}catch{continue}if(!CW(W))continue;if(X.push(Y),!Z)G5(Y,{force:!0})}return X}function sI($){let Q=new Set;if(!M8($))return Q;for(let Z of j8($,{withFileTypes:!0})){if(!Z.isFile())continue;let X=E8(Z.name);if(!EW.has(X))continue;try{if(CW(T8(T$($,Z.name),"utf8")))Q.add(Z.name)}catch{}}return Q}function tI($,Q,Z){if(!M8($))return[];let X=[];for(let U of j8($,{withFileTypes:!0})){if(!U.isFile())continue;if(Q.has(U.name))continue;if(E8(U.name)!==TW)continue;let J=T$($,U.name),Y;try{Y=T8(J,"utf8")}catch{continue}if(!eI(Y))continue;if(X.push(J),!Z)G5(J,{force:!0})}return X}function eI($){return $.includes(jW)}function $D($,Q,Z){if(!M8($))return[];let X=[];for(let U of j8($,{withFileTypes:!0})){if(!U.isFile())continue;if(Q.has(U.name))continue;if(E8(U.name)!==TW)continue;let J=T$($,U.name),Y;try{Y=T8(J,"utf8")}catch{continue}if(!Y.includes(jW))continue;if(X.push(J),!Z)G5(J,{force:!0})}return X}function QD($,Q,Z){let X=iI($.body,II);if(!X)return Z.warnings.push(`Claude hook "${$.name}" has no recognized code-fenced block (bash, sh, python, js, ts); skipped.`),null;if(!$.event?.trim())return Z.warnings.push(`Claude hook "${$.name}" is missing event frontmatter; skipped.`),null;let U=cI[X.lang],J=nI[X.lang],Y=rI($,U,Z.warnings),W=T$(process.cwd(),".claude","hooks",Y);if(s(W,oI(X.content,J),Q.dryRun),!Q.dryRun)try{JI(W,493)}catch{}return Z.filesWritten.push(W),{topic:$,fileName:Y,event:$.event}}function ZD($,Q,Z){let X=$.target?.trim()||U0($),U=z5(X),Y=`${U.replace(/\.(toml|md|yaml|yml)$/i,"")}.md`;if(X!==U)Z.warnings.push(`Claude subagent "${$.name}" target was normalized to "${Y}".`);let W=MW($,"claude"),G=`${K8({name:h$($),description:$.description,...CI($),...W})}
|
|
678
681
|
|
|
679
|
-
${
|
|
682
|
+
${mI}
|
|
680
683
|
|
|
681
684
|
${$.body.trim()}
|
|
682
|
-
`,z=
|
|
685
|
+
`,z=T$(process.cwd(),".claude","agents",Y);return s(z,G,Q.dryRun),Z.filesWritten.push(z),Y}function XD($,Q,Z){let X=$.target?.trim()||U0($),U=z5(X),Y=`${U.replace(/\.md$/i,"")}.md`;if(X!==U)Z.warnings.push(`Claude workflow "${$.name}" target was normalized to "${Y}".`);let W=$.channels?.claude??pI,_={description:$.description};for(let[V,O]of[["model","model"],["argumentHint","argument-hint"],["argument_hint","argument-hint"],["argument-hint","argument-hint"],["allowedTools","allowed-tools"],["allowed_tools","allowed-tools"],["allowed-tools","allowed-tools"]]){let K=W[V];if(typeof K==="string"&&K.trim())_[O]=K}let G=["---"];for(let[V,O]of Object.entries(_))G.push(`${V}: ${JSON.stringify(O)}`);G.push("---");let z=`${G.join(`
|
|
683
686
|
`)}
|
|
684
687
|
|
|
685
|
-
${
|
|
688
|
+
${lI}
|
|
686
689
|
|
|
687
690
|
${$.body.trim()}
|
|
688
|
-
`,H=
|
|
691
|
+
`,H=T$(process.cwd(),".claude","commands",Y);return s(H,z,Q.dryRun),Z.filesWritten.push(H),Y}function UD($,Q){let Z={filesWritten:[],filesRemoved:[],warnings:[]},X=$.map((V)=>x0(V,"claude")).filter(OW),U=X.filter(_8),J=X.filter(G8),Y=X.filter(KW);if(U.length===0&&J.length===0&&Y.length===0)return Z;g$(T$(process.cwd(),".claude"),Q.dryRun);let W=T$(process.cwd(),".claude","hooks");if(J.length>0)g$(W,Q.dryRun);if(U.length>0)g$(T$(process.cwd(),".claude","agents"),Q.dryRun);if(Y.length>0)g$(T$(process.cwd(),".claude","commands"),Q.dryRun);let _=sI(W),G=[];for(let V of J){let O=QD(V,Q,Z);if(O)G.push(O)}if(J.length>0||_.size>0)gI(G,_,Q,Z);let z=new Set;for(let V of U)z.add(ZD(V,Q,Z));let H=new Set;for(let V of Y)H.add(XD(V,Q,Z));return Z.filesRemoved.push(...aI(W,new Set(G.map((V)=>V.fileName)),Q.dryRun)),Z.filesRemoved.push(...tI(T$(process.cwd(),".claude","agents"),z,Q.dryRun)),Z.filesRemoved.push(...$D(T$(process.cwd(),".claude","commands"),H,Q.dryRun)),Z}function JD($,Q){let Z=_5("claude",$,Q),X=UD($,Q);return{filesWritten:[...Z.filesWritten,...X.filesWritten],filesRemoved:[...Z.filesRemoved,...X.filesRemoved],warnings:[...Z.warnings,...X.warnings]}}function TD($,Q,Z=!0){let X=/```([A-Za-z0-9_-]*)\r?\n([\s\S]*?)\r?\n```/g,U=[];for(let J of $.matchAll(X)){let Y=y0(J,1).toLowerCase(),W=y0(J,2);if(Q.includes(Y))return W.trim();U.push(W.trim())}return Z?U[0]??null:null}function ED($){let Q=/```([A-Za-z0-9_-]*)\r?\n([\s\S]*?)\r?\n```/g;for(let Z of $.matchAll(Q)){let X=y0(Z,1).toLowerCase();if(BD.includes(X))return{lang:X,content:y0(Z,2).trim()}}return null}function y0($,Q){let Z=$[Q];if(Z===void 0)return"";return Z}function FW($,Q,Z){let X=`${U0($)}.${Q}`,U=$.target?.trim()||X,J=KD(U);if(J!==U)Z.push(`Codex resource "${$.name}" target was normalized to "${J}" to keep output inside the managed directory.`);return J.endsWith(`.${Q}`)?J:`${J}.${Q}`}function CD($=process.cwd()){let Q=SD($);return{syncCommand:Q,tomlHeader:`# Generated by SUMR Playbook. Edit the source doc and run \`${Q}\`.
|
|
689
692
|
`,scriptHeader:`# Generated by SUMR Playbook. Edit the source doc and run \`${Q}\`.
|
|
690
693
|
`,markdownHeader:`<!-- Generated by SUMR Playbook. Edit the source doc and run \`${Q}\`. -->
|
|
691
|
-
`}}function
|
|
694
|
+
`}}function SD($){let Q=qD($,"package.json");if(!VD(Q))return s6;try{let Z=JSON.parse(OD(Q,"utf8"));if(!dJ(Z)||!dJ(Z.scripts))return s6;let X=Z.scripts.sync;if(typeof X==="string"&&jD.test(X))return LD}catch{return s6}return s6}function dJ($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function FD($,Q){let Z=$.trim();if(Z.startsWith(hQ))return`${Z}
|
|
692
695
|
`;return`${Q.tomlHeader}${Z}
|
|
693
|
-
`}function
|
|
696
|
+
`}function ID($,Q){let Z=$.trim();if(Z.startsWith(SW))return`${Z}
|
|
694
697
|
`;return`${Q.markdownHeader}
|
|
695
698
|
${Z}
|
|
696
|
-
`}function
|
|
699
|
+
`}function DD($,Q,Z){let X=$.trim();if(X.startsWith("#!")){let U=X.indexOf(`
|
|
697
700
|
`);if(U===-1)return`${X}
|
|
698
|
-
${Z.scriptHeader}`;let
|
|
699
|
-
`;return`${
|
|
700
|
-
${Z.scriptHeader}${
|
|
701
|
-
`}if(X.startsWith(
|
|
701
|
+
${Z.scriptHeader}`;let J=X.slice(0,U).trimEnd(),Y=X.slice(U+1).trimStart();if(Y.startsWith(hQ))return`${X}
|
|
702
|
+
`;return`${J}
|
|
703
|
+
${Z.scriptHeader}${Y}
|
|
704
|
+
`}if(X.startsWith(hQ))return`${X}
|
|
702
705
|
`;return`${Q}
|
|
703
706
|
${Z.scriptHeader}${X}
|
|
704
|
-
`}function
|
|
705
|
-
`)}function
|
|
707
|
+
`}function RD($){return $.startsWith(AD)||$.startsWith(SW)||MD.test($)}function ND($){if(!uJ.test($))return{content:$,stripped:!1};return{content:$.replace(uJ,"").trimStart(),stripped:!0}}function wD($,Q,Z,X){if($.length===0)return!1;let U=HD(process.cwd(),".codex","AGENTS.md"),J;if(GD(U)){let Y=zD(U,"utf8");if(!RD(Y))return Z.warnings.push("Codex AGENTS.md exists and is not SUMR generated; leaving it untouched and not wiring model_instructions_file."),!1;J=Y}return s(U,ID(PD($,X,J),X),Q.dryRun),Z.filesWritten.push(U),!0}function PD($,Q,Z){let X=bD($,Z),U=X.map((W)=>W.name),J=["# SUMR Codex Agent Guide","","This file is generated from SUMR Playbook team-member docs. Use it as the Codex startup routing guide for generated SUMR agents.","","## Generated Resources","","- Skills live under `.agents/skills/sumr-*`.","- Agent profiles live under `.codex/agents/*.toml`.","- Generated resources are hidden and gitignored by design; inspect them with direct paths or `rg --hidden --files .codex .agents` before reporting they are absent.",`- Treat generated files as read-only outputs; edit the Playbook source docs and run \`${Q.syncCommand}\`.`,""],Y=fD(U);if(Y)J.push("## Quality Audit Orchestration","","When the user asks for `quality code`, `check quality code`, `review quality code`, `audit code`, `audit repo`, `quality audit`, `full repo audit`, or a `quality gate` report, treat that request as authorization to activate the generated SUMR audit team. Do not require the user to write a longer prompt or name the subagents.","","First load and apply the generated audit skill when it exists: `.agents/skills/sumr-devkit-code-audit/SKILL.md`.","","Do not invent scripts or tools such as `quality:agent`; inspect `package.json` and use the real module scripts.","","Use this flow when the current runtime exposes delegation tools:","",`1. Start \`${Y.runner}\` for command evidence, standards coverage, managed-file drift, dependencies, secrets hygiene, and initial findings.`,`2. Start \`${Y.reviewer}\` in parallel for read-only source review against SUMR standards.`,`3. Send both evidence sets to \`${Y.qualityLead}\` for the final severity-based gate decision.`,"","If the runtime does not expose delegation tools, state `Delegation unavailable: <reason>` in the audit report, then run the same role sequence locally. Never silently skip the generated team.","","A quality audit is incomplete unless the report includes a `TypeScript & Engineering Principles` matrix. That matrix must cover explicit `any`, unsafe casts, interfaces/types in logic files, inline object types, TypeScript enums, string-union-only option sets, magic string comparisons, DRY duplicated concepts, file/function size, fallback chains, swallowed errors, validation boundaries, and schema/type duplication. If this evidence is missing, the gate is `Blocked`.","");J.push(IW,"","| Agent | Description |","| --- | --- |");for(let W of X)J.push(`| \`${W.name}\` | ${W.description} |`);return J.join(`
|
|
708
|
+
`)}function bD($,Q){let Z=$.map((J)=>({name:h$(J),description:yD(J.description)})),X=new Set(Z.map((J)=>J.name)),U=kD(Q).filter((J)=>!X.has(J.name));return[...Z,...U]}function kD($){if(!$)return[];let Q=$.indexOf(IW);if(Q===-1)return[];let Z=$.slice(Q).split(/\r?\n/),X=[];for(let U of Z){let J=U.match(/^\|\s*`([^`]+)`\s*\|\s*(.*?)\s*\|\s*$/);if(!J)continue;let Y=y0(J,1).trim(),W=y0(J,2).trim();if(!Y||!W)continue;X.push({name:Y,description:W})}return X}function fD($){let Q=FQ($,"code-audit-runner"),Z=FQ($,"codebase-reviewer"),X=FQ($,"quality-lead");if(!Q||!Z||!X)return null;return{runner:Q,reviewer:Z,qualityLead:X}}function FQ($,Q){return $.find((Z)=>Z===Q||Z===`sumr-${Q}`||Z.endsWith(`-${Q}`))}function yD($){return $.replace(/\|/g,"\\|").replace(/\r?\n/g," ").trim()}function v0($){return JSON.stringify($)}function xD($){return/^[A-Za-z0-9_-]+$/.test($)?$:JSON.stringify($)}function RW($){if(typeof $==="string")return v0($);if(typeof $==="boolean")return String($);if(typeof $==="number"&&Number.isFinite($))return String($);if(Array.isArray($)){let Q=$.map(RW);if(Q.some((Z)=>Z===null))return null;return`[${Q.join(", ")}]`}return null}function gD($){if($.includes("'''"))return v0($);return`'''
|
|
706
709
|
${$}
|
|
707
|
-
'''`}function
|
|
710
|
+
'''`}function uD($,Q,Z){for(let[X,U]of hD){let J=Q[X];if(Z.add(X),typeof J==="string"&&J.trim())$.push(`${U} = ${v0(J)}`)}}function dD($,Q,Z){for(let[X,U]of Object.entries(Q)){if(Z.has(X))continue;let J=RW(U);if(J===null)continue;$.push(`${xD(X)} = ${J}`)}}function mD($,Q){let Z={...SI($),...$.channels?.codex??vD},X=typeof Z.name==="string"&&Z.name.trim()?Z.name:void 0,U=typeof Z.description==="string"&&Z.description.trim()?Z.description:void 0,J=[`${Q.trimEnd()}`,`name = ${v0(X??h$($))}`,`description = ${v0(U??$.description)}`],Y=new Set(["name","description","developer_instructions"]);return uD(J,Z,Y),dD(J,Z,Y),J.push(`developer_instructions = ${gD($.body.trim())}`),`${J.join(`
|
|
708
711
|
`)}
|
|
709
|
-
`}function
|
|
710
|
-
`).trimEnd()}function
|
|
711
|
-
`).trimEnd()}function
|
|
712
|
-
`,Z.dryRun),X.filesWritten.push(
|
|
713
|
-
`:`${
|
|
714
|
-
`;
|
|
712
|
+
`}function lD($,Q,Z){let X=new RegExp(`^\\s*${O8(Q)}\\s*=`),U=$.findIndex((W)=>X.test(W));if(U>=0){$[U]=`${Q} = ${Z}`;return}let J=$.findIndex((W)=>/^\s*\[[^\]]+\]\s*(?:#.*)?$/.test(W));if(J===-1){if($.length>0&&$[$.length-1]?.trim())$.push("");$.push(`${Q} = ${Z}`);return}let Y=[`${Q} = ${Z}`];if(J>0&&$[J-1]?.trim())Y.push("");$.splice(J,0,...Y)}function pD($,Q){let Z=$.split(/\r?\n/);if(wW(Z))Z.pop();for(let[X,U]of Object.entries(Q))lD(Z,X,U);return Z.join(`
|
|
713
|
+
`).trimEnd()}function cD($,Q){let Z=new RegExp(`^\\s*\\[${O8(Q)}\\]\\s*(?:#.*)?$`),X=$.findIndex((U)=>Z.test(U));if(X===-1){if($.length>0&&$[$.length-1]?.trim())$.push("");X=$.length,$.push(`[${Q}]`)}return X}function nD($,Q){let Z=/^\s*\[[^\]]+\]\s*(?:#.*)?$/;for(let X=Q+1;X<$.length;X+=1)if(Z.test(NW($,X)))return X;return $.length}function iD($,Q,Z,X){let U=new Set(X),J=Z;for(let Y=Q+1;Y<J;Y+=1){let _=NW($,Y).match(/^\s*([A-Za-z0-9_-]+)\s*=/)?.[1];if(_&&U.has(_))$.splice(Y,1),Y-=1,J-=1}return J}function rD($,Q,Z,X){let U=Z;for(let[J,Y]of Object.entries(X)){let W=new RegExp(`^\\s*${O8(J)}\\s*=`),_=$.slice(Q+1,U).findIndex((G)=>W.test(G));if(_>=0)$[Q+1+_]=`${J} = ${Y}`;else $.splice(U,0,`${J} = ${Y}`),U+=1}}function mJ($,Q,Z,X=[]){let U=$.split(/\r?\n/);if(wW(U))U.pop();let J=cD(U,Q),Y=nD(U,J),W=iD(U,J,Y,X);return rD(U,J,W,Z),U.join(`
|
|
714
|
+
`).trimEnd()}function NW($,Q){let Z=$[Q];if(Z===void 0)return DW;return Z}function wW($){return $.length===1&&$[0]===DW}function sD($,Q,Z,X){let U=ED($.body);if(!U)return Z.warnings.push(`Codex hook "${$.name}" has no recognized code-fenced block (bash, sh, python, js, ts); skipped.`),null;if(!$.event?.trim())return Z.warnings.push(`Codex hook "${$.name}" is missing event frontmatter; skipped.`),null;let J=oD[U.lang],Y=aD[U.lang],W=FW($,J,Z.warnings),_=b2(process.cwd(),".codex","hooks",W);if(s(_,DD(U.content,Y,X),Q.dryRun),!Q.dryRun)YD(_,493);return Z.filesWritten.push(_),{fileName:W,event:$.event}}function tD($){return`"$(git rev-parse --show-toplevel)/.codex/hooks/${$}"`}function eD($,Q,Z,X){if($.length===0)return;let U={};for(let{topic:Y,fileName:W,event:_}of Q){let G={hooks:[{type:"command",command:tD(W),...Y.timeout!==void 0?{timeout:Y.timeout}:{},...Y.statusMessage?{statusMessage:Y.statusMessage}:{}}]};if(Y.matcher)G.matcher=Y.matcher;let z=U[_];if(z)z.push(G);else U[_]=[G]}let J=b2(process.cwd(),".codex","hooks.json");s(J,`${JSON.stringify({hooks:U},null,2)}
|
|
715
|
+
`,Z.dryRun),X.filesWritten.push(J)}function $R($,Q,Z,X,U,J){if(!$&&!Q&&!Z)return;let Y=b2(process.cwd(),".codex","config.toml"),W=WD(Y)?_D(Y,"utf8"):"",_=W.trim().length>0,G=ND(W),z=G.stripped;if(W=G.content,W.trim()===J.tomlHeader.trim())W="";if(Q)W=mJ(W,"features",{hooks:"true"},["codex_hooks"]);if(Z)W=pD(W,{model_instructions_file:v0("AGENTS.md")});if($)W=mJ(W,"agents",{max_threads:"6",max_depth:"1"});let H=!_||z?`${J.tomlHeader}${W.trimEnd()}
|
|
716
|
+
`:`${W.trimEnd()}
|
|
717
|
+
`;s(Y,H,X.dryRun),U.filesWritten.push(Y)}function QR($,Q,Z,X){let U=FW($,"toml",Z.warnings),J=TD($.body,["toml"],!1),Y=J?FD(J,X):mD($,X.tomlHeader),W=b2(process.cwd(),".codex","agents",U);return s(W,Y,Q.dryRun),Z.filesWritten.push(W),U}function ZR($,Q){let Z={filesWritten:[],filesRemoved:[],warnings:[]},X=CD(),U=$.map((G)=>x0(G,"codex")).filter((G)=>_8(G)||G8(G));if(U.length===0)return Z;g$(b2(process.cwd(),".codex"),Q.dryRun);let J=U.filter(_8),Y=U.filter(G8),W=[],_=wD(J,Q,Z,X);$R(J.length>0,Y.length>0,_,Q,Z,X);for(let G of J)QR(G,Q,Z,X);for(let G of Y){let z=sD(G,Q,Z,X);if(z)W.push({topic:G,...z})}return eD(Y,W,Q,Z),Z}function XR($,Q){let Z=_5("codex",$,Q),X=ZR($,Q);return{filesWritten:[...Z.filesWritten,...X.filesWritten],filesRemoved:[...Z.filesRemoved,...X.filesRemoved],warnings:[...Z.warnings,...X.warnings]}}function UR($,Q){return`${U0($)}.${Q}`}function q5($,Q,Z){let X=VY(V8($.channelId),$.channelId),{dryRun:U}=Z,J=lJ(process.cwd(),X.outputDir),Y=[],W=[];g$(J,U);let _=new Set,G=$.includeTopic??W5;for(let H of Q.filter(G)){let V=x0(H,$.channelId),O=UR(V,$.extension);_.add(O);let K=xY(V.body),{mainContent:q,sections:B}=KY(OY(V,K,$.channelId)),S=qY(V.references),M=B.map((v)=>`
|
|
715
718
|
|
|
716
|
-
${v.content}`).join(""),
|
|
719
|
+
${v.content}`).join(""),R=K8({...$.frontmatter(V),metadata:nQ(V)}),w=$.includeTitle?`
|
|
717
720
|
|
|
718
|
-
# ${V.title}`:"",
|
|
721
|
+
# ${V.title}`:"",P=`${R}${w}
|
|
719
722
|
|
|
720
|
-
${
|
|
721
|
-
`,l=
|
|
722
|
-
`)}function
|
|
723
|
+
${q}${M}${S}
|
|
724
|
+
`,l=lJ(J,O);s(l,P,U),Y.push(l)}let z=F2(J,_,X.filePattern,U);return{filesWritten:Y,filesRemoved:z,warnings:W}}function JR($,Q){return O5(q5({channelId:"copilot",extension:"md",includeTitle:!0,frontmatter:()=>({applyTo:"**"})},$,Q),V5({channelId:"copilot",outputDir:".github/agents",generatedFilePattern:/^sumr-.+\.md$/},$,Q))}function WR($,Q){return q5({channelId:"cursor",extension:"mdc",includeTitle:!1,frontmatter:(Z)=>{let X=Z.channels?.cursor??YR,U=Array.isArray(X.globs)?X.globs:[],J={description:Z.description||Z.title,alwaysApply:!1};if(U.length>0)J.globs=U;return J}},$,Q)}function _R($,Q){return O5(_5("gemini",$,Q),V5({channelId:"gemini",outputDir:".gemini/agents",generatedFilePattern:/^sumr-.+\.md$/},$,Q))}function HR($,Q){return O5(q5({channelId:"opencode",extension:"md",includeTitle:!0,includeTopic:(Z)=>W5(Z)||KW(Z),frontmatter:(Z)=>({description:Z.description||Z.title})},$,Q),V5(zR,$,Q))}function J0($,Q="Unexpected error"){if($ instanceof Error)return $.message;if(typeof $==="string"&&$.trim().length>0)return $;return Q}function VR(){return process.stdin.isTTY===!0&&process.stdout.isTTY===!0}function bW($,Q,Z){let X=Z?"to write":"written",U=Z?"to remove":"removed";return[$>0?`${$} ${X}`:"",Q>0?`${Q} ${U}`:""].filter(Boolean).join(", ")||"no changes"}function OR($,Q,Z,X,U,J,Y){let{log:W,spinner:_,logOpts:G,spinOpts:z}=Q;for(let H of X){let V=V8(H);if(!V)continue;let O=PW[H];if(!O)continue;let K=_(z("purple"));K.start(`${V.displayName}${Y}\u2026`);try{let q=O(Z,{dryRun:U});$.allWritten.push(...q.filesWritten),$.allRemoved.push(...q.filesRemoved),$.allWarnings.push(...q.warnings);let B=bW(q.filesWritten.length,q.filesRemoved.length,U);K.stop(`${V.displayName} \u2014 ${B}${J?`; target ${V.outputDir}`:""}`)}catch(q){$.hasError=!0,K.stop(`${V.displayName} \u2014 failed`),W.error(J0(q),G("error"))}}}function KR($,Q,Z,X,U,J){let{log:Y,spinner:W,logOpts:_,spinOpts:G}=Q,z=W(G("purple"));z.start(`Instruction assembly${J}\u2026`);try{let H=hY(Z,X,{dryRun:U});$.allWritten.push(...H.filesWritten),$.allRemoved.push(...H.filesRemoved),$.allWarnings.push(...H.warnings);let V=bW(H.filesWritten.length,H.filesRemoved.length,U);z.stop(`Instruction assembly \u2014 ${V}`)}catch(H){$.hasError=!0,z.stop("Instruction assembly \u2014 failed"),Y.error(J0(H),_("error"))}}async function qR($,Q,Z,X,U,J,Y){let{log:W,logOpts:_}=Q;try{let G=await pY({cwd:Y,channelIds:X,context:mY(Z,U),specs:lY(),dryRun:J,interactive:!J&&VR()});if($.allWritten.push(...G.filesWritten),$.allWarnings.push(...G.warnings),G.filesWritten.length>0)W.info(`Advisory files \u2014 updated ${G.filesWritten.length} file${G.filesWritten.length===1?"":"s"}`,_("info"))}catch(G){$.hasError=!0,W.error(J0(G,"Advisory file assistant failed"),_("error"))}}function BR($,Q,Z,X,U,J){let{spinner:Y,spinOpts:W}=Q,_=Y(W("purple"));_.start(`Ignore files${J}\u2026`);let G=bY(U,$.allWritten),z=eY(U,X,G),H=$W(U,X,G,Z),V=[z,...H],O=V.filter((K)=>K.updated).map((K)=>K.path.split(RS).pop()??K.path);for(let K of V)if(K.updated)$.allWritten.push(K.path);_.stop(O.length>0?`Ignore files \u2014 ${X?"to update":"updated"} ${O.join(", ")}`:"Ignore files \u2014 no changes")}function LR($,Q,Z,X,U,J,Y){let{log:W,spinner:_,logOpts:G,spinOpts:z}=Q;if(X){let V=E$.filter((q)=>Z.includes(q.id)),O=_(z("purple"));O.start(`VS Code settings${Y}\u2026`);let K=WW(J,V,!0,U);if(K.patternsAdded.length>0)$.allWritten.push(".vscode/settings.json"),O.stop(`VS Code settings \u2014 ${U?"to add":"added"} ${K.patternsAdded.length} exclude pattern${K.patternsAdded.length===1?"":"s"}`);else O.stop("VS Code settings \u2014 no changes")}let H=_W(J,U);if(H.associationsAdded.length>0)$.allWritten.push(".vscode/settings.json"),W.info(`VS Code icons \u2014 ${U?"to add":"added"} ${H.associationsAdded.length} Playbook file association${H.associationsAdded.length===1?"":"s"}`,G("info"))}async function AR($,Q,Z,X,U,J,Y,W){let{log:_,logOpts:G}=Q;if($.allWarnings.length>0)if(Y)for(let z of $.allWarnings)_.warn(z,G("warn"));else _.warn(_S($.allWarnings),G("warn"));if(!$.hasError){if(Y){await P0("Sources",jS(U,W));let z=WS(X,W,$.allRemoved,$.allWritten);if(z)await P0("Generated outputs",z)}_.success(GS(Z.length,X.length,J),G("success")),jR()}}async function MR($,Q,Z,X,U,J,Y,W,_){let{log:G,spinner:z}=await import("@clack/prompts"),{brandLogOptions:H,brandSpinnerOptions:V}=await Promise.resolve().then(() => (D(),p0)),O={log:G,spinner:z,logOpts:H,spinOpts:V},K={allWarnings:[...X],allWritten:[],allRemoved:[],hasError:!1},q=process.cwd(),B=U?" (dry run)":"";return OR(K,O,$,Q,U,_,B),K.allRemoved.push(...iQ(Z,U)),KR(K,O,$,W,U,B),await qR(K,O,$,Q,W,U,q),BR(K,O,Q,U,q,B),LR(K,O,Q,Y,U,q,B),await AR(K,O,$,Q,J,U,_,q),K.hasError?1:0}function jR(){S2(`
|
|
725
|
+
`)}function TR($){return{channel:$}}function ER($,Q,Z,X){for(let U of Z){let J=PW[U];if(!J)continue;try{let Y=J(Q,{dryRun:X});$.allWritten.push(...Y.filesWritten),$.allRemoved.push(...Y.filesRemoved),$.allWarnings.push(...Y.warnings)}catch(Y){$.errorResult={code:"RENDER_ERROR",message:J0(Y,"Renderer failed"),details:TR(U)}}}}function CR($,Q,Z,X){try{let U=hY(Q,Z,{dryRun:X});$.allWritten.push(...U.filesWritten),$.allRemoved.push(...U.filesRemoved),$.allWarnings.push(...U.warnings)}catch(U){$.errorResult=$.errorResult??{code:"AGENTS_MD_RENDER_ERROR",message:J0(U,"AGENTS.md renderer failed"),details:{}}}}async function SR($,Q,Z,X,U,J){try{let Y=await pY({cwd:J,channelIds:Z,context:mY(Q,X),specs:lY(),dryRun:U,interactive:!1});$.allWritten.push(...Y.filesWritten),$.allWarnings.push(...Y.warnings)}catch(Y){$.errorResult=$.errorResult??{code:"ADVISORY_FILE_ERROR",message:J0(Y,"Advisory file assistant failed"),details:{}}}}function FR($,Q,Z,X){let U=bY(X,$.allWritten),J=eY(X,Z,U),Y=$W(X,Z,U,Q),W=[J,...Y],_=[];for(let G of W)if(G.updated)$.allWritten.push(G.path),_.push(G.path);return _}function IR($,Q,Z,X,U){if(Z){let Y=E$.filter((_)=>Q.includes(_.id));if(WW(U,Y,!0,X).patternsAdded.length>0)$.allWritten.push(".vscode/settings.json")}if(_W(U,X).associationsAdded.length>0)$.allWritten.push(".vscode/settings.json")}async function DR($,Q,Z,X,U,J,Y,W){let _={allWarnings:[...X],allWritten:[],allRemoved:[],errorResult:null};ER(_,$,Q,U),_.allRemoved.push(...iQ(Z,U)),CR(_,$,W,U);let G=process.cwd();await SR(_,$,Q,W,U,G);let z=FR(_,Q,U,G);IR(_,Q,Y,U,G);let H={topicsLoaded:$.length,channelsRun:Q,filesWritten:_.allWritten,filesRemoved:_.allRemoved,ignoreFilesUpdated:z,sources:J};return G1(_1("playbook sync",_.errorResult===null,H,_.allWarnings,_.errorResult)),_.errorResult===null?0:1}function bR($,Q,Z){let X=[],U=$.slice(1);for(let J=0;J<U.length;J++){let Y=U[J],W=U[J+1];if(Y===NR&&W&&!W.startsWith("--"))X.push(W),J++;else if(Y?.startsWith(pJ))X.push(Y.slice(pJ.length))}if(X.length===0&&typeof Q.source==="string")X.push(Q.source);if(X.length>0)return{paths:X,origin:E2.EXPLICIT};if(Z)return{paths:Z.playbook.sources,origin:E2.CONFIG};return{paths:[fW],origin:E2.DEFAULT}}function kR($,Q){if($.origin===E2.DEFAULT&&!RR(kW(Q,fW)))return[];return $.paths}function fR($,Q){let Z=k0($.map((_)=>kW(Q,_)),{source:z$.LOCAL}),X=eQ(),U=[...Z.warnings,...X.warnings],J=[],Y=[];for(let _ of X.roots){let G=k0([_.root],{source:z$.CORE,module:_.module});J=[...J,...G.topics],U.push(...G.warnings),Y.push({label:yR(_),path:_.root,topics:G.topics.length})}xR(Z.topics);let W=vR([{label:"SUMR resources",topics:J,duplicatePolicy:fQ.ERROR},{label:"local sources",topics:Z.topics,duplicatePolicy:fQ.SKIP}]);return U.push(...W.warnings),{topics:W.topics,warnings:U,breakdown:{local:{paths:$,topics:Z.topics.length},core:{source:X.source,path:X.root,paths:X.roots.map((_)=>_.root),providers:Y,topics:J.length}}}}function yR($){return $.label||$.packageName||PR}function vR($){let Q=new Map,Z=[],X=[];for(let U of $)for(let J of U.topics){if(!cJ(J,U.label,Q,U.duplicatePolicy,X,qJ.TOPIC))continue;let Y=[];for(let W of J.references)if(cJ(W,U.label,Q,U.duplicatePolicy,X,qJ.REFERENCE))Y.push(W);Z.push({...J,references:Y})}return{topics:Z.sort((U,J)=>U.name.localeCompare(J.name)),warnings:X}}function xR($){let Q=gR($).filter((X)=>X.source===z$.LOCAL&&X.name.startsWith(wR));if(Q.length===0)return;let Z=Q.map((X)=>` - "${X.name}" in ${X.sourcePath}`);throw Error(`Reserved prefix "sumr-" is used in local Playbook docs:
|
|
723
726
|
${Z.join(`
|
|
724
727
|
`)}
|
|
725
728
|
|
|
726
|
-
Use unprefixed names in source docs. SUMR adds managed prefixes during generation.`)}function
|
|
729
|
+
Use unprefixed names in source docs. SUMR adds managed prefixes during generation.`)}function gR($){return $.flatMap((Q)=>[Q,...Q.references])}function cJ($,Q,Z,X,U,J){let Y=h$($),W=Z.get(Y);if(W){if(X===fQ.SKIP)return U.push(`Skipped local Playbook ${J} "${$.name}" because it already exists in ${W}.`),!1;throw Error(`Duplicate Playbook topic name "${Y}" found in ${W} and ${Q}.
|
|
727
730
|
|
|
728
|
-
Rename one of them or set a unique "name:" in frontmatter.`)}return Z.set(
|
|
729
|
-
|
|
730
|
-
`)}async function
|
|
731
|
-
`)
|
|
731
|
+
Rename one of them or set a unique "name:" in frontmatter.`)}return Z.set(Y,Q),!0}function cR($){return $.flatMap((Q)=>[Q,...Q.references])}function nR($,Q,Z){let X=h$($),U=Q.get(X);if(U)Z.push({severity:i.ERROR,code:"DUPLICATE_NAME",topic:$.name,file:$.sourcePath,message:`Duplicate topic name "${X}" \u2014 already used in ${U}`});else Q.set(X,$.sourcePath)}function iR($,Q){if($.source===z$.LOCAL&&$.name.startsWith(pR))Q.push({severity:i.ERROR,code:"RESERVED_PREFIX",topic:$.name,file:$.sourcePath,message:`Reserved prefix "sumr-" used in local topic "${$.name}". SUMR adds managed prefixes during generation.`})}function rR($,Q){let Z=Buffer.byteLength($.body,"utf8");if(Z>lR)Q.push({severity:i.WARNING,code:"TOPIC_TOO_LARGE",topic:$.name,file:$.sourcePath,message:`Topic "${$.name}" body is ${Math.round(Z/1024)} KB \u2014 consider splitting it (soft cap: 64 KB)`})}function oR($,Q){if($.category!==vW)return;if(!$.label)Q.push({severity:i.WARNING,code:"REFERENCE_MISSING_LABEL",topic:$.name,file:$.sourcePath,message:`Reference "${$.name}" is missing required frontmatter field: label`});if(!$.when)Q.push({severity:i.WARNING,code:"REFERENCE_MISSING_WHEN",topic:$.name,file:$.sourcePath,message:`Reference "${$.name}" is missing required frontmatter field: when`});if($.order===void 0)Q.push({severity:i.WARNING,code:"REFERENCE_MISSING_ORDER",topic:$.name,file:$.sourcePath,message:`Reference "${$.name}" is missing required frontmatter field: order`})}function aR($,Q){if(G8($)&&!$.event)Q.push({severity:i.ERROR,code:"LIFECYCLE_MISSING_EVENT",topic:$.name,file:$.sourcePath,message:`Lifecycle resource "${$.name}" is missing required frontmatter field: event`})}function ZN($,Q){if($.source!==z$.LOCAL)return;let Z=`${$.description}
|
|
732
|
+
${$.body}`;for(let X of sR){let U=Z.match(X);if(U){Q.push({severity:i.ERROR,code:"PLACEHOLDER_TEXT",topic:$.name,file:$.sourcePath,message:`Topic "${$.name}" still contains scaffold placeholder text: "${U[0]}". Replace it with the real value before syncing.`});return}}}function XN($,Q){if($.source!==z$.LOCAL)return;if($.category===vW)return;let Z=$.description.trim(),X=Z.length<eR,U=!tR.test(Z);if(!X&&!U)return;let J=X?`is only ${Z.length} characters`:"states what the doc covers but not when to use it";Q.push({severity:i.WARNING,code:"WEAK_DESCRIPTION",topic:$.name,file:$.sourcePath,message:`Description for "${$.name}" ${J}. The model loads a doc from its description \u2014 say what it covers AND when to use it (e.g. "\u2026 Use when \u2026").`})}function UN($,Q){if($.source!==z$.LOCAL||!$.channels)return;for(let[Z,X]of Object.entries($.channels))for(let U of EI(Z,X))Q.push({severity:i.WARNING,code:"UNSUPPORTED_CHANNEL_HINT",topic:$.name,file:$.sourcePath,message:`Topic "${$.name}" sets "${U}" under its "${Z}" block, but ${Z} does not honor it \u2014 the value will be ignored.`})}function JN($,Q){for(let Z of $.invalidAgentFields??[])Q.push({severity:i.ERROR,code:"INVALID_AGENT_FIELD",topic:$.name,file:$.sourcePath,message:`Topic "${$.name}" sets ${Z.field}: "${Z.value}", but allowed values are: ${Z.allowed.join(", ")}.`})}function YN($){return $.replace(QN,"$1")}function WN($){if(!$.endsWith(".md"))return!1;if(/^[a-z]+:\/\//i.test($))return!1;if($.startsWith("/"))return!1;return!0}function _N($,Q){if($.source!==z$.LOCAL)return;for(let Z of YN($.body).matchAll($N)){let X=Z[1]?.trim();if(!X)continue;let U=X.split("#")[0]?.trim()??"";if(!WN(U))continue;if(hR(yW(uR($.sourcePath),U)))continue;Q.push({severity:i.ERROR,code:"BROKEN_REFERENCE",topic:$.name,file:$.sourcePath,message:`Topic "${$.name}" links to "${X}", which does not exist relative to its source file.`})}}function GN($,Q,Z){if($.source!==z$.LOCAL)return;for(let X of $.teamMembers??[]){if(Q.has(X))continue;Z.push({severity:i.ERROR,code:"UNKNOWN_TEAM_MEMBER",topic:$.name,file:$.sourcePath,message:`Topic "${$.name}" references team member "${X}", which is not a known topic.`})}}function xW($,Q){let Z=[];for(let Y of Q)Z.push({severity:i.WARNING,code:"LOADER_WARNING",message:Y});let X=cR($),U=new Map,J=new Set(X.map((Y)=>Y.name));for(let Y of X)nR(Y,U,Z),iR(Y,Z),rR(Y,Z),oR(Y,Z),aR(Y,Z),ZN(Y,Z),XN(Y,Z),JN(Y,Z),_N(Y,Z),GN(Y,J,Z),UN(Y,Z);return Z}function zN($,Q,Z){if($)return[$];if(N2(Q)){let X=w2(Q),U=rJ(X.playbook);if(!U.ok)for(let Y of U.issues)Z.push({severity:i.WARNING,code:"CONFIG_SCHEMA_INVALID",message:`sumr.yaml.playbook: ${Y}`});let J=X.playbook.sources;if(J.length===0)Z.push({severity:i.ERROR,code:"CONFIG_SOURCES_EMPTY",message:DQ});return J}return[dR]}function HN($){let Q=eQ(),Z=[];for(let X of Q.roots){let U=k0([X.root],{source:z$.CORE,module:X.module});Z=[...Z,...U.topics],$.push(...U.warnings)}return Z}function nJ($,Q){return` ${E(`${$} [${Q.code}]`,"purple")} ${E(Q.message,"dim")}`}function VN($,Q,Z){let X=[];if($.length>0){X.push(E(`Errors (${$.length}):`,"pink"));for(let U of $)X.push(nJ("\u2717",U))}if(Q.length>0){if(X.length>0)X.push("");X.push(E(`Warnings (${Q.length}):`,"orchid"));for(let U of Q)X.push(nJ("\u26A0",U))}return X.push(""),X.push(E(`Sources: ${Z.join(", ")}`,"dim")),X.join(`
|
|
733
|
+
`)}async function ON($,Q,Z){try{let X=k0($,{source:z$.LOCAL});return{topics:X.topics,warnings:X.warnings}}catch(X){Z?.stop("Could not load Playbook topics");let U=J0(X,"Failed to load Playbook topics.");if(Q)G1(_1("playbook validate",!1,null,[],{code:"LOAD_ERROR",message:U}));else await b0("Could not load Playbook topics",U);return 1}}async function KN($,Q,Z,X,U,J,Y){let W={valid:X,errors:Q.length,warnings:Z.length,issues:$};if(J)return G1(_1("playbook validate",X,W,[],null)),X?0:1;if($.length===0){let _=Y?["No issues found \uD83C\uDF89","",`Sources: ${U.join(", ")}`].join(`
|
|
734
|
+
`):"No issues found \uD83C\uDF89";return await P0("Playbook valid",_,"mauve"),S2(`
|
|
735
|
+
`),0}return await P0(X?"Playbook warnings":"Playbook validation failed",VN(Q,Z,U),X?"mauve":"pink"),S2(`
|
|
736
|
+
`),X?0:1}async function qN(){let{spinner:$}=await import("@clack/prompts"),{brandSpinnerOptions:Q}=await Promise.resolve().then(() => (D(),p0));return $(Q("purple"))}async function BN($){let{extras:Q}=$.args,Z=Q.json===!0,X=Q.verbose===!0,U=process.cwd(),J=typeof Q.source==="string"?Q.source:void 0,Y=[],W=zN(J,U,Y),_=W.map((R)=>yW(U,R)),G=Z?void 0:await qN();G?.start("Loading Playbook topics\u2026");let z=await ON(_,Z,G);if(typeof z==="number")return z;let H=z.warnings;G?.message("Merging core resources\u2026");let V=HN(H);G?.message("Validating topics\u2026");let O=[...V,...z.topics],K=[...Y,...xW(O,H)],q=K.filter((R)=>R.severity===i.ERROR),B=K.filter((R)=>R.severity===i.WARNING),S=q.length===0,M=`${O.length} topic${O.length===1?"":"s"}`;return G?.stop(`Checked ${M}`),KN(K,q,B,S,W,Z,X)}async function D0($,Q,Z,X,U,J=[],Y){if($)G1(_1("playbook sync",!1,null,J,{code:Q,message:Z,details:Y}));else await b0(X,U)}function jN($){return{issues:$.map((Q)=>({severity:Q.severity,code:Q.code,message:Q.message,topic:Q.topic,file:Q.file}))}}async function TN($,Q,Z){let X=xW($,[]);for(let Y of X)if(Y.severity===i.WARNING)Q.push(`[${Y.code}] ${Y.message}`);let U=X.filter((Y)=>Y.severity===i.ERROR);if(U.length===0)return;let J=U.map((Y)=>`\u2717 [${Y.code}] ${Y.message}`).join(`
|
|
737
|
+
`);return await D0(Z,"VALIDATION_FAILED",`Validation failed with ${U.length} error(s). Run \`sumr playbook validate\` for detail.`,"Playbook validation failed",J,Q,jN(U)),1}async function EN($){if($)return;let{spinner:Q}=await import("@clack/prompts"),{brandSpinnerOptions:Z}=await Promise.resolve().then(() => (D(),p0)),X=Q(Z("purple"));return X.start("Loading Playbook sources\u2026"),X}async function CN($,Q,Z){let{extras:X}=$.args,U=process.cwd(),J=IN(U);if(!J)return await D0(Q,"NO_CONFIG","No sumr.yaml found in the current directory. Run `sumr playbook config` to set up this repo.","No sumr.yaml found","No sumr.yaml found in the current directory. Run `sumr playbook config` to set up this repo."),1;let Y=bR($.argv,X,J);if(Y.origin===E2.CONFIG&&Y.paths.length===0)return await D0(Q,"INVALID_CONFIG",DQ,"Invalid Playbook configuration",DQ),1;let W=kR(Y,U);if(Z!==void 0&&!r$.includes(Z)){let M=`Unknown channel: "${Z}". Valid channels: ${r$.join(", ")}`;return await D0(Q,"INVALID_CHANNEL",M,"Invalid Playbook channel",[`Requested: ${Z}`,"",`Valid channels: ${r$.join(", ")}`].join(`
|
|
738
|
+
`)),1}let _,G=[],z=await EN(Q);try{_=fR(W,U),G.push(..._.warnings)}catch(M){z?.stop("Could not load Playbook sources");let R=M instanceof Error?M.message:"Failed to load Playbook topics.";return await D0(Q,"LOAD_ERROR",R,"Could not load Playbook topics",R),1}if(_.topics.length===0){z?.stop("No Playbook topics found");let M=MS(Y.paths,U,G);return await D0(Q,"NO_TOPICS",M,"No Playbook topics found",M,G),1}let V={PLAYBOOK_PATH:J.playbook.sources[0]??AN,...eC(J)},O=FN(_.topics,V);z?.stop(`Loaded ${O.length} topic${O.length===1?"":"s"}`);let K=await TN(O,G,Q);if(K!==void 0)return K;let q=Q8(J),B=Z?E$.filter((M)=>M.id===Z):E$.filter((M)=>q.includes(M.id)),S=Z?[]:E$.filter((M)=>!q.includes(M.id));return{topics:O,channelsToRun:B,channelsToClean:S,hideGen:J.playbook.hideGen??!1,yamlConfig:J,allWarnings:G,breakdown:_.breakdown}}async function SN($){let{extras:Q}=$.args,Z=Q["dry-run"]===!0,X=Q.json===!0,U=Q.verbose===!0,J=typeof Q.channel==="string"?Q.channel:void 0,Y=await CN($,X,J);if(typeof Y==="number")return Y;let{topics:W,channelsToRun:_,channelsToClean:G,hideGen:z,yamlConfig:H,allWarnings:V,breakdown:O}=Y;if(X)return DR(W,_.map((K)=>K.id),G,V,Z,O,z,H);return MR(W,_.map((K)=>K.id),G,V,Z,O,z,H,U)}function FN($,Q){return $.map((Z)=>({...Z,description:Q0(Z.description,Q),when:Z.when?Q0(Z.when,Q):Z.when,body:Q0(Z.body,Q),references:Z.references.map((X)=>({...X,description:Q0(X.description,Q),when:X.when?Q0(X.when,Q):X.when,body:Q0(X.body,Q)}))}))}function IN($){if(!N2($))return;try{return w2($)}catch{return}}var mM,iJ,rM,oM,aM,sM,tM,eM,$j,Qj,Zj,KQ,qQ,XJ,Xj,Vj=".",Oj="'.'",Kj="# Playbook",qj,Aj,W1,G$,e,Mj,jj='"',Tj="'",DQ,Ej,f1,pj="",cj,QT,v$,ZT,XT=`---
|
|
732
739
|
name: my-topic
|
|
733
740
|
title: My Topic
|
|
734
741
|
description: "What this topic covers. Use when doing X."
|
|
@@ -745,7 +752,7 @@ tags: [optional, tags]
|
|
|
745
752
|
## Core Rules
|
|
746
753
|
|
|
747
754
|
Keep the main doc concise. Put deep detail in category: reference files in the same folder.
|
|
748
|
-
`,
|
|
755
|
+
`,UT=`---
|
|
749
756
|
category: reference
|
|
750
757
|
name: my-topic-detail
|
|
751
758
|
title: Detail Section Title
|
|
@@ -760,18 +767,18 @@ order: 10
|
|
|
760
767
|
## Section A
|
|
761
768
|
|
|
762
769
|
Supporting detail that should load on demand.
|
|
763
|
-
`,
|
|
770
|
+
`,JJ=`docs/
|
|
764
771
|
-- my-topic/
|
|
765
772
|
|-- overview.md
|
|
766
773
|
|-- detail-a.md
|
|
767
774
|
|-- detail-b.md
|
|
768
|
-
-- detail-c.md`,
|
|
775
|
+
-- detail-c.md`,JT=`docs/
|
|
769
776
|
-- standards/
|
|
770
777
|
-- testing/
|
|
771
778
|
|-- overview.md
|
|
772
779
|
-- playwright-cli/
|
|
773
780
|
|-- overview.md \u2190 main topic and invoker
|
|
774
|
-
-- command-catalog.md \u2190 category: reference`,
|
|
781
|
+
-- command-catalog.md \u2190 category: reference`,YT=`## Flow
|
|
775
782
|
|
|
776
783
|
Use compact arrows for a simple, mostly linear process:
|
|
777
784
|
|
|
@@ -796,14 +803,14 @@ flowchart LR
|
|
|
796
803
|
Transition rules:
|
|
797
804
|
- Do not enter implementation until the approval gate is satisfied.
|
|
798
805
|
- If review finds missing context, return to draft instead of continuing.
|
|
799
|
-
`,
|
|
806
|
+
`,WT=`docs/
|
|
800
807
|
-- team-members/
|
|
801
808
|
|-- orchestrator.tm.md \u2190 drives multi-domain tasks
|
|
802
809
|
|-- code-audit-runner.tm.md \u2190 repo-wide quality agent
|
|
803
810
|
-- quality-lead.tm.md \u2190 gate-keeper, not domain-specific
|
|
804
811
|
-- standards/
|
|
805
812
|
-- backend/
|
|
806
|
-
-- overview.md`,
|
|
813
|
+
-- overview.md`,_T=`docs/
|
|
807
814
|
-- standards/
|
|
808
815
|
|-- backend/
|
|
809
816
|
| |-- overview.md
|
|
@@ -813,7 +820,7 @@ Transition rules:
|
|
|
813
820
|
|-- overview.md
|
|
814
821
|
-- frontend-worker.tm.md \u2190 lives beside the frontend docs it follows
|
|
815
822
|
-- team-members/
|
|
816
|
-
-- orchestrator.tm.md \u2190 cross-domain, stays at root`,
|
|
823
|
+
-- orchestrator.tm.md \u2190 cross-domain, stays at root`,GT=`docs/
|
|
817
824
|
-- architecture/ \u2190 system design, diagrams, ADRs
|
|
818
825
|
|-- system/
|
|
819
826
|
| -- overview.md
|
|
@@ -836,8 +843,8 @@ Transition rules:
|
|
|
836
843
|
-- workflows/ \u2190 user-invoked AI workflows
|
|
837
844
|
-- ui-review.wf.md
|
|
838
845
|
-- lifecycle/ \u2190 optional lifecycle automations
|
|
839
|
-
-- session-start.lc.md`,
|
|
840
|
-
`),UE={version:1,playbook:{channels:{claude:!0,codex:!0,cursor:!0,copilot:!1,gemini:!1,opencode:!1},sources:["docs"],agentsMd:{enabled:!0,targets:["."],claudeMd:!0}}};P1={SKILL:"skill",TEAM_MEMBER:"team-member",WORKFLOW:"workflow",LIFECYCLE:"lifecycle",REFERENCE:"reference"};DE={name:"playbook add",description:"Scaffold a new Playbook doc with correct frontmatter",usage:["sumr playbook add","sumr playbook add --source docs/standards/backend"],options:[{flag:"--source <path>",description:"Destination folder (skips the folder prompt)"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook add","sumr playbook add --source docs/standards/backend"]};xE=E({name:"add",description:"Scaffold a new Playbook doc with correct frontmatter",group:"modules",visibility:"public",help:DE,execute:vE}),y$={OVERVIEW:"overview",FRONTMATTER:"frontmatter",STRUCTURE:"structure",FOLDER_PATTERNS:"folderPatterns",REFERENCES:"references",EXTRACTION:"extraction",CODEX:"codex",FLOWS:"flows",FILE_EXTENSIONS:"fileExtensions",PLACEHOLDERS:"placeholders",MODULE_RESOURCES:"moduleResources",CHECKLIST:"checklist"},gE={OVERVIEW:"overview",REFERENCE:"reference",FOLDER:"folder",FLOW:"flow",TEAM_MEMBERS_ROOT:"teamMembersRoot",TEAM_MEMBERS_DOMAIN:"teamMembersDomain",FULL_STRUCTURE:"fullStructure"},cW={version:1,name:"playbook-authoring",description:"Canonical authoring contract for SUMR Playbook Markdown topics, references, and extraction markers.",sourceOfTruth:{localMode:"Canonical content lives in configured repo source paths such as docs/ or playbook/. Modules ship their consumer-facing AI resources from a resources/ root declared in sumr.module.yaml under spec.exports.aiResources.",cloudMode:"Canonical content lives in SUMR Playbook storage and is fetched by the CLI before rendering.",generatedOutput:"Generated AI tool folders are never source of truth. Codex repo skills render to .agents/skills; team-member docs render to native delegated-role folders such as .codex/agents, .claude/agents, .gemini/agents, .opencode/agents, and .github/agents. Codex also gets a generated .codex/AGENTS.md startup guide for routing. Platform topics shipped by Playbook generate flat sumr-<topic> names; module-shipped topics generate the namespaced canonical sumr-<module>:<topic> (filesystem artifacts use sumr-<module>-<topic>)."},sections:{overview:"A Playbook topic is canonical Markdown plus frontmatter. Renderers convert it into Claude, Codex, Cursor, Copilot, Gemini, and OpenCode output.",frontmatter:"Every main topic requires name, title, and description. Reference files also require category, label, when, and order. Advanced AI-tool features live in top-level channel blocks such as codex:, claude:, gemini:, opencode:, copilot:, and cursor:.",structure:"Use one folder per domain or topic context. Put overview.md as the main entry point and category: reference files beside it in the same folder. When splitting an existing file, decide the owning context folder first; do not just add another peer file to a broad folder. Team-members can live in a dedicated root folder (orchestrators, cross-domain agents) or inside their domain folder (domain-specific workers).",folderPatterns:"Root-level team-members/ for orchestrators and generalist agents. Domain-embedded .tm.md files for workers tightly coupled to a specific standards or architecture folder. Workflows live in workflows/ or beside their owning process. Lifecycle automations live in lifecycle/ or beside the domain they guard.",references:"Reference files are supporting detail for the main doc in the same folder. They attach by folder proximity; no references field is allowed.",extraction:"Use extract markers for long examples or templates that should become separate generated files inside skill folders.",codex:"Canonical AI resources use category: team-member for delegated roles, category: workflow for user-invoked prompts, and category: lifecycle for lifecycle automations. Codex renders team-member resources into .codex agent files plus a generated startup guide, and renders lifecycle resources into hook config/scripts. The legacy category: hook alias is still accepted.",flows:"Document simple workflows with one compact arrow flow. Use [role] for responsible agents or team members, visible gate labels for human decisions, and optional emojis only when they make state changes easier to scan. Use Mermaid for branching, loops, or failure paths.",fileExtensions:"Optional compound extensions imply category without frontmatter: .tm.md \u2192 team-member, .wf.md \u2192 workflow, .lc.md \u2192 lifecycle, .hk.md \u2192 lifecycle legacy alias, .rf.md \u2192 reference. Explicit frontmatter category always wins. Plain .md remains the default for skills.",placeholders:"Use {{PLAYBOOK_PATH}} in topic bodies to reference the user-configured docs directory without hard-coding a path. Use {{TEAM-MEMBER}} when source prose means a generated delegated role; Playbook replaces it per channel (for example Subagent for Claude/Codex/Gemini and Agent for Copilot/OpenCode).",moduleResources:"A SUMR CLI module ships consumer-facing AI resources (usage skills, references, workflows, team-members) from a resources/ directory declared in sumr.module.yaml under spec.exports.aiResources: { module, roots, activation }. Author source topic names UNPREFIXED (e.g. name: usage) \u2014 never start a module source name with sumr-. The renderer namespaces module topics as the canonical sumr-<module>:<topic> and the filesystem-safe sumr-<module>-<topic>, keeping them distinct from flat platform standards (sumr-<topic>) and generic non-SUMR skills. When activation.mode is command, resources install into a consumer repo only after the user runs the declared init command (e.g. `sumr <module> init`); mode always installs whenever the module is present.",checklist:"Before syncing, check required frontmatter, folder structure, reference fields, extraction markers, and generated-output boundaries."},fieldRules:[{name:"name",required:!0,appliesTo:"all",description:"Stable unique kebab-case identifier. Keep source docs unprefixed; SUMR adds managed prefixes to generated outputs (flat sumr-<name> for platform topics, namespaced sumr-<module>:<name> for module-shipped topics). Never start a source name with sumr-."},{name:"title",required:!0,appliesTo:"all",description:"Human-facing title. It may change without breaking generated output identity."},{name:"description",required:!0,appliesTo:"all",description:"AI retrieval summary. Write what the doc covers and when to use it. Quote it in YAML."},{name:"category",required:!1,appliesTo:"all",description:"Content type. Use reference for supporting files; use team-member, workflow, or lifecycle for canonical AI resources that render into tool-specific outputs. The hook value remains a lifecycle alias for older docs."},{name:"target",required:!1,appliesTo:"all",description:"Output file name for generated team-member, workflow, and lifecycle files. The renderer keeps it inside the managed channel directory."},{name:"event",required:!0,appliesTo:"main",description:"Lifecycle event name for category: lifecycle, for example SessionStart, PreToolUse, PostToolUse, UserPromptSubmit, or Stop."},{name:"matcher",required:!1,appliesTo:"main",description:"Optional lifecycle matcher regex or event source filter. For example startup|resume or Bash|apply_patch."},{name:"timeout",required:!1,appliesTo:"main",description:"Optional lifecycle automation timeout in seconds."},{name:"statusMessage",required:!1,appliesTo:"main",description:"Optional short status shown while a lifecycle command runs."},{name:"tags",required:!1,appliesTo:"main",description:"Optional lowercase discovery/scoping labels."},{name:"label",required:!0,appliesTo:"reference",description:"Short display label used in generated reference tables."},{name:"when",required:!0,appliesTo:"reference",description:"Action phrases that tell AI when to load the reference. Use verbs such as Creating, Reviewing, Debugging."},{name:"order",required:!0,appliesTo:"reference",description:"Integer sort order among sibling references. Use gaps such as 10, 20, 30."},{name:"modelTier",required:!1,appliesTo:"main",description:"Optional model hint: reasoning, coding, or fast. Channels that support model selection use this to pick the right model class. Per-channel native blocks always take precedence."},{name:"team-member",required:!1,appliesTo:"main",description:"Optional list of delegated team-member role names used by generated skills to show the agent flow for a workflow."},{name:"review",required:!1,appliesTo:"main",description:"Set true when a standard must be part of reviewer and audit checklists."},{name:"insight",required:!1,appliesTo:"main",description:"Optional discovery labels for conceptual standards, such as core, quality, testing, or security."},{name:"channels",required:!1,appliesTo:"main",description:"Legacy-compatible per-channel hints. Prefer top-level native channel blocks for new docs."},{name:"codex, claude, cursor, copilot, gemini, opencode",required:!1,appliesTo:"main",description:"Optional top-level native channel blocks. Add a short comment above each block that explains the tool and output purpose."}],categories:[{value:"omitted",purpose:"Default main topic/how-to document.",requiredFields:["name","title","description"]},{value:"topic",purpose:"General Playbook entry.",requiredFields:["name","title","description"]},{value:"how-to",purpose:"Procedural guide or reusable workflow.",requiredFields:["name","title","description"]},{value:"reference",purpose:"Supporting detail attached to the main doc in the same folder.",requiredFields:["category","name","title","description","label","when","order"]},{value:"role",purpose:"Role/profile guidance for recurring AI or team behavior.",requiredFields:["name","title","description"]},{value:"team-member",purpose:"Canonical delegated team-member role. Source prose should use {{TEAM-MEMBER}} for the role label; channels render to their native delegated-role profile format.",requiredFields:["name","title","description","category"]},{value:"workflow",purpose:"Canonical user-invoked AI workflow. Claude renders it as a slash command; other channels can map it to their command/prompt surface.",requiredFields:["name","title","description","category"]},{value:"lifecycle",purpose:"Canonical lifecycle guardrail or context automation. Codex renders the script, hooks.json binding, and hooks feature flag.",requiredFields:["name","title","description","category","event","target"]},{value:"hook",purpose:"Legacy alias for lifecycle. Prefer category: lifecycle in new docs.",requiredFields:["name","title","description","category","event","target"]}],folderStructure:{pattern:eU,microconceptPattern:dE,mainDoc:"overview.md is the preferred main entry point for a topic folder.",references:"Reference files live beside overview.md and set category: reference in frontmatter.",contextRules:["If the current folder already has an overview.md and the split content only supports that topic, keep the new files in that folder as category: reference.","If the split content is a substantial subtopic with its own context, create a child folder and put its entry point in child-topic/overview.md.","If a split creates two or more files for one microconcept, promote that microconcept to a child folder; the child overview.md is the invoker/entry point and sibling files are references.","Avoid multiple unrelated main docs in one folder; broad folders should contain child topic folders, not many peer overview-like files.","Before creating a new file, check whether the content should be merged into an existing topic or reference instead."],splitFlow:["Analyze context: identify the domain, the current folder owner, and whether the file is a main topic or supporting detail.","Choose placement: same-folder reference for supporting detail; child folder with overview.md for a substantial standalone subtopic or any microconcept that now needs multiple files.","Split content: keep concise rules and navigation in overview.md; move deep examples, tables, and edge cases into references.","Check naming: use kebab-case filenames, stable name fields, overview.md for the entry point, label/when/order for references, and no generated prefixes in source docs.","Run validation: sumr playbook validate --source docs.","Preview generation: sumr playbook sync --source docs --dry-run --json; run normal sync only after the preview has no warnings or unexpected output."],forbidden:["Do not create references/ folders manually.","Do not split a large doc by adding another main doc beside an existing overview.md when a child topic folder is the real owner.","Do not leave multiple peer files in a broad parent folder when they all describe the same subtopic.","Do not add a references field to frontmatter.","Do not edit generated .claude/.agents/.cursor/.github/.gemini/.opencode output as source."],teamMemberPlacement:{root:"Place orchestrators and cross-domain agents in a dedicated docs/team-members/ folder. These agents are not owned by any one domain and benefit from being visible at the top level.",domainEmbedded:"Place domain-specific workers (e.g. frontend-worker, backend-worker) beside the standards or architecture docs they follow. Co-location reinforces the connection and keeps the agent updated when the domain docs change.",guidance:"Use root placement for agents that coordinate multiple domains or have no natural home. Use domain-embedded placement when the agent role is inseparable from one area of the codebase."},standardsNaming:[{name:"standards",purpose:"Technical rules, specs, and non-negotiable constraints. Clear and precise."},{name:"guidelines",purpose:"Softer guidance and recommendations. Good when rules allow judgment calls."},{name:"playbook",purpose:"Team playbook mixing process, culture, and technical conventions. Good all-in-one name."},{name:"handbook",purpose:"Team handbook including onboarding, culture, and practices alongside tech rules."},{name:"conventions",purpose:"Naming, structure, and pattern conventions. Good when the focus is consistency."},{name:"practices",purpose:"Engineering practices and ways of working. Implies lived habits, not just rules."}],recommendedTopLevel:[{name:"architecture",purpose:"System design, diagrams, ADRs, and infrastructure topology."},{name:"standards",purpose:"Domain-specific technical rules (backend/, frontend/, security/, etc.)."},{name:"team-members",purpose:"Orchestrators and cross-domain AI agents."},{name:"workflows",purpose:"User-invoked AI workflows (.wf.md files) such as PR prep or issue triage."},{name:"lifecycle",purpose:"Lifecycle automation scripts (.lc.md files) that guard or enrich AI sessions."},{name:"processes",purpose:"Workflows, release checklists, incident runbooks, and repeatable procedures."}]},extraction:{markerSyntax:`<!-- extract:examples -->
|
|
846
|
+
-- session-start.lc.md`,eJ,mQ,lQ,BT="authoring",LT,TT,E$,r$,wT,PT,z$,_Y,j2,P2,R0,LQ="sumr-",GY=":",zY="sumr-playbook",uT,dT,mT,sT,eT,U8,XE,YE,b1,KE,N0,PQ,qE,BE,LE="",ME,jE,jY,TY,EY,CY,wE,PE,bE,kE,GJ="reference",zJ="overview.md",fE,uE=65536,dE,IY,eE,$C,QC,OJ="",KJ="..",BC="SUMR_PLAYBOOK_RESOURCES_DIR",LC="SUMR_PLAYBOOK_RESOURCES_CACHE_DIR",AC="@sumr/cli-playbook",MC="playbook",jC="@sumr/devkit",A2,T2,n,y1,TC,mC,iC,E2,fQ,qJ,i,rC,oC,w0,I0,x,u,aC="ask",sC,zS,PY,HS,TQ,VS=".codex/hooks.json",OS=".codex/hooks/",KS=".",I,U5,e6,NS,jJ,vQ,A8="<!-- sumr-playbook:managed -->",vS=".",xS,k1=".",lS="*",pS="docs",cS="..",gY="",nS,oS,eS,NJ,dY=".",HF="mission-workflow",VF,OF,q$,oY="# SUMR Playbook generated files",aY="# sumr-playbook:start",sY="# sumr-playbook:end",PF=".ignore",bF,tY,kF,fF,pF=".vscode/settings.json",cF,zW,HW,VW,$I,gQ="SKILL.md",z8="references",H8=".md",ZI,YI,WI,_I,GI,zI,HI,yJ,II,RI="<!-- Generated by SUMR Playbook. Edit the source doc and run `bun run sync`. -->",NI="metadata",AW,gJ="# Generated by SUMR Playbook. Edit the source doc and run `bun run sync`.\n",mI="<!-- Generated by SUMR Playbook. Edit the source doc and run `bun run sync`. -->",lI="<!-- Generated by SUMR Playbook. Edit the source doc and run `bun run sync`. -->",jW="<!-- Generated by SUMR Playbook.",TW=".md",EW,pI,cI,nI,BD,s6="sumr playbook sync",LD="bun run sync",hQ="# Generated by SUMR Playbook",AD="# Generated by SUMR Playbook.",SW="<!-- Generated by SUMR Playbook.",MD,uJ,jD,IW="## Available Agents",vD,DW="",hD,oD,aD,YR,GR,zR,PW,fW="docs",NR="--source",pJ="--source=",wR="sumr-",PR="resources",dR="docs",mR,lR=65536,pR="sumr-",vW="reference",sR,tR,eR=25,$N,QN,LN,AN="docs",MN,DN,RN;var hW=v2(()=>{D();D();D();D();D();D();D();D();D();D();D();mM=N$.object({enabled:N$.boolean().optional(),targets:N$.array(N$.string().min(1)).optional(),claudeMd:N$.boolean().optional()}).strict(),iJ=N$.object({channels:N$.record(N$.string(),N$.boolean()),sources:N$.array(N$.string().min(1)),hideGen:N$.boolean().optional(),agentsMd:mM.optional()}).strict();rM=["github","gitlab","jira","linear","azure-boards","shortcut","clickup","asana","trello","notion","custom"],oM=["github","gitlab","bitbucket","azure-devops","gitea","codeberg","generic-git","none"],aM=["preview","ask","disabled"],sM=["basic","planning-only","standard-delivery","full-delivery"],tM=["auto","ask","human","manual"],eM={root:"root",playbook:"playbook",kontract:"kontract",mission:"mission",other:"other"},$j={none:"none",channels:"channels",sources:"sources",agentsMd:"agentsMd",agentsMdTargets:"agentsMdTargets"},Qj={none:"none",tracker:"tracker",git:"git",flow:"flow",flowSteps:"flowSteps",issuePrefixes:"issuePrefixes"},Zj={TRUE:"true",FALSE:"false"},KQ={KONTRACT:"kontract:",MISSION:"mission:",PLAYBOOK:"playbook:"},qQ={BASE_BRANCH:"baseBranch",PROVIDER:"provider",PR_MODE:"prMode"},XJ={REPO_ID:"repoId",RETENTION_DAYS:"retentionDays"},Xj={INPUT:"input",OUTPUT:"output"};qj=[];Aj=H1,W1=eM,G$=$j,e=Qj,Mj=Zj,DQ=["`playbook.sources` is configured in sumr.yaml, but no source paths were found.","","Add at least one source path:"," playbook:"," sources:"," - docs"].join(`
|
|
847
|
+
`),Ej={version:1,playbook:{channels:{claude:!0,codex:!0,cursor:!0,copilot:!1,gemini:!1,opencode:!1},sources:["docs"],agentsMd:{enabled:!0,targets:["."],claudeMd:!0}}};f1={SKILL:"skill",TEAM_MEMBER:"team-member",WORKFLOW:"workflow",LIFECYCLE:"lifecycle",REFERENCE:"reference"};cj={name:"playbook add",description:"Scaffold a new Playbook doc with correct frontmatter",usage:["sumr playbook add","sumr playbook add --source docs/standards/backend"],options:[{flag:"--source <path>",description:"Destination folder (skips the folder prompt)"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook add","sumr playbook add --source docs/standards/backend"]};QT=T({name:"add",description:"Scaffold a new Playbook doc with correct frontmatter",group:"modules",visibility:"public",help:cj,execute:$T}),v$={OVERVIEW:"overview",FRONTMATTER:"frontmatter",STRUCTURE:"structure",FOLDER_PATTERNS:"folderPatterns",REFERENCES:"references",EXTRACTION:"extraction",CODEX:"codex",FLOWS:"flows",FILE_EXTENSIONS:"fileExtensions",PLACEHOLDERS:"placeholders",MODULE_RESOURCES:"moduleResources",CHECKLIST:"checklist"},ZT={OVERVIEW:"overview",REFERENCE:"reference",FOLDER:"folder",FLOW:"flow",TEAM_MEMBERS_ROOT:"teamMembersRoot",TEAM_MEMBERS_DOMAIN:"teamMembersDomain",FULL_STRUCTURE:"fullStructure"},eJ={version:1,name:"playbook-authoring",description:"Canonical authoring contract for SUMR Playbook Markdown topics, references, and extraction markers.",sourceOfTruth:{localMode:"Canonical content lives in configured repo source paths such as docs/ or playbook/. Modules ship their consumer-facing AI resources from a resources/ root declared in sumr.module.yaml under spec.exports.aiResources.",cloudMode:"Canonical content lives in SUMR Playbook storage and is fetched by the CLI before rendering.",generatedOutput:"Generated AI tool folders are never source of truth. Codex repo skills render to .agents/skills; team-member docs render to native delegated-role folders such as .codex/agents, .claude/agents, .gemini/agents, .opencode/agents, and .github/agents. Codex also gets a generated .codex/AGENTS.md startup guide for routing. Platform topics shipped by Playbook generate flat sumr-<topic> names; module-shipped topics generate the namespaced canonical sumr-<module>:<topic> (filesystem artifacts use sumr-<module>-<topic>)."},sections:{overview:"A Playbook topic is canonical Markdown plus frontmatter. Renderers convert it into Claude, Codex, Cursor, Copilot, Gemini, and OpenCode output.",frontmatter:"Every main topic requires name, title, and description. Reference files also require category, label, when, and order. Advanced AI-tool features live in top-level channel blocks such as codex:, claude:, gemini:, opencode:, copilot:, and cursor:.",structure:"Use one folder per domain or topic context. Put overview.md as the main entry point and category: reference files beside it in the same folder. When splitting an existing file, decide the owning context folder first; do not just add another peer file to a broad folder. Team-members can live in a dedicated root folder (orchestrators, cross-domain agents) or inside their domain folder (domain-specific workers).",folderPatterns:"Root-level team-members/ for orchestrators and generalist agents. Domain-embedded .tm.md files for workers tightly coupled to a specific standards or architecture folder. Workflows live in workflows/ or beside their owning process. Lifecycle automations live in lifecycle/ or beside the domain they guard.",references:"Reference files are supporting detail for the main doc in the same folder. They attach by folder proximity; no references field is allowed.",extraction:"Use extract markers for long examples or templates that should become separate generated files inside skill folders.",codex:"Canonical AI resources use category: team-member for delegated roles, category: workflow for user-invoked prompts, and category: lifecycle for lifecycle automations. When a user asks about hooks, automatic AI checks, session start/stop behavior, or tool-use guardrails, create a lifecycle source doc before editing tool-native hook files. Codex renders team-member resources into .codex agent files plus a generated startup guide, and renders lifecycle resources into hook config/scripts. The legacy category: hook alias is still accepted.",flows:"Document simple workflows with one compact arrow flow. Use [role] for responsible agents or team members, visible gate labels for human decisions, and optional emojis only when they make state changes easier to scan. Use Mermaid for branching, loops, or failure paths.",fileExtensions:"Optional compound extensions imply category without frontmatter: .tm.md \u2192 team-member, .wf.md \u2192 workflow, .lc.md \u2192 lifecycle, .hk.md \u2192 lifecycle legacy alias, .rf.md \u2192 reference. Explicit frontmatter category always wins. Plain .md remains the default for skills.",placeholders:"Use {{PLAYBOOK_PATH}} in topic bodies to reference the user-configured docs directory without hard-coding a path. Use {{TEAM-MEMBER}} when source prose means a generated delegated role; Playbook replaces it per channel (for example Subagent for Claude/Codex/Gemini and Agent for Copilot/OpenCode).",moduleResources:"A SUMR CLI module ships consumer-facing AI resources (usage skills, references, workflows, team-members) from a resources/ directory declared in sumr.module.yaml under spec.exports.aiResources: { module, roots, activation }. Author source topic names UNPREFIXED (e.g. name: usage) \u2014 never start a module source name with sumr-. The renderer namespaces module topics as the canonical sumr-<module>:<topic> and the filesystem-safe sumr-<module>-<topic>, keeping them distinct from flat platform standards (sumr-<topic>) and generic non-SUMR skills. When activation.mode is command, resources install into a consumer repo only after the user runs the declared init command (e.g. `sumr <module> init`); mode always installs whenever the module is present.",checklist:"Before syncing, check required frontmatter, folder structure, reference fields, extraction markers, and generated-output boundaries."},fieldRules:[{name:"name",required:!0,appliesTo:"all",description:"Stable unique kebab-case identifier. Keep source docs unprefixed; SUMR adds managed prefixes to generated outputs (flat sumr-<name> for platform topics, namespaced sumr-<module>:<name> for module-shipped topics). Never start a source name with sumr-."},{name:"title",required:!0,appliesTo:"all",description:"Human-facing title. It may change without breaking generated output identity."},{name:"description",required:!0,appliesTo:"all",description:"AI retrieval summary. Write what the doc covers and when to use it. Quote it in YAML."},{name:"category",required:!1,appliesTo:"all",description:"Content type. Use reference for supporting files; use team-member, workflow, or lifecycle for canonical AI resources that render into tool-specific outputs. The hook value remains a lifecycle alias for older docs."},{name:"target",required:!1,appliesTo:"all",description:"Output file name for generated team-member, workflow, and lifecycle files. The renderer keeps it inside the managed channel directory."},{name:"event",required:!0,appliesTo:"main",description:"Lifecycle event name for category: lifecycle, for example SessionStart, PreToolUse, PostToolUse, UserPromptSubmit, or Stop."},{name:"matcher",required:!1,appliesTo:"main",description:"Optional lifecycle matcher regex or event source filter. For example startup|resume or Bash|apply_patch."},{name:"timeout",required:!1,appliesTo:"main",description:"Optional lifecycle automation timeout in seconds."},{name:"statusMessage",required:!1,appliesTo:"main",description:"Optional short status shown while a lifecycle command runs."},{name:"tags",required:!1,appliesTo:"main",description:"Optional lowercase discovery/scoping labels."},{name:"label",required:!0,appliesTo:"reference",description:"Short display label used in generated reference tables."},{name:"when",required:!0,appliesTo:"reference",description:"Action phrases that tell AI when to load the reference. Use verbs such as Creating, Reviewing, Debugging."},{name:"order",required:!0,appliesTo:"reference",description:"Integer sort order among sibling references. Use gaps such as 10, 20, 30."},{name:"modelTier",required:!1,appliesTo:"main",description:"Optional model class for a team-member: reasoning, coding, or fast. Resolves to a concrete model per channel (Claude \u2192 opus/sonnet/haiku). An env override (SUMR_MODEL_<CHANNEL>_<TIER>) or a native block always takes precedence."},{name:"effort",required:!1,appliesTo:"main",description:"Optional reasoning depth for a team-member: low, medium, or high. Maps to channels that support a native effort knob (Codex model_reasoning_effort). Defaults from modelTier when unset (reasoning\u2192high, coding\u2192medium, fast\u2192low)."},{name:"access",required:!1,appliesTo:"main",description:"Optional permission posture for a team-member: read-only, write, or full. Channels translate it into their sandbox, tools, or permission model (for example Codex sandbox_mode and OpenCode permission)."},{name:"tools",required:!1,appliesTo:"main",description:"Optional agnostic capability tokens for a team-member: read, edit, shell, web, todo, task. Channels translate them into native tool names or permission keys; channels without a tool or permission surface ignore them."},{name:"team-member",required:!1,appliesTo:"main",description:"Optional list of delegated team-member role names used by generated skills to show the agent flow for a workflow."},{name:"review",required:!1,appliesTo:"main",description:"Set true when a standard must be part of reviewer and audit checklists."},{name:"insight",required:!1,appliesTo:"main",description:"Optional discovery labels for conceptual standards, such as core, quality, testing, or security."},{name:"channels",required:!1,appliesTo:"main",description:"Legacy-compatible per-channel hints. Prefer top-level native channel blocks for new docs."},{name:"codex, claude, cursor, copilot, gemini, opencode",required:!1,appliesTo:"main",description:"Optional top-level native channel blocks. Add a short comment above each block that explains the tool and output purpose."}],categories:[{value:"omitted",purpose:"Default main topic/how-to document.",requiredFields:["name","title","description"]},{value:"topic",purpose:"General Playbook entry.",requiredFields:["name","title","description"]},{value:"how-to",purpose:"Procedural guide or reusable workflow.",requiredFields:["name","title","description"]},{value:"reference",purpose:"Supporting detail attached to the main doc in the same folder.",requiredFields:["category","name","title","description","label","when","order"]},{value:"role",purpose:"Role/profile guidance for recurring AI or team behavior.",requiredFields:["name","title","description"]},{value:"team-member",purpose:"Canonical delegated team-member role. Source prose should use {{TEAM-MEMBER}} for the role label; channels render to their native delegated-role profile format.",requiredFields:["name","title","description","category"]},{value:"workflow",purpose:"Canonical user-invoked AI workflow. Claude renders it as a slash command; other channels can map it to their command/prompt surface.",requiredFields:["name","title","description","category"]},{value:"lifecycle",purpose:"Canonical lifecycle guardrail or context automation. Use when a user asks for hooks, startup context, session stop checks, pre/post tool guards, or automatic AI-tool behavior. Codex renders the script, hooks.json binding, and hooks feature flag.",requiredFields:["name","title","description","category","event","target"]},{value:"hook",purpose:"Legacy alias for lifecycle. Prefer category: lifecycle in new docs.",requiredFields:["name","title","description","category","event","target"]}],folderStructure:{pattern:JJ,microconceptPattern:JT,mainDoc:"overview.md is the preferred main entry point for a topic folder.",references:"Reference files live beside overview.md and set category: reference in frontmatter.",contextRules:["If the current folder already has an overview.md and the split content only supports that topic, keep the new files in that folder as category: reference.","If the split content is a substantial subtopic with its own context, create a child folder and put its entry point in child-topic/overview.md.","If a split creates two or more files for one microconcept, promote that microconcept to a child folder; the child overview.md is the invoker/entry point and sibling files are references.","Avoid multiple unrelated main docs in one folder; broad folders should contain child topic folders, not many peer overview-like files.","Before creating a new file, check whether the content should be merged into an existing topic or reference instead."],splitFlow:["Analyze context: identify the domain, the current folder owner, and whether the file is a main topic or supporting detail.","Choose placement: same-folder reference for supporting detail; child folder with overview.md for a substantial standalone subtopic or any microconcept that now needs multiple files.","Split content: keep concise rules and navigation in overview.md; move deep examples, tables, and edge cases into references.","Check naming: use kebab-case filenames, stable name fields, overview.md for the entry point, label/when/order for references, and no generated prefixes in source docs.","Run validation: sumr playbook validate --source docs.","Preview generation: sumr playbook sync --source docs --dry-run --json; run normal sync only after the preview has no warnings or unexpected output."],forbidden:["Do not create references/ folders manually.","Do not split a large doc by adding another main doc beside an existing overview.md when a child topic folder is the real owner.","Do not leave multiple peer files in a broad parent folder when they all describe the same subtopic.","Do not add a references field to frontmatter.","Do not edit generated .claude/.agents/.cursor/.github/.gemini/.opencode output as source."],teamMemberPlacement:{root:"Place orchestrators and cross-domain agents in a dedicated docs/team-members/ folder. These agents are not owned by any one domain and benefit from being visible at the top level.",domainEmbedded:"Place domain-specific workers (e.g. frontend-worker, backend-worker) beside the standards or architecture docs they follow. Co-location reinforces the connection and keeps the agent updated when the domain docs change.",guidance:"Use root placement for agents that coordinate multiple domains or have no natural home. Use domain-embedded placement when the agent role is inseparable from one area of the codebase."},standardsNaming:[{name:"standards",purpose:"Technical rules, specs, and non-negotiable constraints. Clear and precise."},{name:"guidelines",purpose:"Softer guidance and recommendations. Good when rules allow judgment calls."},{name:"playbook",purpose:"Team playbook mixing process, culture, and technical conventions. Good all-in-one name."},{name:"handbook",purpose:"Team handbook including onboarding, culture, and practices alongside tech rules."},{name:"conventions",purpose:"Naming, structure, and pattern conventions. Good when the focus is consistency."},{name:"practices",purpose:"Engineering practices and ways of working. Implies lived habits, not just rules."}],recommendedTopLevel:[{name:"architecture",purpose:"System design, diagrams, ADRs, and infrastructure topology."},{name:"standards",purpose:"Domain-specific technical rules (backend/, frontend/, security/, etc.)."},{name:"team-members",purpose:"Orchestrators and cross-domain AI agents."},{name:"workflows",purpose:"User-invoked AI workflows (.wf.md files) such as PR prep or issue triage."},{name:"lifecycle",purpose:"Lifecycle automation scripts (.lc.md files) that guard or enrich AI sessions and generate AI Channel hooks."},{name:"processes",purpose:"Workflows, release checklists, incident runbooks, and repeatable procedures."}]},extraction:{markerSyntax:`<!-- extract:examples -->
|
|
841
848
|
## Examples
|
|
842
849
|
|
|
843
850
|
\`\`\`text
|
|
@@ -848,10 +855,10 @@ Transition rules:
|
|
|
848
855
|
\u251C\u2500\u2500 locators.md
|
|
849
856
|
\u2514\u2500\u2500 fixtures.md
|
|
850
857
|
\`\`\`
|
|
851
|
-
<!-- /extract:examples -->`,generatedFile:"The marker name becomes a generated section file, for example examples.md inside skill folders, and the skill gets an Additional resources link.",whenToUse:["Long examples","Reusable templates","Dedicated sample sections","Boilerplate that should be available on demand"],keepInline:["Short snippets that are central to the instruction","Small config examples","Directory trees","Schema outlines","ASCII diagrams"]},examples:{overview:hE,reference:uE,folder:eU,flow:mE,teamMembersRoot:lE,teamMembersDomain:pE,fullStructure:cE},checklist:["Main topics have name, title, and description.","Descriptions explain what plus when and are quoted in YAML.","Main docs include a When to Use section.","Reference files set category: reference.","Reference files have label, when, and order.","Reference files live in the same folder as the main doc.","Splitting starts by choosing the owning context folder before creating files.","Standalone subtopics split into child folders with overview.md; supporting detail splits into same-folder references.","No references/ folder is created manually.","No references frontmatter field is used.","Dedicated examples, samples, and templates use extract markers.","Lifecycle docs include event, target, and optional matcher, timeout, and statusMessage.","Workflow docs define a user-invoked procedure and optional per-channel command metadata.","Simple workflow docs include a compact arrow flow; branching workflows use Mermaid plus transition rules.","Codex output is generated from canonical team-member/lifecycle docs and uses [features].hooks.","Team-member docs define name, description, and body instructions. Native channel blocks are the escape hatch for tool-specific agent features.","Add a short # comment above every native channel block so humans can scan which AI tool it configures.","Use role archetype names such as orchestrator, product-owner, researcher, planner, implementer, reviewer, and validator as guidance, not required frontmatter.","Generated AI tool folders are not edited as source.","Use {{PLAYBOOK_PATH}} instead of hard-coding docs/ or other source paths in topic bodies.","Module resources are declared in sumr.module.yaml spec.exports.aiResources (module, roots, activation), not hand-wired into Playbook.","Module source topic names are unprefixed; the renderer adds the sumr-<module>: namespace. Never author a source name starting with sumr-.","Command-activated modules document their init command; resources install only after the user runs it."]},v7=Object.values(y$),x7=Object.values(gE);eE={name:"playbook authoring",description:"Print the canonical Playbook Markdown authoring contract",usage:["sumr playbook authoring","sumr playbook authoring --section structure","sumr playbook authoring --example reference","sumr playbook authoring --json"],options:[{flag:"--section <id>",description:`Only print one section (${v7.join(", ")})`},{flag:"--example <id>",description:`Only print one example (${x7.join(", ")})`},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook authoring","sumr playbook authoring --section frontmatter","sumr playbook authoring --section structure --json","sumr playbook authoring --example overview"]};XT=E({name:"authoring",description:"Print the canonical Playbook Markdown authoring contract",group:"modules",visibility:"public",help:eE,execute:ZT}),A$=[{id:"claude",displayName:"Claude Code",outputDir:".claude/skills",filePattern:/^sumr-.+$/,vscodeExcludePattern:".claude/skills/sumr-*",gitignorePatterns:[".claude/skills/sumr-*/",".claude/agents/sumr-*",".claude/hooks/sumr-*",".claude/commands/sumr-*",".claude/rules/sumr-*"]},{id:"codex",displayName:"Codex CLI",outputDir:".agents/skills",legacyOutputDirs:[".codex/skills"],filePattern:/^sumr-.+$/,vscodeExcludePattern:".agents/skills/sumr-*",gitignorePatterns:[".agents/skills/sumr-*/",".codex/skills/sumr-*/",".codex/agents/sumr-*.toml"]},{id:"cursor",displayName:"Cursor",outputDir:".cursor/rules",filePattern:/^sumr-.+\.mdc$/,vscodeExcludePattern:".cursor/rules/sumr-*",gitignorePatterns:[".cursor/rules/sumr-*"]},{id:"copilot",displayName:"GitHub Copilot",outputDir:".github/instructions",filePattern:/^sumr-.+\.md$/,vscodeExcludePattern:".github/instructions/sumr-*",gitignorePatterns:[".github/instructions/sumr-*",".github/agents/sumr-*"]},{id:"gemini",displayName:"Gemini CLI",outputDir:".gemini/skills",filePattern:/^sumr-.+$/,vscodeExcludePattern:".gemini/skills/sumr-*",gitignorePatterns:[".gemini/skills/sumr-*/",".gemini/agents/sumr-*"]},{id:"opencode",displayName:"OpenCode",outputDir:".opencode/commands",filePattern:/^sumr-.+\.md$/,vscodeExcludePattern:".opencode/commands/sumr-*",gitignorePatterns:[".opencode/commands/sumr-*",".opencode/agents/sumr-*"]}],i$=A$.map(($)=>$.id);VT={PLAYBOOK_PATH:"{{PLAYBOOK_PATH}}",TEAM_MEMBER:"{{TEAM-MEMBER}}",MISSION_TRIGGER_HINTS:"{{MISSION_TRIGGER_HINTS}}",MISSION_IDENTIFIER_GUIDANCE:"{{MISSION_IDENTIFIER_GUIDANCE}}",MISSION_START_EXAMPLES:"{{MISSION_START_EXAMPLES}}",MISSION_FLOW_PRESET:"{{MISSION_FLOW_PRESET}}",MISSION_FLOW_TEXT:"{{MISSION_FLOW_TEXT}}",MISSION_FLOW_STEPS:"{{MISSION_FLOW_STEPS}}",MISSION_PR_MODE:"{{MISSION_PR_MODE}}"};OT={claude:"Subagent",codex:"Subagent",cursor:"Subagent",copilot:"Agent",gemini:"Subagent",opencode:"Agent"};r$={CORE:"core",LOCAL:"local"},KT={REASONING:"reasoning",CODING:"coding",FAST:"fast"};ST=/\n?<!--\s*extract:(\w+)\s*-->([\s\S]*?)<!--\s*\/extract:\1\s*-->\n?/g,CT=/```[\s\S]*?```/g,FT=[];fT={name:"playbook clean",description:"Remove SUMR-managed Playbook outputs from the current repo",usage:["sumr playbook clean","sumr playbook clean --channel claude","sumr playbook clean --dry-run","sumr playbook clean --json"],options:[{flag:"--channel <id>",description:`Channel to clean (one of: ${i$.join(", ")})`},{flag:"--dry-run",description:"Preview deletions without writing to disk"},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook clean","sumr playbook clean --channel claude","sumr playbook clean --dry-run"]};vT=E({name:"clean",description:"Remove SUMR-managed Playbook outputs from the current repo",group:"modules",visibility:"public",help:fT,execute:yT}),t8={DISCARD:"__discard__",SAVE:"__save__"};uT={name:"playbook config",description:"Set up or update Playbook configuration for this repo",usage:["sumr playbook config"],options:[{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook config"]};lT=E({name:"config",description:"Set up or update Playbook configuration for this repo",group:"modules",visibility:"public",help:uT,execute:mT}),Q0={TAGS:"tags",FRAMEWORK:"framework",TECH:"tech",GUIDE:"guide",INSIGHT:"insight",TOPIC:"topic",TEAM_MEMBERS:"teamMembers"},aT={NAME:"name",TITLE:"title",DESCRIPTION:"description",CATEGORY:"category",TARGET:"target",EVENT:"event",MATCHER:"matcher",STATUS_MESSAGE:"statusMessage",LABEL:"label",WHEN:"when",MODEL_TIER:"modelTier"},I0={CHANNELS:"channels",ORDER:"order",REVIEW:"review",TEAM_MEMBER:"team-member",TIMEOUT:"timeout"},F7={TRUE:"true",FALSE:"false"},sT=new Set(["claude","codex","cursor","copilot","gemini","opencode"]),tT=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;Qj=new Set([Q0.TAGS,Q0.FRAMEWORK,Q0.TECH,Q0.GUIDE,Q0.INSIGHT,Q0.TOPIC,I0.TEAM_MEMBER]),Zj=new Set(Object.values(aT));Vj=new Set(Object.values(KT)),Oj=[];Lj={".tm.md":"team-member",".lc.md":"lifecycle",".hk.md":"lifecycle",".wf.md":"workflow",".rf.md":"reference"};OJ={dev:"dev",cache:"cache",bundled:"bundled",missing:"missing"},Rj={always:"always",command:"command"},Nj={none:"none",metadata:"metadata",exports:"exports",resources:"resources",aiResources:"aiResources",aiActivation:"aiActivation"},wj={ACTIVATION:"activation:",AI_RESOURCES:"aiResources:",EXPORTS:"exports:",METADATA:"metadata:",RESOURCES:"resources:",ROOTS:"roots:"};K2=OJ,B2=Rj,n=Nj,f1=wj,aj=["sumr.module.yaml","sumr.module.yml","module.yaml","module.yml"];BS={name:"playbook status",description:"Show Playbook configuration and topic counts for the current repo",usage:["sumr playbook status","sumr playbook status --json"],options:[{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook status"]};jS=E({name:"status",description:"Show Playbook configuration and topic counts for the current repo",group:"modules",visibility:"public",help:BS,execute:TS}),A2={CONFIG:"config",DEFAULT:"default",EXPLICIT:"explicit"},R7={ERROR:"error",SKIP:"skip"},YW={REFERENCE:"reference",TOPIC:"topic"},SS={github:{tracker:"github",label:"GitHub",softwareNames:["GitHub issues","GitHub Projects"],nouns:["issue numbers","#123","GH-123","GitHub issue","GitHub ticket"],defaultPrefix:"GH",rawIssueExample:"4501",normalizedIssueKey:"GH-4501",normalizedKeyPattern:"GH-<number>",referenceExamples:["issue 4501","#4501","issue #4501","GitHub issue 4501","GitHub #4501","GH-4501","github.com/org/repo/issues/4501"],sourceGuidance:"GitHub issue numbers normalize to `GH-<number>`. GitHub Projects cards should still resolve to the underlying issue when one exists.",apiGuidance:"When an MCP/API gives a GitHub issue number, pass the raw number with `--tracker github --issue <number>`."},gitlab:{tracker:"gitlab",label:"GitLab",softwareNames:["GitLab issues"],nouns:["issue IIDs","#123","GL-123","GitLab issue","GitLab ticket"],defaultPrefix:"GL",rawIssueExample:"4501",normalizedIssueKey:"GL-4501",normalizedKeyPattern:"GL-<iid>",referenceExamples:["issue 4501","#4501","issue #4501","GitLab issue 4501","GitLab #4501","GL-4501","gitlab.com/org/repo/-/issues/4501"],sourceGuidance:"GitLab issue IIDs normalize to `GL-<iid>`. Prefer the project-local IID over a global database ID.",apiGuidance:"When an MCP/API gives a GitLab issue IID, pass the raw IID with `--tracker gitlab --issue <iid>`."},jira:{tracker:"jira",label:"Jira",softwareNames:["Jira","Jira Software"],nouns:["ticket","issue","story","bug","task","epic"],defaultPrefix:"PROJECT",rawIssueExample:"PROJECT-123",normalizedIssueKey:"PROJECT-123",normalizedKeyPattern:"<PROJECT>-<number>",referenceExamples:["PROJECT-123","Jira ticket PROJECT-123","story PROJECT-123"],sourceGuidance:"Jira references should use the full project key and number. A bare phrase like `issue 4501` is not enough unless trusted tracker context supplies the project key.",apiGuidance:"When an MCP/API gives a Jira issue key, pass the full key with `--tracker jira --issue <PROJECT-123>`."},linear:{tracker:"linear",label:"Linear",softwareNames:["Linear"],nouns:["issue","ticket","team key","project","cycle"],defaultPrefix:"TEAM",rawIssueExample:"TEAM-123",normalizedIssueKey:"TEAM-123",normalizedKeyPattern:"<TEAM>-<number>",referenceExamples:["TEAM-123","Linear issue TEAM-123","cycle issue TEAM-123"],sourceGuidance:"Linear references should use the full team key and number. A bare phrase like `issue 4501` is not enough unless trusted tracker context supplies the team key.",apiGuidance:"When an MCP/API gives a Linear issue identifier, pass the full key with `--tracker linear --issue <TEAM-123>`."},custom:{tracker:"custom",label:"Custom",softwareNames:["custom notes","local task lists"],nouns:["custom work ID","note","local slug","named task","non-ticket work"],defaultPrefix:"TASK",rawIssueExample:"release-notes-pass",normalizedIssueKey:"release-notes-pass",normalizedKeyPattern:"<local-label>",referenceExamples:["release-notes-pass","checkout race condition","manual QA pass","non-ticket task"],sourceGuidance:"Custom references become safe local Mission IDs. Use this for work that does not have a tracker-owned key.",apiGuidance:'When an MCP/API gives only a name or note title, pass it with `--tracker custom --issue "<local label>"`.'}},CS=["Azure DevOps work items (`AB#123`, `work item 123`)","ClickUp tasks","Asana tasks","Trello cards","Notion tasks"],D0={CUSTOM:"custom",JIRA:"jira",LINEAR:"linear"},F0={BASIC:"basic",PLANNING_ONLY:"planning-only",STANDARD_DELIVERY:"standard-delivery",FULL_DELIVERY:"full-delivery"},x={AUTO:"auto",ASK:"ask",HUMAN:"human",MANUAL:"manual"},u={ISSUE_SYNC:"issue.sync",CONTEXT_RESEARCH:"context.research",PLAN_CREATE:"plan.create",PLAN_APPROVE:"plan.approve",BRANCH_CHECK:"branch.check",WORK_CLAIM:"work.claim",IMPLEMENTATION_REPORT:"implementation.report",REVIEW_REPORT:"review.report",VALIDATION_REPORT:"validation.report",QUALITY_GATE:"quality.gate",PR_PREPARE:"pr.prepare",PR_CREATE:"pr.create",MISSION_CLOSE:"mission.close"},IS=[];hS={claude:[".claude/agents",".claude/hooks",".claude/commands"],codex:[".codex/agents",".codex/hooks"],opencode:[".opencode/agents"]},AJ=[],uS=[],q7=OJ;F={CLAUDE_ONLY:"claude-only",CLOSEOUT:"closeout",COMMAND:"command",CONVENTION:"convention",MAP:"map",OVERVIEW:"overview",RULE:"rule",SECURITY:"security",STARTUP:"startup",STUCK:"stuck"},e7=[F.OVERVIEW,F.STARTUP,F.MAP,F.RULE,F.COMMAND,F.CONVENTION,F.SECURITY,F.CLOSEOUT,F.STUCK,F.CLAUDE_ONLY],i8={ID:"id",ORDER:"order",SCOPE:"scope"},UC=new Set([F.OVERVIEW,F.STUCK]),KW=new Set(Object.values(i8)),w7=/<!--\s*agents-md:([a-z-]+)((?:\s+[a-z]+=[^\s>]+)*)\s*-->([\s\S]*?)<!--\s*\/agents-md:\1\s*-->/g;VC=[];TC=[];CC=[F.STARTUP,F.CLOSEOUT,F.MAP,F.RULE,F.COMMAND,F.CONVENTION,F.SECURITY];RC={};SW=["purpose","before-you-start","mission-issue-routing","repo-map","hard-rules","common-commands","code-conventions","security","closeout","if-stuck"],dC=[],mC=[{id:"root-claude-md",channelIds:["claude"],targetPath:"CLAUDE.md",title:"Claude project memory",sectionIds:[...SW,"claude-specific"],appliesTo:CW},{id:"root-agents-md",channelIds:["codex"],targetPath:"AGENTS.md",title:"Agent instructions",sectionIds:SW,appliesTo:CW}];O$={APPEND:"append",SKIP:"skip",CANCEL:"cancel"};GF=[],hJ=["!docs/standards/devkit/","!docs/standards/devkit/**"],_F={claude:["!.claude/","!.claude/skills/","!.claude/skills/**","!.claude/agents/","!.claude/agents/**","!.claude/hooks/","!.claude/hooks/**","!.claude/commands/","!.claude/commands/**","!.claude/rules/","!.claude/rules/**"],codex:["!.agents/","!.agents/skills/","!.agents/skills/**","!.codex/","!.codex/AGENTS.md","!.codex/config.toml","!.codex/hooks.json","!.codex/agents/","!.codex/agents/**","!.codex/hooks/","!.codex/hooks/**"],cursor:["!.cursor/","!.cursor/rules/","!.cursor/rules/**"],copilot:["!.github/","!.github/instructions/","!.github/instructions/**","!.github/agents/","!.github/agents/**"],gemini:["!.gemini/","!.gemini/skills/","!.gemini/skills/**","!.gemini/agents/","!.gemini/agents/**"],opencode:["!.opencode/","!.opencode/commands/","!.opencode/commands/**","!.opencode/agents/","!.opencode/agents/**"]},YF=[{channelId:"cursor",file:".cursorignore",allowEntries:["!.cursor/","!.cursor/rules/","!.cursor/rules/**"],extraEntryPrefixes:[".cursor/"]},{channelId:"gemini",file:".geminiignore",allowEntries:["!.gemini/","!.gemini/skills/","!.gemini/skills/**","!.gemini/agents/","!.gemini/agents/**"],extraEntryPrefixes:[".gemini/"]}];EF={"*.tm.md":"robot","*.wf.md":"rocket","*.lc.md":"settings","*.hk.md":"settings","*.rf.md":"changelog"};sJ=["team-member"],tJ=["lifecycle","hook"],eJ=["workflow"],NF=[...sJ,...tJ,...eJ];bF=[];yF=["bash","sh","python","py","javascript","js","ts"],XG={};GG=new Set([".sh",".py",".js",".ts"]),eF={},$I={bash:"sh",sh:"sh",python:"py",py:"py",javascript:"js",js:"js",ts:"ts"},QI={bash:"#!/usr/bin/env bash",sh:"#!/bin/sh",python:"#!/usr/bin/env python3",py:"#!/usr/bin/env python3",javascript:"#!/usr/bin/env node",js:"#!/usr/bin/env node",ts:"#!/usr/bin/env bun"};FI=["bash","sh","python","py","javascript","js","ts"],RI=/^#!.*\r?\n# Generated by SUMR Playbook/,PW=/^# Generated by SUMR Playbook\.[^\r\n]*(?:\r?\n|$)/,NI=/\b(?:sumr-devkit\s+sync|sumr\s+playbook\s+sync)\b/;cI={};rI=[["model","model"],["modelReasoningEffort","model_reasoning_effort"],["model_reasoning_effort","model_reasoning_effort"],["sandboxMode","sandbox_mode"],["sandbox_mode","sandbox_mode"],["sandbox-mode","sandbox_mode"]];UD={bash:"sh",sh:"sh",python:"py",py:"py",javascript:"js",js:"js",ts:"ts"},WD={bash:"#!/usr/bin/env bash",sh:"#!/bin/sh",python:"#!/usr/bin/env python3",py:"#!/usr/bin/env python3",javascript:"#!/usr/bin/env node",js:"#!/usr/bin/env node",ts:"#!/usr/bin/env bun"};qD={};AD={mode:"subagent"},MD={channelId:"opencode",outputDir:".opencode/agents",generatedFilePattern:/^sumr-.+\.md$/,defaultProps:AD};LG={claude:KI,codex:VD,cursor:LD,copilot:KD,gemini:BD,opencode:ED};oD={name:"playbook sync",description:"Sync Playbook topics into AI tool channels",usage:["sumr playbook sync","sumr playbook sync --source docs","sumr playbook sync --source docs --channel claude","sumr playbook sync --dry-run","sumr playbook sync --json"],options:[{flag:"--source <path>",description:"Source directory containing canonical .md files (repeatable)"},{flag:"--channel <id>",description:`Channel to sync (one of: ${i$.join(", ")})`},{flag:"--dry-run",description:"Preview changes without writing to disk"},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--verbose",description:"Show detailed warnings, sources, and generated outputs"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook sync","sumr playbook sync --source docs --channel claude","sumr playbook sync --dry-run"]};$R=E({name:"sync",description:"Sync Playbook topics into AI tool channels",group:"modules",visibility:"public",help:oD,execute:sD}),D$={ERROR:"error",WARNING:"warning"},XR={name:"playbook validate",description:"Check Playbook docs for errors without writing any files",usage:["sumr playbook validate","sumr playbook validate --source docs","sumr playbook validate --json"],options:[{flag:"--source <path>",description:"Path to docs folder (overrides sumr.yaml)"},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook validate","sumr playbook validate --json"]};ER=E({name:"validate",description:"Check Playbook docs for errors without writing any files",group:"modules",visibility:"public",help:XR,execute:MR}),TR=K1({name:"playbook",description:"Sync Playbook docs into AI tools",group:"modules",visibility:"public",commands:[lT,$R,ER,jS,xE,vT,XT]})});import{log as NG}from"@clack/prompts";D();import{spawnSync as vQ}from"child_process";function d$($,Q){let Z=process.env[$];if(!Z)return Q;let X=Number(Z);return Number.isFinite(X)?X:Q}var D6=".sumr",kQ=".sumr-local-link",d0="1.1.0",R6="1.3.0",PQ=d$("SUMR_AWS_CREDENTIAL_TIMEOUT_MS",15000),y2=d$("SUMR_TOOL_VERSION_TIMEOUT_MS",5000),fQ=d$("SUMR_KEYCHAIN_COMMAND_TIMEOUT_MS",15000),uR=d$("SUMR_BUILD_COMMAND_TIMEOUT_MS",120000),dR=d$("SUMR_CHECK_COMMAND_TIMEOUT_MS",30000),mR=d$("SUMR_NPM_COMMAND_TIMEOUT_MS",30000),lR=d$("SUMR_TARBALL_CONTENT_BUFFER_BYTES",16777216),v2="1",yQ="SUMR_NO_KEYCHAIN",N6="SUMR_ALLOW_PLAINTEXT_AUTH_FILE",pR=d$("SUMR_LOCAL_CLI_COMMAND_TIMEOUT_MS",120000),w6=d$("SUMR_API_REQUEST_TIMEOUT_MS",30000),b6=d$("SUMR_IDENTITY_REQUEST_TIMEOUT_MS",30000);function xQ(){return{...process.env}}function gQ(){return process.env.SUMR_AWS_BIN?.trim()||"aws"}function hQ(){return vQ(gQ(),["--version"],{stdio:"pipe",env:xQ(),timeout:PQ}).status===0}function uQ(){let $=vQ(gQ(),["--version"],{stdio:"pipe",encoding:"utf8",env:xQ(),timeout:y2});if($.status!==0)return;return`${$.stdout}
|
|
852
|
-
${$.stderr}`.trim()||void 0}var
|
|
853
|
-
`)}function
|
|
854
|
-
`),"SUMR init")}async function
|
|
858
|
+
<!-- /extract:examples -->`,generatedFile:"The marker name becomes a generated section file, for example examples.md inside skill folders, and the skill gets an Additional resources link.",whenToUse:["Long examples","Reusable templates","Dedicated sample sections","Boilerplate that should be available on demand"],keepInline:["Short snippets that are central to the instruction","Small config examples","Directory trees","Schema outlines","ASCII diagrams"]},examples:{overview:XT,reference:UT,folder:JJ,flow:YT,teamMembersRoot:WT,teamMembersDomain:_T,fullStructure:GT},checklist:["Main topics have name, title, and description.","Descriptions explain what plus when and are quoted in YAML.","Main docs include a When to Use section.","Reference files set category: reference.","Reference files have label, when, and order.","Reference files live in the same folder as the main doc.","Splitting starts by choosing the owning context folder before creating files.","Standalone subtopics split into child folders with overview.md; supporting detail splits into same-folder references.","No references/ folder is created manually.","No references frontmatter field is used.","Dedicated examples, samples, and templates use extract markers.","Lifecycle docs include event, target, and optional matcher, timeout, and statusMessage.","When users ask for hooks or automatic AI-tool behavior, create or update a lifecycle doc first; do not hand-edit generated hook outputs as source.","Workflow docs define a user-invoked procedure and optional per-channel command metadata.","Simple workflow docs include a compact arrow flow; branching workflows use Mermaid plus transition rules.","Codex output is generated from canonical team-member/lifecycle docs and uses [features].hooks.","Team-member docs define name, description, and body instructions. Native channel blocks are the escape hatch for tool-specific agent features.","Add a short # comment above every native channel block so humans can scan which AI tool it configures.","Use role archetype names such as orchestrator, product-owner, researcher, planner, implementer, reviewer, and validator as guidance, not required frontmatter.","Generated AI tool folders are not edited as source.","Use {{PLAYBOOK_PATH}} instead of hard-coding docs/ or other source paths in topic bodies.","Module resources are declared in sumr.module.yaml spec.exports.aiResources (module, roots, activation), not hand-wired into Playbook.","Module source topic names are unprefixed; the renderer adds the sumr-<module>: namespace. Never author a source name starting with sumr-.","Command-activated modules document their init command; resources install only after the user runs it."]},mQ=Object.values(v$),lQ=Object.values(ZT);LT={name:"playbook authoring",description:"Print the canonical Playbook Markdown authoring contract",usage:["sumr playbook authoring","sumr playbook authoring --section structure","sumr playbook authoring --example reference","sumr playbook authoring --json"],options:[{flag:"--section <id>",description:`Only print one section (${mQ.join(", ")})`},{flag:"--example <id>",description:`Only print one example (${lQ.join(", ")})`},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook authoring","sumr playbook authoring --section frontmatter","sumr playbook authoring --section structure --json","sumr playbook authoring --example overview"]};TT=T({name:"authoring",description:"Print the canonical Playbook Markdown authoring contract",group:"modules",visibility:"public",help:LT,execute:jT}),E$=[{id:"claude",displayName:"Claude Code",outputDir:".claude/skills",filePattern:/^sumr-.+$/,vscodeExcludePattern:".claude/skills/sumr-*",gitignorePatterns:[".claude/skills/sumr-*/",".claude/agents/sumr-*",".claude/hooks/sumr-*",".claude/commands/sumr-*",".claude/rules/sumr-*"]},{id:"codex",displayName:"Codex CLI",outputDir:".agents/skills",legacyOutputDirs:[".codex/skills"],filePattern:/^sumr-.+$/,vscodeExcludePattern:".agents/skills/sumr-*",gitignorePatterns:[".agents/skills/sumr-*/",".codex/skills/sumr-*/",".codex/agents/sumr-*.toml"]},{id:"cursor",displayName:"Cursor",outputDir:".cursor/rules",filePattern:/^sumr-.+\.mdc$/,vscodeExcludePattern:".cursor/rules/sumr-*",gitignorePatterns:[".cursor/rules/sumr-*"]},{id:"copilot",displayName:"GitHub Copilot",outputDir:".github/instructions",filePattern:/^sumr-.+\.md$/,vscodeExcludePattern:".github/instructions/sumr-*",gitignorePatterns:[".github/instructions/sumr-*",".github/agents/sumr-*"]},{id:"gemini",displayName:"Gemini CLI",outputDir:".gemini/skills",filePattern:/^sumr-.+$/,vscodeExcludePattern:".gemini/skills/sumr-*",gitignorePatterns:[".gemini/skills/sumr-*/",".gemini/agents/sumr-*"]},{id:"opencode",displayName:"OpenCode",outputDir:".opencode/commands",filePattern:/^sumr-.+\.md$/,vscodeExcludePattern:".opencode/commands/sumr-*",gitignorePatterns:[".opencode/commands/sumr-*",".opencode/agents/sumr-*"]}],r$=E$.map(($)=>$.id);wT={PLAYBOOK_PATH:"{{PLAYBOOK_PATH}}",TEAM_MEMBER:"{{TEAM-MEMBER}}",MISSION_TRIGGER_HINTS:"{{MISSION_TRIGGER_HINTS}}",MISSION_IDENTIFIER_GUIDANCE:"{{MISSION_IDENTIFIER_GUIDANCE}}",MISSION_START_EXAMPLES:"{{MISSION_START_EXAMPLES}}",MISSION_FLOW_PRESET:"{{MISSION_FLOW_PRESET}}",MISSION_FLOW_TEXT:"{{MISSION_FLOW_TEXT}}",MISSION_FLOW_STEPS:"{{MISSION_FLOW_STEPS}}",MISSION_PR_MODE:"{{MISSION_PR_MODE}}"};PT={claude:"Subagent",codex:"Subagent",cursor:"Subagent",copilot:"Agent",gemini:"Subagent",opencode:"Agent"};z$={CORE:"core",LOCAL:"local"},_Y={REASONING:"reasoning",CODING:"coding",FAST:"fast"},j2={LOW:"low",MEDIUM:"medium",HIGH:"high"},P2={READ_ONLY:"read-only",WRITE:"write",FULL:"full"},R0={READ:"read",EDIT:"edit",SHELL:"shell",WEB:"web",TODO:"todo",TASK:"task"};uT=/\n?<!--\s*extract:(\w+)\s*-->([\s\S]*?)<!--\s*\/extract:\1\s*-->\n?/g,dT=/```[\s\S]*?```/g,mT=[];sT={name:"playbook clean",description:"Remove SUMR-managed Playbook outputs from the current repo",usage:["sumr playbook clean","sumr playbook clean --channel claude","sumr playbook clean --dry-run","sumr playbook clean --json"],options:[{flag:"--channel <id>",description:`Channel to clean (one of: ${r$.join(", ")})`},{flag:"--dry-run",description:"Preview deletions without writing to disk"},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook clean","sumr playbook clean --channel claude","sumr playbook clean --dry-run"]};eT=T({name:"clean",description:"Remove SUMR-managed Playbook outputs from the current repo",group:"modules",visibility:"public",help:sT,execute:tT}),U8={DISCARD:"__discard__",SAVE:"__save__"};XE={name:"playbook config",description:"Set up or update Playbook configuration for this repo",usage:["sumr playbook config"],options:[{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook config"]};YE=T({name:"config",description:"Set up or update Playbook configuration for this repo",group:"modules",visibility:"public",help:XE,execute:JE}),b1={TAGS:"tags",FRAMEWORK:"framework",TECH:"tech",GUIDE:"guide",INSIGHT:"insight",TOPIC:"topic",TEAM_MEMBERS:"teamMembers",TOOLS:"tools"},KE={NAME:"name",TITLE:"title",DESCRIPTION:"description",CATEGORY:"category",TARGET:"target",EVENT:"event",MATCHER:"matcher",STATUS_MESSAGE:"statusMessage",LABEL:"label",WHEN:"when",MODEL_TIER:"modelTier",EFFORT:"effort",ACCESS:"access"},N0={CHANNELS:"channels",ORDER:"order",REVIEW:"review",TEAM_MEMBER:"team-member",TIMEOUT:"timeout"},PQ={TRUE:"true",FALSE:"false"},qE=new Set(["claude","codex","cursor","copilot","gemini","opencode"]),BE=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;ME=new Set([b1.TAGS,b1.FRAMEWORK,b1.TECH,b1.GUIDE,b1.INSIGHT,b1.TOPIC,b1.TOOLS,N0.TEAM_MEMBER]),jE=new Set(Object.values(KE));jY=new Set(Object.values(_Y)),TY=new Set(Object.values(j2)),EY=new Set(Object.values(P2)),CY=new Set(Object.values(R0)),wE=Object.values(_Y),PE=Object.values(j2),bE=Object.values(P2),kE=Object.values(R0),fE=[];dE={".tm.md":"team-member",".lc.md":"lifecycle",".hk.md":"lifecycle",".wf.md":"workflow",".rf.md":"reference"};IY={dev:"dev",cache:"cache",bundled:"bundled",missing:"missing"},eE={always:"always",command:"command"},$C={none:"none",metadata:"metadata",exports:"exports",resources:"resources",aiResources:"aiResources",aiActivation:"aiActivation"},QC={ACTIVATION:"activation:",AI_RESOURCES:"aiResources:",EXPORTS:"exports:",METADATA:"metadata:",RESOURCES:"resources:",ROOTS:"roots:"};A2=IY,T2=eE,n=$C,y1=QC,TC=["sumr.module.yaml","sumr.module.yml","module.yaml","module.yml"];mC={name:"playbook status",description:"Show Playbook configuration and topic counts for the current repo",usage:["sumr playbook status","sumr playbook status --json"],options:[{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook status"]};iC=T({name:"status",description:"Show Playbook configuration and topic counts for the current repo",group:"modules",visibility:"public",help:mC,execute:nC}),E2={CONFIG:"config",DEFAULT:"default",EXPLICIT:"explicit"},fQ={ERROR:"error",SKIP:"skip"},qJ={REFERENCE:"reference",TOPIC:"topic"},i={ERROR:"error",WARNING:"warning"},rC={github:{tracker:"github",label:"GitHub",softwareNames:["GitHub issues","GitHub Projects"],nouns:["issue numbers","#123","GH-123","GitHub issue","GitHub ticket"],defaultPrefix:"GH",rawIssueExample:"4501",normalizedIssueKey:"GH-4501",normalizedKeyPattern:"GH-<number>",referenceExamples:["issue 4501","#4501","issue #4501","GitHub issue 4501","GitHub #4501","GH-4501","github.com/org/repo/issues/4501"],sourceGuidance:"GitHub issue numbers normalize to `GH-<number>`. GitHub Projects cards should still resolve to the underlying issue when one exists.",apiGuidance:"When an MCP/API gives a GitHub issue number, pass the raw number with `--tracker github --issue <number>`."},gitlab:{tracker:"gitlab",label:"GitLab",softwareNames:["GitLab issues"],nouns:["issue IIDs","#123","GL-123","GitLab issue","GitLab ticket"],defaultPrefix:"GL",rawIssueExample:"4501",normalizedIssueKey:"GL-4501",normalizedKeyPattern:"GL-<iid>",referenceExamples:["issue 4501","#4501","issue #4501","GitLab issue 4501","GitLab #4501","GL-4501","gitlab.com/org/repo/-/issues/4501"],sourceGuidance:"GitLab issue IIDs normalize to `GL-<iid>`. Prefer the project-local IID over a global database ID.",apiGuidance:"When an MCP/API gives a GitLab issue IID, pass the raw IID with `--tracker gitlab --issue <iid>`."},jira:{tracker:"jira",label:"Jira",softwareNames:["Jira","Jira Software"],nouns:["ticket","issue","story","bug","task","epic"],defaultPrefix:"PROJECT",rawIssueExample:"PROJECT-123",normalizedIssueKey:"PROJECT-123",normalizedKeyPattern:"<PROJECT>-<number>",referenceExamples:["PROJECT-123","Jira ticket PROJECT-123","story PROJECT-123"],sourceGuidance:"Jira references should use the full project key and number. A bare phrase like `issue 4501` is not enough unless trusted tracker context supplies the project key.",apiGuidance:"When an MCP/API gives a Jira issue key, pass the full key with `--tracker jira --issue <PROJECT-123>`."},linear:{tracker:"linear",label:"Linear",softwareNames:["Linear"],nouns:["issue","ticket","team key","project","cycle"],defaultPrefix:"TEAM",rawIssueExample:"TEAM-123",normalizedIssueKey:"TEAM-123",normalizedKeyPattern:"<TEAM>-<number>",referenceExamples:["TEAM-123","Linear issue TEAM-123","cycle issue TEAM-123"],sourceGuidance:"Linear references should use the full team key and number. A bare phrase like `issue 4501` is not enough unless trusted tracker context supplies the team key.",apiGuidance:"When an MCP/API gives a Linear issue identifier, pass the full key with `--tracker linear --issue <TEAM-123>`."},custom:{tracker:"custom",label:"Custom",softwareNames:["custom notes","local task lists"],nouns:["custom work ID","note","local slug","named task","non-ticket work"],defaultPrefix:"TASK",rawIssueExample:"release-notes-pass",normalizedIssueKey:"release-notes-pass",normalizedKeyPattern:"<local-label>",referenceExamples:["release-notes-pass","checkout race condition","manual QA pass","non-ticket task"],sourceGuidance:"Custom references become safe local Mission IDs. Use this for work that does not have a tracker-owned key.",apiGuidance:'When an MCP/API gives only a name or note title, pass it with `--tracker custom --issue "<local label>"`.'}},oC=["Azure DevOps work items (`AB#123`, `work item 123`)","ClickUp tasks","Asana tasks","Trello cards","Notion tasks"],w0={CUSTOM:"custom",JIRA:"jira",LINEAR:"linear"},I0={BASIC:"basic",PLANNING_ONLY:"planning-only",STANDARD_DELIVERY:"standard-delivery",FULL_DELIVERY:"full-delivery"},x={AUTO:"auto",ASK:"ask",HUMAN:"human",MANUAL:"manual"},u={ISSUE_SYNC:"issue.sync",CONTEXT_RESEARCH:"context.research",PLAN_CREATE:"plan.create",PLAN_APPROVE:"plan.approve",BRANCH_CHECK:"branch.check",WORK_CLAIM:"work.claim",IMPLEMENTATION_REPORT:"implementation.report",REVIEW_REPORT:"review.report",VALIDATION_REPORT:"validation.report",QUALITY_GATE:"quality.gate",PR_PREPARE:"pr.prepare",PR_CREATE:"pr.create",MISSION_CLOSE:"mission.close"},sC=[];zS={claude:[".claude/agents",".claude/hooks",".claude/commands"],codex:[".codex/agents",".codex/hooks"],opencode:[".opencode/agents"]},PY=[],HS=[],TQ=IY;I={CLAUDE_ONLY:"claude-only",CLOSEOUT:"closeout",COMMAND:"command",CONVENTION:"convention",MAP:"map",OVERVIEW:"overview",RULE:"rule",SECURITY:"security",STARTUP:"startup",STUCK:"stuck"},U5=[I.OVERVIEW,I.STARTUP,I.MAP,I.RULE,I.COMMAND,I.CONVENTION,I.SECURITY,I.CLOSEOUT,I.STUCK,I.CLAUDE_ONLY],e6={ID:"id",ORDER:"order",SCOPE:"scope"},NS=new Set([I.OVERVIEW,I.STUCK]),jJ=new Set(Object.values(e6)),vQ=/<!--\s*agents-md:([a-z-]+)((?:\s+[a-z]+=[^\s>]+)*)\s*-->([\s\S]*?)<!--\s*\/agents-md:\1\s*-->/g;xS=[];nS=[];oS=[I.STARTUP,I.CLOSEOUT,I.MAP,I.RULE,I.COMMAND,I.CONVENTION,I.SECURITY];eS={};NJ=["purpose","before-you-start","mission-issue-routing","repo-map","hard-rules","common-commands","code-conventions","security","closeout","if-stuck"],VF=[],OF=[{id:"root-claude-md",channelIds:["claude"],targetPath:"CLAUDE.md",title:"Claude project memory",sectionIds:[...NJ,"claude-specific"],appliesTo:wJ},{id:"root-agents-md",channelIds:["codex"],targetPath:"AGENTS.md",title:"Agent instructions",sectionIds:NJ,appliesTo:wJ}];q$={APPEND:"append",SKIP:"skip",CANCEL:"cancel"};bF=[],tY=["!docs/standards/devkit/","!docs/standards/devkit/**"],kF={claude:["!.claude/","!.claude/skills/","!.claude/skills/**","!.claude/agents/","!.claude/agents/**","!.claude/hooks/","!.claude/hooks/**","!.claude/commands/","!.claude/commands/**","!.claude/rules/","!.claude/rules/**"],codex:["!.agents/","!.agents/skills/","!.agents/skills/**","!.codex/","!.codex/AGENTS.md","!.codex/config.toml","!.codex/hooks.json","!.codex/agents/","!.codex/agents/**","!.codex/hooks/","!.codex/hooks/**"],cursor:["!.cursor/","!.cursor/rules/","!.cursor/rules/**"],copilot:["!.github/","!.github/instructions/","!.github/instructions/**","!.github/agents/","!.github/agents/**"],gemini:["!.gemini/","!.gemini/skills/","!.gemini/skills/**","!.gemini/agents/","!.gemini/agents/**"],opencode:["!.opencode/","!.opencode/commands/","!.opencode/commands/**","!.opencode/agents/","!.opencode/agents/**"]},fF=[{channelId:"cursor",file:".cursorignore",allowEntries:["!.cursor/","!.cursor/rules/","!.cursor/rules/**"],extraEntryPrefixes:[".cursor/"]},{channelId:"gemini",file:".geminiignore",allowEntries:["!.gemini/","!.gemini/skills/","!.gemini/skills/**","!.gemini/agents/","!.gemini/agents/**"],extraEntryPrefixes:[".gemini/"]}];cF={"*.tm.md":"robot","*.wf.md":"rocket","*.lc.md":"settings","*.hk.md":"settings","*.rf.md":"changelog"};zW=["team-member"],HW=["lifecycle","hook"],VW=["workflow"],$I=[...zW,...HW,...VW];ZI=[];YI={claude:{id:"claude",models:{reasoning:"opus",coding:"sonnet",fast:"haiku"},toolMap:{read:["Read","Grep","Glob"],edit:["Read","Edit","Write"],shell:["Bash"],web:["WebFetch","WebSearch"],todo:["TodoWrite"],task:["Task"]},toolFormat:"comma-string",features:{model:!0,tools:!0,permissions:!1,reasoningEffort:!1,sandbox:!1}},codex:{id:"codex",models:{},features:{model:!0,tools:!1,permissions:!1,reasoningEffort:!0,sandbox:!0}},gemini:{id:"gemini",models:{},toolMap:{read:["read_file","read_many_files","list_directory","glob","grep_search"],edit:["replace","write_file"],shell:["run_shell_command"],web:["web_fetch","google_web_search"],todo:["write_todos"]},toolFormat:"array",features:{model:!0,tools:!0,permissions:!1,reasoningEffort:!1,sandbox:!1}},opencode:{id:"opencode",models:{},toolMap:{read:["read","glob","grep","list"],edit:["edit"],shell:["bash"],web:["webfetch","websearch"],todo:["todowrite"],task:["task"]},toolFormat:"permission",features:{model:!0,tools:!1,permissions:!0,reasoningEffort:!1,sandbox:!1}},copilot:{id:"copilot",models:{},toolMap:{read:["read","search"],edit:["edit"],shell:["execute"],web:["web"],todo:["todo"],task:["agent"]},toolFormat:"array",features:{model:!0,tools:!0,permissions:!1,reasoningEffort:!1,sandbox:!1}},cursor:{id:"cursor",models:{},features:{model:!0,tools:!1,permissions:!1,reasoningEffort:!1,sandbox:!1}}},WI=["Read","Grep","Glob","Edit","Write","Bash","WebFetch","WebSearch","TodoWrite","Task"],_I=["read","glob","grep","list","edit","bash","webfetch","websearch","todowrite","task"],GI={"read-only":[R0.READ],write:[R0.READ,R0.EDIT,R0.SHELL]},zI={"read-only":"read-only",write:"workspace-write",full:"danger-full-access"},HI={reasoning:j2.HIGH,coding:j2.MEDIUM,fast:j2.LOW},yJ={model:["model"],tools:["tools"],permissions:["permission"],reasoningEffort:["model_reasoning_effort","modelReasoningEffort"],sandbox:["sandbox_mode","sandboxMode","sandbox-mode"]};II=["bash","sh","python","py","javascript","js","ts"],AW={};EW=new Set([".sh",".py",".js",".ts"]),pI={},cI={bash:"sh",sh:"sh",python:"py",py:"py",javascript:"js",js:"js",ts:"ts"},nI={bash:"#!/usr/bin/env bash",sh:"#!/bin/sh",python:"#!/usr/bin/env python3",py:"#!/usr/bin/env python3",javascript:"#!/usr/bin/env node",js:"#!/usr/bin/env node",ts:"#!/usr/bin/env bun"};BD=["bash","sh","python","py","javascript","js","ts"],MD=/^#!.*\r?\n# Generated by SUMR Playbook/,uJ=/^# Generated by SUMR Playbook\.[^\r\n]*(?:\r?\n|$)/,jD=/\b(?:sumr-devkit\s+sync|sumr\s+playbook\s+sync)\b/;vD={};hD=[["model","model"],["modelReasoningEffort","model_reasoning_effort"],["model_reasoning_effort","model_reasoning_effort"],["sandboxMode","sandbox_mode"],["sandbox_mode","sandbox_mode"],["sandbox-mode","sandbox_mode"]];oD={bash:"sh",sh:"sh",python:"py",py:"py",javascript:"js",js:"js",ts:"ts"},aD={bash:"#!/usr/bin/env bash",sh:"#!/bin/sh",python:"#!/usr/bin/env python3",py:"#!/usr/bin/env python3",javascript:"#!/usr/bin/env node",js:"#!/usr/bin/env node",ts:"#!/usr/bin/env bun"};YR={};GR={mode:"subagent"},zR={channelId:"opencode",outputDir:".opencode/agents",generatedFilePattern:/^sumr-.+\.md$/,defaultProps:GR};PW={claude:JD,codex:XR,cursor:WR,copilot:JR,gemini:_R,opencode:HR};mR={name:"playbook validate",description:"Check Playbook docs for errors without writing any files",usage:["sumr playbook validate","sumr playbook validate --source docs","sumr playbook validate --json"],options:[{flag:"--source <path>",description:"Path to docs folder (overrides sumr.yaml)"},{flag:"--verbose",description:"On success, also list every source that was checked"},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook validate","sumr playbook validate --verbose","sumr playbook validate --json"]};sR=[/<[a-z][a-z0-9 _-]*command>/i,/<your[ -][^>]*>/i,/<placeholder[^>]*>/i,/\bREPLACE (?:THIS|ME|WITH)\b/i,/\bFILL IN\b/i],tR=/\b(?:use (?:when|this|it|for)|when (?:you|the|a|implementing|adding|debugging|reviewing|writing|creating|editing|working|changing|building)|before |after |during )/i,$N=/\[[^\]]*\]\(([^)]+)\)/g,QN=/(^|\n)( {0,3}```[\s\S]*?(?:\n {0,3}```|$))/g;LN=T({name:"validate",description:"Check Playbook docs for errors without writing any files",group:"modules",visibility:"public",help:mR,execute:BN}),MN={name:"playbook sync",description:"Sync Playbook topics into AI tool channels",usage:["sumr playbook sync","sumr playbook sync --source docs","sumr playbook sync --source docs --channel claude","sumr playbook sync --dry-run","sumr playbook sync --json"],options:[{flag:"--source <path>",description:"Source directory containing canonical .md files (repeatable)"},{flag:"--channel <id>",description:`Channel to sync (one of: ${r$.join(", ")})`},{flag:"--dry-run",description:"Preview changes without writing to disk"},{flag:"--json",description:"Output machine-readable JSON envelope"},{flag:"--verbose",description:"Show detailed warnings, sources, and generated outputs"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr playbook sync","sumr playbook sync --source docs --channel claude","sumr playbook sync --dry-run"]};DN=T({name:"sync",description:"Sync Playbook topics into AI tool channels",group:"modules",visibility:"public",help:MN,execute:SN}),RN=K1({name:"playbook",description:"Sync Playbook docs into AI tools",group:"modules",visibility:"public",commands:[YE,DN,LN,iC,QT,eT,TT]})});import{log as iW}from"@clack/prompts";D();import{spawnSync as m5}from"child_process";function m$($,Q){let Z=process.env[$];if(!Z)return Q;let X=Number(Z);return Number.isFinite(X)?X:Q}var k8=".sumr",g5=".sumr-local-link",c0="1.1.0",f8="1.3.0",h5=m$("SUMR_AWS_CREDENTIAL_TIMEOUT_MS",15000),d2=m$("SUMR_TOOL_VERSION_TIMEOUT_MS",5000),u5=m$("SUMR_KEYCHAIN_COMMAND_TIMEOUT_MS",15000),iN=m$("SUMR_BUILD_COMMAND_TIMEOUT_MS",120000),rN=m$("SUMR_CHECK_COMMAND_TIMEOUT_MS",30000),oN=m$("SUMR_NPM_COMMAND_TIMEOUT_MS",30000),aN=m$("SUMR_TARBALL_CONTENT_BUFFER_BYTES",16777216),m2="1",d5="SUMR_NO_KEYCHAIN",y8="SUMR_ALLOW_PLAINTEXT_AUTH_FILE",sN=m$("SUMR_LOCAL_CLI_COMMAND_TIMEOUT_MS",120000),v8=m$("SUMR_API_REQUEST_TIMEOUT_MS",30000),x8=m$("SUMR_IDENTITY_REQUEST_TIMEOUT_MS",30000);function l5(){return{...process.env}}function p5(){return process.env.SUMR_AWS_BIN?.trim()||"aws"}function c5(){return m5(p5(),["--version"],{stdio:"pipe",env:l5(),timeout:h5}).status===0}function n5(){let $=m5(p5(),["--version"],{stdio:"pipe",encoding:"utf8",env:l5(),timeout:d2});if($.status!==0)return;return`${$.stdout}
|
|
859
|
+
${$.stderr}`.trim()||void 0}var a5="Bun runtime",s5="Bun version",r_="Bun recommended version";function i5($){let Q=$.match(/^v?(\d+)\.(\d+)\.(\d+)/);if(!Q)return;return[Number(Q[1]),Number(Q[2]),Number(Q[3])]}function r5($,Q){let Z=i5($),X=i5(Q);if(!Z||!X)return!1;if(Z[0]!==X[0])return Z[0]>X[0];if(Z[1]!==X[1])return Z[1]>X[1];return Z[2]>=X[2]}function o5($,Q){return $.checks.some((Z)=>Z.label===Q&&Z.required&&!Z.ok)}async function l2(){let $=process.versions.bun,Q=process.versions.node,Z=Boolean($),X=$?r5($,c0):!1,U=$?r5($,f8):!1,J=[{label:a5,ok:Z,required:!0,details:Z?`active (${$})`:`not active (running on Node ${Q})`},{label:s5,ok:X,required:!0,details:$?`${$} (required >= ${c0})`:"unknown (Bun runtime not active)"},{label:r_,ok:U,required:!1,details:$?`${$} (recommended >= ${f8})`:"unknown (Bun runtime not active)"}];return{ok:J.filter((W)=>W.required).every((W)=>W.ok),bunVersion:$,nodeVersion:Q,checks:J}}function p2($,Q={}){let Z=Q.includeDoctorFollowUp??!0,X=["\u26A0 Runtime precheck failed."],U=o5($,a5),J=o5($,s5);if(U)X.push("- SUMR CLI runs on Bun runtime only."),X.push(`- Current runtime: Node ${$.nodeVersion}.`),X.push("- Install Bun: https://bun.sh/docs/installation"),X.push("- Reinstall SUMR with Bun: `bun add -g @sumrco/cli`.");else if(J)X.push(`- Bun ${$.bunVersion??"unknown"} is below required ${c0}.`),X.push(`- Upgrade Bun to >= ${c0}: \`bun upgrade\`.`);else X.push("- Runtime checks failed. Run `sumr doctor` for details.");if(Z)X.push("Run `sumr doctor` for full diagnostics.");return X}var o_={name:"doctor",description:"Check runtime and tool requirements",usage:["sumr doctor"],options:[{flag:"--help, -h",description:"Show command help"}],examples:["sumr doctor"]};function t5($){if($.ok)return E("PASS",["pink","bold"]);return $.required?E("FAIL",["pink","bold"]):E("WARN",["orchid","bold"])}async function a_($){let Q=await l2(),Z=$.visibility==="private",X=Z?c5():!0,U=Z?n5():void 0;console.log(""),console.log(E("SUMR doctor",["purple","bold"])),console.log("");for(let J of Q.checks)console.log(`- ${t5(J)} ${J.label}: ${J.details}`);if(Z)console.log(`- ${t5({ok:X,required:!0})} AWS CLI: ${U??"not found"}`),console.log("");else console.log("");if(!Q.ok){for(let J of p2(Q,{includeDoctorFollowUp:!1}).slice(1))console.log(J);return 1}if(Z&&!X)return console.log(E("Install AWS CLI to use private team commands.","orchid")),1;return console.log(E(Z?"Environment looks good.":"Runtime looks good.","pink")),0}var c2=T({name:"doctor",description:"Check runtime and tool requirements",group:"system",visibility:"public",help:o_,execute:a_});D();import{existsSync as s_}from"fs";import{join as t_}from"path";import{log as g8}from"@clack/prompts";var h8=["docs"],e_=new Set(["source","yes"]),$G=new Set(["input","output"]),QG={claude:!0,codex:!0,cursor:!0,copilot:!1,gemini:!1,opencode:!1},ZG={name:"init",description:"Create a sumr.yaml config for this repository",usage:["sumr init","sumr init --yes","sumr init --source docs,standards"],options:[{flag:"--source <paths>",description:"Private mode: playbook source paths (comma-separated, e.g. docs,standards)"},{flag:"--yes",description:"Skip overwrite prompts and create/update sumr.yaml"},{flag:"--help, -h",description:"Show command help"}],examples:["sumr init","sumr init --yes","sumr init --source docs,standards"]};function XG($,Q,Z,X){let U=$.indexOf("=");if(U!==-1)return X[$.slice(2,U)]=$.slice(U+1),0;let J=Q[Z+1];if(J&&!J.startsWith("-"))return X[$.slice(2)]=J,1;return X[$.slice(2)]=!0,0}function UG($,Q,Z,X){let U=Q[Z+1];if(U&&!U.startsWith("-"))return X[$.slice(1)]=U,1;return X[$.slice(1)]=!0,0}function JG($){let Q={},Z=[];for(let X=0;X<$.length;X+=1){let U=$[X];if(!U)continue;if(U.startsWith("--")){X+=XG(U,$,X,Q);continue}if(U.startsWith("-")&&U.length===2){X+=UG(U,$,X,Q);continue}Z.push(U)}return{positionals:Z,options:Q}}function YG($,Q){let Z=$[Q];return typeof Z==="string"?Z:void 0}function WG($,Q){return Object.hasOwn($,Q)}function _G($,Q){return $[Q]===!0}function GG($){if(!$)return[...h8];let Q=$.split(",").map((Z)=>Z.trim()).filter(Boolean);if(Q.length===0)return[...h8];return Q}function e5(){let $=[];return $.push("# SUMR per-repo configuration"),$.push("# Add product-specific sections only when the repository needs them."),$.push("version: 1"),$.push(""),$.join(`
|
|
860
|
+
`)}function zG($){let Q=[];Q.push("# Playbook"),Q.push("playbook:"),Q.push(" channels:");for(let[Z,X]of Object.entries(QG))Q.push(` ${Z}: ${X}`);Q.push(" sources:");for(let Z of $.sourcePaths)Q.push(` - ${Z}`);return Q}function HG($){return Object.keys($).filter((Q)=>!e_.has(Q))}function VG($){return $.length===1?`-${$}`:`--${$}`}function OG($){let Q=$.map(VG).join(", "),Z=$.length===1?"is":"are";if($.some((U)=>$G.has(U))){console.error(`${Q} ${Z} no longer supported by \`sumr init\`. Configure Kontract with \`kontract.sources\` in sumr.yaml or pass generation flags to \`sumr kontract generate\`.`);return}console.error(`Unsupported init option: ${Q}.`)}async function KG($,Q){if($||!Q)return!0;let{confirm:Z,outro:X,isCancel:U}=await import("@clack/prompts"),J=await Z({message:"sumr.yaml already exists. Update it?",initialValue:!1});if(U(J)||!J)return X("Cancelled \u2014 existing sumr.yaml was not changed."),!1;return!0}function qG($,Q,Z){if(!Q&&!Z.includePlaybook)return W0($,e5()),!0;if(!Z.includePlaybook)return!1;return h1($,"playbook",zG(Z),{fallbackContent:e5(),sectionComment:"# Playbook"}),!0}function BG($,Q){if(!$)return"Created";return Q?"Updated":"Kept existing"}function LG($){return $?`${H1} kept existing module config.`:`${H1} created in this directory.`}function AG($){return $?["Next:"," sumr playbook sync"," sumr --help"]:["Next:"," sumr --help"]}async function MG($,Q,Z,X,U){if(Q){g8.success(`${BG(Z,X)} ${H1} in ${$}`);return}let{note:J}=await import("@clack/prompts");J([LG(Z),"",...AG(U)].join(`
|
|
861
|
+
`),"SUMR init")}async function jG($){if($.args.flags.profile)return g8.error("Use `sumr init` without `--profile`."),1;let Q=JG($.argv.slice(1));if(Q.positionals.length>0)return g8.error("Use `sumr init` with flags only."),1;let Z=HG(Q.options);if(Z.length>0)return OG(Z),1;let X=process.cwd(),U=t_(X,H1),J=_G(Q.options,"yes"),Y=WG(Q.options,"source"),W=$.visibility==="private"&&Y,_=YG(Q.options,"source");if($.visibility!=="private"&&Y)return console.error("`--source` is only available in private mode (when playbook commands are present)."),1;let G={sourcePaths:W?GG(_):[...h8],includePlaybook:W},z=s_(U);if(!await KG(J,z))return 0;let V=qG(U,z,G);return await MG(X,J,z,V,W),0}var $Z=T({name:"init",description:"Create a sumr.yaml config for this repository",group:"system",visibility:"public",help:ZG,execute:jG});D();import{chmodSync as XZ,existsSync as m8,mkdirSync as FG,readFileSync as UZ,rmSync as IG}from"fs";import{homedir as JZ}from"os";import{join as YZ}from"path";import{existsSync as TG,renameSync as EG,rmSync as CG,writeFileSync as SG}from"fs";function u8($,Q,Z){let X=`${$}.sumr-tmp-${process.pid}-${Date.now()}`;try{SG(X,Q,Z),EG(X,$)}finally{if(TG(X))CG(X,{force:!0})}}var DG="auth.json",i2="sumr-cli",r2="default",WZ="SUMR CLI authentication";function i0($=JZ()){return YZ($,k8,DG)}function _Z($=JZ()){FG(YZ($,k8),{recursive:!0,mode:448})}function RG($){if(typeof $!=="object"||$===null)return!1;let Q=$;return typeof Q.accessToken==="string"&&typeof Q.stage==="string"}function QZ($){try{let Q=JSON.parse($);return RG(Q)?Q:null}catch{return null}}function n0($,Q){try{let Z=Bun.spawnSync({cmd:$,stdin:Q===void 0?void 0:new TextEncoder().encode(Q),stdout:"pipe",stderr:"ignore",env:{...process.env},timeout:u5});return{code:Z.exitCode,stdout:new TextDecoder().decode(Z.stdout)}}catch{return{code:-1,stdout:""}}}var NG="$ErrorActionPreference='Stop'; Add-Type -AssemblyName System.Security; $p=[Console]::In.ReadToEnd(); $b=[System.Text.Encoding]::UTF8.GetBytes($p); $e=[System.Security.Cryptography.ProtectedData]::Protect($b,$null,[System.Security.Cryptography.DataProtectionScope]::CurrentUser); [Console]::Out.Write([System.Convert]::ToBase64String($e))",wG="$ErrorActionPreference='Stop'; Add-Type -AssemblyName System.Security; $c=[Console]::In.ReadToEnd().Trim(); $e=[System.Convert]::FromBase64String($c); $b=[System.Security.Cryptography.ProtectedData]::Unprotect($e,$null,[System.Security.Cryptography.DataProtectionScope]::CurrentUser); [Console]::Out.Write([System.Text.Encoding]::UTF8.GetString($b))";function ZZ($,Q){if(!Bun.which("powershell"))return{code:-1,stdout:""};return n0(["powershell","-NoProfile","-NonInteractive","-Command",$],Q)}var PG=`
|
|
855
862
|
import Darwin
|
|
856
863
|
import Foundation
|
|
857
864
|
import Security
|
|
@@ -913,8 +920,8 @@ case "clear":
|
|
|
913
920
|
default:
|
|
914
921
|
exit(64)
|
|
915
922
|
}
|
|
916
|
-
`;function
|
|
917
|
-
`,{encoding:"utf8",mode:384}),
|
|
918
|
-
`)}}async function
|
|
919
|
-
`),"Sign in to SUMR","purple"),
|
|
920
|
-
`),"Signed in","purple"),O1(),0}function
|
|
923
|
+
`;function n2($){return JSON.stringify($).replace(/\$/g,"\\$")}function bG($){return PG.replace("__ACTION__",n2($)).replace("__SERVICE__",n2(i2)).replace("__ACCOUNT__",n2(r2)).replace("__LABEL__",n2(WZ))}function d8($,Q){if(!Bun.which("swift"))return{code:-1,stdout:""};return n0(["swift","-e",bG($)],Q)}var kG={set:($)=>d8("set",$).code===0,get:()=>{let{code:$,stdout:Q}=d8("get");if($!==0)return null;let Z=Q.replace(/\n$/,"");return Z.length>0?Z:null},clear:()=>{d8("clear")}},fG={set:($)=>{if(!Bun.which("secret-tool"))return!1;return n0(["secret-tool","store",`--label=${WZ}`,"service",i2,"account",r2],$).code===0},get:()=>{if(!Bun.which("secret-tool"))return null;let{code:$,stdout:Q}=n0(["secret-tool","lookup","service",i2,"account",r2]);if($!==0||Q.length===0)return null;return Q},clear:()=>{if(!Bun.which("secret-tool"))return;n0(["secret-tool","clear","service",i2,"account",r2])}},GZ={set:($)=>{let{code:Q,stdout:Z}=ZZ(NG,$);if(Q!==0)return!1;let X=Z.trim();if(X.length===0)return!1;try{xG(X)}catch{return!1}return!0},get:()=>{let $=i0();if(!m8($))return null;let Q=gG($);if(Q===null||Q.trim().length===0)return null;let{code:Z,stdout:X}=ZZ(wG,Q);if(Z!==0)return null;let U=X.trim();return U.length>0?U:null},clear:()=>{p8()}};function l8($){if($!==void 0)return null;if(process.env[d5]===m2)return null;if(process.platform==="darwin")return kG;if(process.platform==="linux")return fG;if(process.platform==="win32")return GZ;return null}function zZ($){return $!==void 0||process.env[y8]===m2}function yG(){return Error(`SUMR auth keychain is unavailable. Refusing to write plaintext auth credentials. Set ${y8}=${m2} only for local development or CI isolation.`)}function HZ($,Q){if($!==GZ)p8(Q)}function vG($,Q){_Z(Q);let Z=i0(Q);u8(Z,`${JSON.stringify($,null,2)}
|
|
924
|
+
`,{encoding:"utf8",mode:384}),XZ(Z,384)}function p8($){let Q=i0($);if(m8(Q))IG(Q,{force:!0})}function xG($){_Z();let Q=i0();u8(Q,$,{encoding:"utf8",mode:384}),XZ(Q,384)}function gG($){try{return UZ($,"utf8")}catch{return null}}function z0($){let Q=l8($);if(Q){let X=Q.get(),U=X?QZ(X):null;if(U)return U}let Z=i0($);if(!m8(Z))return null;try{let X=QZ(UZ(Z,"utf8"));if(!X)return null;if(zZ($))return X;if(Q?.set(JSON.stringify(X)))return HZ(Q,$),X;return null}catch{return null}}function o2($,Q){let Z=l8(Q);if(Z?.set(JSON.stringify($))){HZ(Z,Q);return}if(!zZ(Q))throw yG();vG($,Q)}function a2($){let Q=l8($);if(Q)Q.clear();p8($)}function VZ($){if($.expiresAt===void 0)return!1;return Date.now()>=$.expiresAt}function OZ($,Q=300000){if($.expiresAt===void 0)return!1;return Date.now()>=$.expiresAt-Q}var r0={AuthorizationPending:"authorization_pending",SlowDown:"slow_down",AccessDenied:"access_denied",ExpiredToken:"expired_token"},c8={Team:"team",Personal:"personal"};class o0 extends Error{constructor(){super("Login cancelled.");this.name="LoginCancelledError"}}function S$($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function F$($){return $===void 0||typeof $==="string"}function s2($){return $ instanceof Error&&($.name==="AbortError"||$.message.toLowerCase().includes("aborted"))}function a0($){return $ instanceof Error?$.message:String($)}var hG="urn:ietf:params:oauth:grant-type:device_code",uG="refresh_token";function dG($){return $===void 0||typeof $==="number"}function mG($){if(!S$($))return!1;return F$($.sub)&&F$($.email)&&F$($.name)}function lG($){if(!S$($))return!1;return typeof $.deviceCode==="string"&&typeof $.userCode==="string"&&typeof $.verificationUri==="string"&&F$($.verificationUriComplete)&&typeof $.expiresIn==="number"&&typeof $.interval==="number"}function KZ($){if(!S$($))return!1;return typeof $.access_token==="string"&&F$($.refresh_token)&&F$($.id_token)&&F$($.token_type)&&dG($.expires_in)}function pG($){if(!S$($))return!1;return typeof $.error==="string"&&F$($.error_description)}async function qZ($){try{return await $.text()}catch(Q){return`Unable to read response body: ${a0(Q)}`}}async function t2($,Q){try{return await $.json()}catch(Z){throw Error(`${Q} returned invalid JSON: ${a0(Z)}`)}}function BZ($){try{let Q=$.split(".");if(Q.length!==3||!Q[1])return{};let Z=Q[1].replace(/-/g,"+").replace(/_/g,"/"),X=atob(Z),U=JSON.parse(X);return mG(U)?U:{}}catch{return{}}}function cG($){return new Promise((Q)=>setTimeout(Q,$))}function nG($,Q){switch($){case r0.AuthorizationPending:return Q;case r0.SlowDown:return Q+5;case r0.AccessDenied:throw Error("Access denied. You declined the login request in the browser.");case r0.ExpiredToken:throw Error("Device code expired. Run `sumr login` to try again.");default:throw Error(`Unexpected error from auth server: ${$}`)}}function n8($){if($?.aborted)throw new o0}async function i8($,Q,Z){let X=new AbortController,U=setTimeout(()=>X.abort(),x8),J=()=>X.abort();if(Z?.aborted)X.abort();else Z?.addEventListener("abort",J,{once:!0});try{return await fetch($,{...Q,signal:X.signal})}catch(Y){if(s2(Y))throw n8(Z),Error(`SUMR identity request timed out after ${x8}ms.`);throw Y}finally{clearTimeout(U),Z?.removeEventListener("abort",J)}}function iG($,Q){let Z=BZ(Q.access_token),X=Q.expires_in?Date.now()+Q.expires_in*1000:void 0;return{stage:$,accessToken:Q.access_token,refreshToken:Q.refresh_token,tokenType:Q.token_type??"Bearer",expiresAt:X,createdAt:new Date().toISOString(),user:{id:Z.sub,email:Z.email,name:Z.name}}}async function rG($){try{let Q=await t2($,"Device token error response");if(!pG(Q))throw Error("Device token error response did not match the expected shape.");return Q.error}catch{throw Error(`Device token poll failed (${$.status})`)}}async function oG($,Q){let Z=await t2($,"Device token response");if(!KZ(Z))throw Error("Device token response did not match the expected shape.");return iG(Q,Z)}async function aG($,Q,Z,X,U){let J=await i8(Q,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grantType:hG,deviceCode:X,clientId:Z})},U);if(J.ok)return{kind:"approved",session:await oG(J,$)};return{kind:"pending",errorCode:await rG(J)}}async function LZ($){let Q=`${$.apiBaseUrl}/v3/identity/device/code`,Z=await i8(Q,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({clientId:$.clientId,scope:$.scope})});if(!Z.ok){let U=await qZ(Z);throw Error(`Device code request failed (${Z.status}): ${U}`)}let X=await t2(Z,"Device code response");if(!lG(X))throw Error("Device code response did not match the expected shape.");return X}async function AZ($,Q,Z,X,U){let J=`${Q.apiBaseUrl}/v3/identity/device/token`,Y=X;for(;;){n8(U),await cG(Y*1000),n8(U);let W=await aG($,J,Q.clientId,Z,U);if(W.kind==="approved")return W.session;Y=nG(W.errorCode,Y)}}async function MZ($,Q){if(!$.refreshToken)throw Error("No refresh token available.");let Z=`${Q.apiBaseUrl}/v3/identity/oauth/token`,X=await i8(Z,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grantType:uG,clientId:Q.clientId,refreshToken:$.refreshToken})});if(!X.ok){let W=await qZ(X);throw Error(`Token refresh failed (${X.status}): ${W}`)}let U=await t2(X,"Token refresh response");if(!KZ(U))throw Error("Token refresh response did not match the expected shape.");let J=BZ(U.access_token),Y=U.expires_in?Date.now()+U.expires_in*1000:void 0;return{...$,accessToken:U.access_token,refreshToken:U.refresh_token??$.refreshToken,tokenType:U.token_type??$.tokenType,expiresAt:Y,user:{id:J.sub??$.user?.id,email:J.email??$.user?.email,name:J.name??$.user?.name}}}import{log as EZ}from"@clack/prompts";class e2 extends Error{status;details;constructor($,Q){super(`SUMR API request failed (${$}).`);this.name="SumrApiError",this.status=$,this.details=Q}}function sG($){return`Bearer ${$.accessToken}`}function tG($,Q){return{accept:"application/json",authorization:sG($),...Q?{"content-type":"application/json"}:{}}}async function jZ($){try{return await $.text()}catch(Q){return Q instanceof Error?Q.message:String(Q)}}async function eG($){let Q=await jZ($);if(!Q)return;try{return JSON.parse(Q)}catch(Z){let X=Z instanceof Error?Z.message:String(Z);throw Error(`SUMR API returned invalid JSON: ${X}`)}}async function $4($,Q){let Z=new AbortController,X=setTimeout(()=>Z.abort(),v8);try{return await fetch($,{...Q,signal:Z.signal})}catch(U){if(s2(U))throw Error(`SUMR API request timed out after ${v8}ms.`);throw U}finally{clearTimeout(X)}}async function TZ($,Q,Z,X={}){let U=X.body===void 0?void 0:JSON.stringify(X.body),J=await $4(`${$.apiBaseUrl}${Z}`,{method:X.method??"GET",headers:tG(Q,U!==void 0),body:U});if(!J.ok)throw new e2(J.status,await jZ(J));return eG(J)}var SZ="prod",d1={apiBaseUrl:"https://api.sumr.co",clientId:"sumr-cli",scope:"openid offline organizations:read organizations:write api-keys:read api-keys:write"};async function CZ($,Q){if(!$.refreshToken)return null;try{let Z=await MZ($,d1);return o2(Z,Q),Z}catch(Z){return a0(Z),null}}async function FZ($){let Q=z0($);if(!Q)throw EZ.error("Not signed in. Run `sumr login` first."),Error("Not signed in.");if(VZ(Q)){let Z=await CZ(Q,$);if(!Z)throw a2($),EZ.error("Session expired. Run `sumr login` to sign in again."),Error("Session expired.");return Z}if(OZ(Q))return await CZ(Q,$)??Q;return Q}async function IZ($,Q,Z={}){return TZ(d1,$,Q,Z)}var Q4={name:"login",description:"Sign in to SUMR",usage:["sumr login"],options:[{flag:"--help, -h",description:"Show command help"}],examples:["sumr login"]};function Z4($){try{return new URL($).protocol==="https:"}catch{return!1}}function X4($){if(!Z4($))return;try{let Q=process.platform==="win32"?["cmd","/c","start","",$]:process.platform==="darwin"?["open",$]:["xdg-open",$];Bun.spawn(Q,{stdout:"ignore",stderr:"ignore",env:{...process.env},timeout:d2})}catch{}}function U4($){return/Unable to connect|access the url|typo in the url or port|fetch failed|Could not resolve host|getaddrinfo|ENOTFOUND|ECONNREFUSED|connection refused/i.test($)}function J4($){if(!U4($))return{summary:$};return{summary:"Unable to connect to the prod auth API.",details:[`Target: ${d1.apiBaseUrl}`,"Retry later or contact SUMR support if the problem continues.",`Cause: ${$}`].join(`
|
|
925
|
+
`)}}async function Y4($,Q){Q.start("Waiting for browser sign-in...");let Z=new AbortController,X=()=>{Z.abort()};process.on("SIGINT",X);try{let U=await AZ(SZ,d1,$.deviceCode,$.interval,Z.signal);return Q.stop("Sign-in approved."),{kind:"ok",session:U}}catch(U){if(Q.stop(""),U instanceof o0||Z.signal.aborted)return{kind:"cancelled"};return{kind:"error",message:U instanceof Error?U.message:String(U)}}finally{process.off("SIGINT",X)}}async function W4(){let{spinner:$}=await import("@clack/prompts"),Q=$(V1("purple"));Q.start("Requesting sign-in code...");let Z;try{Z=await LZ(d1),Q.stop("Sign-in code ready.")}catch(X){return Q.stop(""),{kind:"error",message:X instanceof Error?X.message:String(X)}}return u$(["Open this URL in your browser:",` ${Z.verificationUriComplete??Z.verificationUri}`,"",`If prompted, enter this code: ${Z.userCode}`,"",`Code expires in ${Math.floor(Z.expiresIn/60)} minutes.`].join(`
|
|
926
|
+
`),"Sign in to SUMR","purple"),X4(Z.verificationUriComplete??Z.verificationUri),Y4(Z,$(V1("purple")))}async function _4($){if($.args.flags.profile)return L$("`sumr login` does not accept --profile."),1;if($.argv.length>1)return L$("Unexpected argument: public login targets SUMR production only."),1;r("sumr");let Q=z0();if(Q){let U=Q.user?.email??Q.user?.name??"your account";return _0(`Already signed in as ${U}. Run \`sumr logout\` first.`),1}let Z=await W4();if(Z.kind==="cancelled")return _0("Sign-in cancelled."),1;if(Z.kind==="error"){let U=J4(Z.message);return L$(`Sign-in failed: ${U.summary}`,{details:U.details,title:"Auth target"}),1}o2(Z.session);let X=Z.session.user?.email??Z.session.user?.name??`account on ${d1.apiBaseUrl.replace("https://","")}`;return f(`Signed in as ${X}.`),O1(),0}var DZ=T({name:"login",description:"Sign in to SUMR",group:"auth",visibility:"public",help:Q4,execute:_4});D();var G4={name:"logout",description:"Sign out of SUMR",usage:["sumr logout"],options:[{flag:"--help, -h",description:"Show command help"}],examples:["sumr logout"]};async function z4($){r("sumr");let Q=z0();if(!Q)return o$("Not signed in."),O1(),0;a2();let Z=Q.user?.email??Q.user?.name??"your account";return f(`Signed out of ${Z}.`),O1(),0}var RZ=T({name:"logout",description:"Sign out of SUMR",group:"auth",visibility:"public",help:G4,execute:z4});D();function H4($){return $===c8.Team||$===c8.Personal}function V4($){if(!S$($))return!1;return typeof $.id==="string"&&typeof $.organizationId==="string"&&typeof $.principalId==="string"&&typeof $.role==="string"&&typeof $.status==="string"&&F$($.invitedBy)&&F$($.acceptedAt)&&typeof $.createdAt==="string"}function O4($){if(!S$($))return!1;return typeof $.id==="string"&&typeof $.slug==="string"&&typeof $.name==="string"&&H4($.kind)}function K4($){if(!S$($))return!1;return V4($.membership)&&O4($.organization)}function q4($){return S$($)&&Array.isArray($.data)&&$.data.every(K4)}function NZ($){if(!q4($))throw Error("SUMR API /v3/me/organizations response did not match the expected shape.");return $}var B4={name:"whoami",description:"Show the currently signed-in user",usage:["sumr whoami"],options:[{flag:"--help, -h",description:"Show command help"}],examples:["sumr whoami"]};function L4($){if($===void 0)return"unknown";let Q=$-Date.now();if(Q<=0)return"expired";let Z=Math.floor(Q/60000);if(Z<60)return`in ${Z} minute${Z===1?"":"s"}`;let X=Math.floor(Z/60);return`in ${X} hour${X===1?"":"s"}`}async function A4($){r("sumr");let Q=await FZ(),Z=NZ(await IZ(Q,"/v3/me/organizations")),X=[];if(Q.user?.email)X.push(Q.user.email);if(Q.user?.name&&Q.user.name!==Q.user.email)X[0]=X[0]?`${X[0]} (${Q.user.name})`:Q.user.name;return X.push(`Stage: ${Q.stage}`),X.push(`Token expires: ${L4(Q.expiresAt)}`),X.push("API: connected"),X.push(`Organizations: ${Z.data.length}`),u$(X.join(`
|
|
927
|
+
`),"Signed in","purple"),O1(),0}function M4($){if($ instanceof e2){let Q=$.details.trim();return Q?`API check failed (${$.status}): ${Q}`:`API check failed (${$.status}).`}return $ instanceof Error?$.message:"Unable to reach SUMR API."}var wZ=T({name:"whoami",description:"Show the currently signed-in user",group:"auth",visibility:"public",help:B4,execute:async($)=>{try{return await A4($)}catch(Q){throw Error(M4(Q))}}});D();function $6($,Q){let Z;async function X(){if(!Z)Z=u2(await $());return Z}return{name:Q.name,description:Q.description,group:Q.group,visibility:Q.visibility,run:async(U)=>(await X()).run(U)}}var NN=$6(()=>Promise.resolve().then(() => (HU(),zU)).then(($)=>$.kontractModule),{name:"kontract",description:"Generate and validate API contract code",group:"modules",visibility:"public"}),wN=$6(()=>Promise.resolve().then(() => (ZJ(),QJ)).then(($)=>$.missionModule),{name:"mission",description:"File-backed execution state for AI-assisted work",group:"modules",visibility:"public"}),PN=$6(()=>Promise.resolve().then(() => (hW(),gW)).then(($)=>$.playbookModule),{name:"playbook",description:"Sync Playbook docs into AI tools (Claude, Cursor, Codex, VS Code)",group:"modules",visibility:"public"});function uW(){return[DZ,RZ,wZ,$Z,c2,NN,wN,PN]}D();import{log as gN}from"@clack/prompts";D();import{existsSync as mW,readFileSync as bN}from"fs";import{dirname as dW,join as B5}from"path";import{fileURLToPath as kN}from"url";var S8="0.0.0";function fN($){if(!S$($))return;return typeof $.version==="string"?$.version:void 0}function F8($=import.meta.url){let Q=dW(kN($));for(;;){if(mW(B5(Q,"package.json")))return Q;let Z=dW(Q);if(Z===Q)return;Q=Z}}function lW($){try{let Q=bN(B5($,"package.json"),"utf8"),Z=JSON.parse(Q);return fN(Z)??S8}catch{return S8}}function pW($=F8()){return Boolean($&&mW(B5($,g5)))}var cW=[" _____ __ __ _____ _____ ","| __|__|__| | __ |","|__ | | | | | | -|","|_____|_____|_|_|_|__|__|"],yN="\u2508".repeat(Math.max(...cW.map(($)=>$.length)));function L5(){if(typeof SUMR_CLI_VERSION==="string"&&SUMR_CLI_VERSION.trim())return SUMR_CLI_VERSION;let $=F8();if(!$)return S8;return lW($)}function vN(){let $=F8();if(!pW($))return"";return E("(Local-Test)","orange")}function xN($){return $==="private"?"\uD83D\uDD12":"\uD83C\uDF10"}function k2($){console.log("");for(let J of cW)console.log(J);console.log(E(yN,["mauve","dim"]));let Q=vN(),Z=xN($),X=E("|",["mauve","dim"]),U=[Z,E(`v${L5()}`,["mauve","dim"]),Q].filter(Boolean).join(` ${X} `);console.log(U),console.log("")}async function nW($){let Q=h2($.argv),Z=new Map($.commands.map((U)=>[U.name,U]));if(!Q.command)return k2($.visibility),console.log(u1($.commands,$.visibility)),0;if(Q.command==="--help"||Q.command==="-h")return k2($.visibility),console.log(u1($.commands,$.visibility)),0;if(Q.command==="--version"||Q.command==="-v")return console.log(L5()),0;let X=Z.get(Q.command);if(!X)return k2($.visibility),console.error(`Unknown command: ${Q.command}`),console.log(u1($.commands,$.visibility)),1;if(X.name!==c2.name){let U=await l2();if(!U.ok){k2($.visibility);for(let J of p2(U))console.error(J);return 1}}try{return await X.run({argv:$.argv,args:Q,visibility:$.visibility})}catch(U){let J=U instanceof Error?U.message:"Unexpected error.";return gN.error(J),1}}try{let $=await nW({argv:process.argv.slice(2),commands:uW(),visibility:"public"});process.exit($)}catch($){let Q=$ instanceof Error?$.message:String($);iW.error(`sumr: ${Q}`),iW.warn("Run `sumr doctor` to diagnose your installation."),process.exit(1)}
|