@willbooster/shared-lib 10.4.0 → 10.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/error.cjs +1 -1
- package/dist/error.cjs.map +1 -1
- package/dist/error.js +1 -1
- package/dist/error.js.map +1 -1
- package/dist/githubTemplates.cjs +4 -3
- package/dist/githubTemplates.cjs.map +1 -1
- package/dist/githubTemplates.d.ts +9 -0
- package/dist/githubTemplates.js +4 -3
- package/dist/githubTemplates.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/dist/testingRules.cjs +6 -0
- package/dist/testingRules.cjs.map +1 -0
- package/dist/testingRules.d.ts +6 -0
- package/dist/testingRules.js +6 -0
- package/dist/testingRules.js.map +1 -0
- package/dist/text.cjs +2 -0
- package/dist/text.cjs.map +1 -0
- package/dist/text.d.ts +4 -0
- package/dist/text.js +2 -0
- package/dist/text.js.map +1 -0
- package/package.json +8 -8
package/dist/error.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";const e=require("./sleep.cjs");function t(e){
|
|
1
|
+
"use strict";const e=require("./sleep.cjs");function t(e){return e instanceof Error?e:Error(typeof e==`string`?e:n(()=>JSON.stringify(e))??n(()=>String(e)))}function n(e){try{return e()}catch{}}function r(e){try{return e()}catch(e){if(typeof e==`object`&&e&&`code`in e&&e.code===`ENOENT`)return;throw e}}async function i(e){try{return await e()}catch{}}async function a(e){try{return await e()}catch(e){if(typeof e==`object`&&e&&`code`in e&&e.code===`ENOENT`)return;throw e}}async function o(t,{beforeRetry:n,handleError:r,retryCount:i=3,retryLogger:a,shouldRetry:o,sleepMilliseconds:s=0,updateSleepMilliseconds:c}={}){let l=0;for(;;)try{return await t(l)}catch(t){if(await r?.(t),l++,l>=i||o&&!o(t))throw t;s>0&&await e.sleep(s),c&&(s=c(s)),a?.(`Retry due to: ${t}
|
|
2
2
|
${t instanceof Error?`---
|
|
3
3
|
`+(t.stack??``):``}`),await n?.(t)}}exports.errorify=t,exports.ignoreEnoent=r,exports.ignoreEnoentAsync=a,exports.ignoreError=n,exports.ignoreErrorAsync=i,exports.withRetry=o;
|
|
4
4
|
//# sourceMappingURL=error.cjs.map
|
package/dist/error.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.cjs","names":["sleep"],"sources":["../src/error.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n/**\n * Convert an object to an error.\n * @param obj The object to convert.\n */\nexport function errorify(obj: unknown): Error {\n if (obj instanceof Error) return obj;\n if (typeof obj === 'string') return new Error(obj);\n
|
|
1
|
+
{"version":3,"file":"error.cjs","names":["sleep"],"sources":["../src/error.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n/**\n * Convert an object to an error.\n * @param obj The object to convert.\n */\nexport function errorify(obj: unknown): Error {\n if (obj instanceof Error) return obj;\n if (typeof obj === 'string') return new Error(obj);\n // `JSON.stringify` answers `undefined` for `undefined`, a symbol and a function, and throws\n // on a bigint or a cycle; `new Error(undefined)` has an empty message, which would drop the\n // only diagnostic a caller has about such a thrown value. Neither representation may throw\n // out of here: this runs in a catch block, where it would replace the error it converts.\n return new Error(ignoreError(() => JSON.stringify(obj)) ?? ignoreError(() => String(obj)));\n}\n\nexport function ignoreError<T>(fn: () => T): T | undefined {\n try {\n return fn();\n } catch {\n // do nothing\n }\n}\n\nexport function ignoreEnoent<T>(fn: () => T): T | undefined {\n try {\n return fn();\n } catch (error) {\n if (typeof error === 'object' && error && 'code' in error && error.code === 'ENOENT') {\n return;\n }\n throw error;\n }\n}\n\nexport async function ignoreErrorAsync<T>(fn: () => Promise<T>): Promise<T | undefined> {\n try {\n return await fn();\n } catch {\n // do nothing\n }\n}\n\nexport async function ignoreEnoentAsync<T>(fn: () => Promise<T>): Promise<T | undefined> {\n try {\n return await fn();\n } catch (error) {\n if (typeof error === 'object' && error && 'code' in error && error.code === 'ENOENT') {\n return;\n }\n throw error;\n }\n}\n\nexport interface RetryOptions {\n beforeRetry?: (error: unknown) => Promise<void>;\n handleError?: (error: unknown) => Promise<void>;\n /**\n * The maximum number of total attempts, including the initial attempt.\n * For example, `retryCount: 3` runs the function at most 3 times: 1 initial attempt and up to 2 retries.\n */\n retryCount?: number;\n retryLogger?: (message: string) => void;\n shouldRetry?: (error: unknown) => boolean;\n sleepMilliseconds?: number;\n updateSleepMilliseconds?: (sleepMilliseconds: number) => number;\n}\n\n/**\n * Retry the given function.\n * @param func The function to retry.\n * @param beforeRetry The function to call immediately before retrying.\n * @param handleError The function to call when an error occurs.\n * @param retryCount The maximum number of total attempts, including the initial attempt.\n * @param retryLogger The function to log retrying.\n * @param sleepMilliseconds The number of milliseconds to sleep before retrying.\n * @param updateSleepMilliseconds The function to update sleep milliseconds after each retry.\n */\nexport async function withRetry<T>(\n func: (failedCount: number) => T | Promise<T>,\n {\n beforeRetry,\n handleError,\n retryCount = 3,\n retryLogger,\n shouldRetry,\n sleepMilliseconds = 0,\n updateSleepMilliseconds,\n }: RetryOptions = {}\n): Promise<T> {\n let failedCount = 0;\n for (;;) {\n try {\n return await func(failedCount);\n } catch (error) {\n await handleError?.(error);\n failedCount++;\n if (failedCount >= retryCount) {\n throw error;\n }\n if (shouldRetry && !shouldRetry(error)) {\n throw error;\n }\n if (sleepMilliseconds > 0) {\n await sleep(sleepMilliseconds);\n }\n if (updateSleepMilliseconds) {\n sleepMilliseconds = updateSleepMilliseconds(sleepMilliseconds);\n }\n retryLogger?.(`Retry due to: ${error}\n${error instanceof Error ? '---\\n' + (error.stack ?? '') : ''}`);\n await beforeRetry?.(error);\n }\n }\n}\n"],"mappings":"4CAMA,SAAgB,EAAS,EAAqB,CAO5C,OANI,aAAe,MAAc,EACO,MAApC,OAAO,GAAQ,SAA2B,EAK7B,MAAkB,KAAK,UAAU,CAAG,CAAC,GAAK,MAAkB,OAAO,CAAG,CAAC,CALvC,CAMnD,CAEA,SAAgB,EAAe,EAA4B,CACzD,GAAI,CACF,OAAO,EAAG,CACZ,MAAQ,CAER,CACF,CAEA,SAAgB,EAAgB,EAA4B,CAC1D,GAAI,CACF,OAAO,EAAG,CACZ,OAAS,EAAO,CACd,GAAI,OAAO,GAAU,UAAY,GAAS,SAAU,GAAS,EAAM,OAAS,SAC1E,OAEF,MAAM,CACR,CACF,CAEA,eAAsB,EAAoB,EAA8C,CACtF,GAAI,CACF,OAAO,MAAM,EAAG,CAClB,MAAQ,CAER,CACF,CAEA,eAAsB,EAAqB,EAA8C,CACvF,GAAI,CACF,OAAO,MAAM,EAAG,CAClB,OAAS,EAAO,CACd,GAAI,OAAO,GAAU,UAAY,GAAS,SAAU,GAAS,EAAM,OAAS,SAC1E,OAEF,MAAM,CACR,CACF,CA0BA,eAAsB,EACpB,EACA,CACE,cACA,cACA,aAAa,EACb,cACA,cACA,oBAAoB,EACpB,2BACgB,CAAC,EACP,CACZ,IAAI,EAAc,EAClB,OACE,GAAI,CACF,OAAO,MAAM,EAAK,CAAW,CAC/B,OAAS,EAAO,CAMd,GALA,MAAM,IAAc,CAAK,EACzB,IACI,GAAe,GAGf,GAAe,CAAC,EAAY,CAAK,EACnC,MAAM,EAEJ,EAAoB,GACtB,MAAMA,EAAAA,MAAM,CAAiB,EAE3B,IACF,EAAoB,EAAwB,CAAiB,GAE/D,IAAc,iBAAiB,EAAM;EACzC,aAAiB,MAAQ;GAAW,EAAM,OAAS,IAAM,IAAI,EACzD,MAAM,IAAc,CAAK,CAC3B,CAEJ"}
|
package/dist/error.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{sleep as e}from"./sleep.js";function t(e){
|
|
1
|
+
import{sleep as e}from"./sleep.js";function t(e){return e instanceof Error?e:Error(typeof e==`string`?e:n(()=>JSON.stringify(e))??n(()=>String(e)))}function n(e){try{return e()}catch{}}function r(e){try{return e()}catch(e){if(typeof e==`object`&&e&&`code`in e&&e.code===`ENOENT`)return;throw e}}async function i(e){try{return await e()}catch{}}async function a(e){try{return await e()}catch(e){if(typeof e==`object`&&e&&`code`in e&&e.code===`ENOENT`)return;throw e}}async function o(t,{beforeRetry:n,handleError:r,retryCount:i=3,retryLogger:a,shouldRetry:o,sleepMilliseconds:s=0,updateSleepMilliseconds:c}={}){let l=0;for(;;)try{return await t(l)}catch(t){if(await r?.(t),l++,l>=i||o&&!o(t))throw t;s>0&&await e(s),c&&(s=c(s)),a?.(`Retry due to: ${t}
|
|
2
2
|
${t instanceof Error?`---
|
|
3
3
|
`+(t.stack??``):``}`),await n?.(t)}}export{t as errorify,r as ignoreEnoent,a as ignoreEnoentAsync,n as ignoreError,i as ignoreErrorAsync,o as withRetry};
|
|
4
4
|
//# sourceMappingURL=error.js.map
|
package/dist/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","names":[],"sources":["../src/error.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n/**\n * Convert an object to an error.\n * @param obj The object to convert.\n */\nexport function errorify(obj: unknown): Error {\n if (obj instanceof Error) return obj;\n if (typeof obj === 'string') return new Error(obj);\n
|
|
1
|
+
{"version":3,"file":"error.js","names":[],"sources":["../src/error.ts"],"sourcesContent":["import { sleep } from './sleep.js';\n\n/**\n * Convert an object to an error.\n * @param obj The object to convert.\n */\nexport function errorify(obj: unknown): Error {\n if (obj instanceof Error) return obj;\n if (typeof obj === 'string') return new Error(obj);\n // `JSON.stringify` answers `undefined` for `undefined`, a symbol and a function, and throws\n // on a bigint or a cycle; `new Error(undefined)` has an empty message, which would drop the\n // only diagnostic a caller has about such a thrown value. Neither representation may throw\n // out of here: this runs in a catch block, where it would replace the error it converts.\n return new Error(ignoreError(() => JSON.stringify(obj)) ?? ignoreError(() => String(obj)));\n}\n\nexport function ignoreError<T>(fn: () => T): T | undefined {\n try {\n return fn();\n } catch {\n // do nothing\n }\n}\n\nexport function ignoreEnoent<T>(fn: () => T): T | undefined {\n try {\n return fn();\n } catch (error) {\n if (typeof error === 'object' && error && 'code' in error && error.code === 'ENOENT') {\n return;\n }\n throw error;\n }\n}\n\nexport async function ignoreErrorAsync<T>(fn: () => Promise<T>): Promise<T | undefined> {\n try {\n return await fn();\n } catch {\n // do nothing\n }\n}\n\nexport async function ignoreEnoentAsync<T>(fn: () => Promise<T>): Promise<T | undefined> {\n try {\n return await fn();\n } catch (error) {\n if (typeof error === 'object' && error && 'code' in error && error.code === 'ENOENT') {\n return;\n }\n throw error;\n }\n}\n\nexport interface RetryOptions {\n beforeRetry?: (error: unknown) => Promise<void>;\n handleError?: (error: unknown) => Promise<void>;\n /**\n * The maximum number of total attempts, including the initial attempt.\n * For example, `retryCount: 3` runs the function at most 3 times: 1 initial attempt and up to 2 retries.\n */\n retryCount?: number;\n retryLogger?: (message: string) => void;\n shouldRetry?: (error: unknown) => boolean;\n sleepMilliseconds?: number;\n updateSleepMilliseconds?: (sleepMilliseconds: number) => number;\n}\n\n/**\n * Retry the given function.\n * @param func The function to retry.\n * @param beforeRetry The function to call immediately before retrying.\n * @param handleError The function to call when an error occurs.\n * @param retryCount The maximum number of total attempts, including the initial attempt.\n * @param retryLogger The function to log retrying.\n * @param sleepMilliseconds The number of milliseconds to sleep before retrying.\n * @param updateSleepMilliseconds The function to update sleep milliseconds after each retry.\n */\nexport async function withRetry<T>(\n func: (failedCount: number) => T | Promise<T>,\n {\n beforeRetry,\n handleError,\n retryCount = 3,\n retryLogger,\n shouldRetry,\n sleepMilliseconds = 0,\n updateSleepMilliseconds,\n }: RetryOptions = {}\n): Promise<T> {\n let failedCount = 0;\n for (;;) {\n try {\n return await func(failedCount);\n } catch (error) {\n await handleError?.(error);\n failedCount++;\n if (failedCount >= retryCount) {\n throw error;\n }\n if (shouldRetry && !shouldRetry(error)) {\n throw error;\n }\n if (sleepMilliseconds > 0) {\n await sleep(sleepMilliseconds);\n }\n if (updateSleepMilliseconds) {\n sleepMilliseconds = updateSleepMilliseconds(sleepMilliseconds);\n }\n retryLogger?.(`Retry due to: ${error}\n${error instanceof Error ? '---\\n' + (error.stack ?? '') : ''}`);\n await beforeRetry?.(error);\n }\n }\n}\n"],"mappings":"mCAMA,SAAgB,EAAS,EAAqB,CAO5C,OANI,aAAe,MAAc,EACO,MAApC,OAAO,GAAQ,SAA2B,EAK7B,MAAkB,KAAK,UAAU,CAAG,CAAC,GAAK,MAAkB,OAAO,CAAG,CAAC,CALvC,CAMnD,CAEA,SAAgB,EAAe,EAA4B,CACzD,GAAI,CACF,OAAO,EAAG,CACZ,MAAQ,CAER,CACF,CAEA,SAAgB,EAAgB,EAA4B,CAC1D,GAAI,CACF,OAAO,EAAG,CACZ,OAAS,EAAO,CACd,GAAI,OAAO,GAAU,UAAY,GAAS,SAAU,GAAS,EAAM,OAAS,SAC1E,OAEF,MAAM,CACR,CACF,CAEA,eAAsB,EAAoB,EAA8C,CACtF,GAAI,CACF,OAAO,MAAM,EAAG,CAClB,MAAQ,CAER,CACF,CAEA,eAAsB,EAAqB,EAA8C,CACvF,GAAI,CACF,OAAO,MAAM,EAAG,CAClB,OAAS,EAAO,CACd,GAAI,OAAO,GAAU,UAAY,GAAS,SAAU,GAAS,EAAM,OAAS,SAC1E,OAEF,MAAM,CACR,CACF,CA0BA,eAAsB,EACpB,EACA,CACE,cACA,cACA,aAAa,EACb,cACA,cACA,oBAAoB,EACpB,2BACgB,CAAC,EACP,CACZ,IAAI,EAAc,EAClB,OACE,GAAI,CACF,OAAO,MAAM,EAAK,CAAW,CAC/B,OAAS,EAAO,CAMd,GALA,MAAM,IAAc,CAAK,EACzB,IACI,GAAe,GAGf,GAAe,CAAC,EAAY,CAAK,EACnC,MAAM,EAEJ,EAAoB,GACtB,MAAM,EAAM,CAAiB,EAE3B,IACF,EAAoB,EAAwB,CAAiB,GAE/D,IAAc,iBAAiB,EAAM;EACzC,aAAiB,MAAQ;GAAW,EAAM,OAAS,IAAM,IAAI,EACzD,MAAM,IAAc,CAAK,CAC3B,CAEJ"}
|
package/dist/githubTemplates.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
"use strict";const e=[{heading:`Why`,requirement:`the problem, with the numbers or observations behind it, and why this approach over the alternatives`},{heading:`Requirements`,requirement:"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed"},{heading:`Customer Summary`,requirement:`behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation`},{heading:`Technical Summary`,requirement:`decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven`},{heading:`Testing`,requirement:`commands run, tests added, and what was NOT exercised and why`},{heading:`Notes`,requirement:`known limitations, compatibility and migration, follow-up work; delete this section if there is none`}],t=
|
|
2
|
-
`)}function
|
|
1
|
+
"use strict";const e=[{heading:`Why`,requirement:`the problem, with the numbers or observations behind it, and why this approach over the alternatives`},{heading:`Requirements`,requirement:"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed"},{heading:`Customer Summary`,requirement:`behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation`},{heading:`Technical Summary`,requirement:`decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven`},{heading:`Testing`,requirement:`commands run, tests added, and what was NOT exercised and why`},{heading:`Notes`,requirement:`known limitations, compatibility and migration, follow-up work; delete this section if there is none`}],t="- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked `required` (asked for, or an existing contract callers depend on) or `chosen` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write `required: not recorded — ask the requester` as the only request-derived line (a `required` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its `required` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a `chosen` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a `required: not recorded` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a `required` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.",n=`- Base the PR body on \`.github/pull_request_template.md\` when creating or updating a PR, even when a skill or workflow supplies its own skeleton: keep the template's headings in order, fill each section with what its placeholder comment asks for at a length fitting the change (a sentence for a small change, numbered subsections for a large one), and delete the placeholder comments and an empty Notes section. Without a template, use no fixed headings: state the scope, the motivation, and the verification concisely.
|
|
2
|
+
- Start the body with \`Close #<n>\` only when the PR resolves an existing issue.\n${t}`,r=[{heading:`Problem`,requirement:`what happens, and what should happen instead`},{heading:`Evidence`,requirement:`reproduction steps, logs, run IDs, or links`},{heading:`Impact`,requirement:`who or what is affected, and how badly`},{heading:`Proposal`,requirement:`the fix you have in mind, and the root cause if known`}],i=[{heading:`Background and goal`,requirement:`the problem being solved, for whom, and what outcome counts as success`},{heading:`Behavior`,requirement:`every user- or caller-observable behavior, including inputs, outputs, error cases, edge cases, and interactions with existing behavior, stated precisely enough that two implementers would build the same thing`},{heading:`Acceptance criteria`,requirement:`checkable conditions (Given/When/Then or an equivalent) that decide whether the implementation is done`},{heading:`Scope and non-goals`,requirement:`what the change covers and what it deliberately leaves out, so an implementer knows where to stop`},{heading:`Design constraints`,requirement:`the data, API, schema, UI, and configuration changes, naming, and the existing code or conventions the implementation must fit — as far as the writer intends to constrain them, with everything else explicitly left to the implementer`},{heading:`Compatibility and migration`,requirement:`what existing data, users, callers, or configurations are affected and how the transition happens`},{heading:`Verification`,requirement:`how the change is tested or demonstrated, including what needs no test and why`},{heading:`Open questions`,requirement:`undecided points, each with its options; empty once the specification is implementable`}];function a(e){return e.map(e=>`- **${e.heading}**: ${e.requirement}`).join(`
|
|
3
|
+
`)}function o(e){return e.map(e=>`## ${e.heading}\n\n<!-- ${e.requirement.charAt(0).toUpperCase()}${e.requirement.slice(1)}. -->`).join(`
|
|
3
4
|
|
|
4
|
-
`)}exports.BUG_ISSUE_SECTIONS=
|
|
5
|
+
`)}exports.BUG_ISSUE_SECTIONS=r,exports.CHANGE_ISSUE_SECTIONS=i,exports.ISSUE_TEMPLATE_RULES="- Follow the closest template under `.github/ISSUE_TEMPLATE/`: `bug.md` for wrong behavior, `change.md` for anything to build or alter; a question or note fitting neither, or a repository without templates, needs no template.\n- Title: a Conventional Commits prefix for the type that fits the change (`feat:`, `fix:`, `refactor:`, `docs:`, `chore:`, ...); when it differs from the template's `title` prefix, replace the template's type label (`t: ...`) with the one matching the type.\n- The YAML front matter between the `---` lines is metadata, not body text: pass its `labels` via `--label` and submit only the content below the closing `---` as the body.",exports.PULL_REQUEST_BODY_RULES=n,exports.PULL_REQUEST_REQUIREMENTS_RULES=t,exports.PULL_REQUEST_SECTIONS=e,exports.renderSectionChecklist=a,exports.renderSectionTemplate=o;
|
|
5
6
|
//# sourceMappingURL=githubTemplates.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubTemplates.cjs","names":[],"sources":["../src/githubTemplates.ts"],"sourcesContent":["/**\n * A section of a PR or issue body: its heading and what the section must state. `requirement`\n * starts lowercase and ends without punctuation, so that it reads both as a placeholder sentence\n * (capitalized, with a period appended) and as a checklist clause after the heading.\n */\nexport interface TemplateSection {\n readonly heading: string;\n readonly requirement: string;\n}\n\n/** Sections of a pull request body, in the order they appear in the PR template. */\nexport const PULL_REQUEST_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Why',\n requirement: 'the problem, with the numbers or observations behind it, and why this approach over the alternatives',\n },\n {\n heading: 'Requirements',\n requirement:\n \"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed\",\n },\n {\n heading: 'Customer Summary',\n requirement:\n 'behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation',\n },\n {\n heading: 'Technical Summary',\n requirement:\n 'decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven',\n },\n {\n heading: 'Testing',\n requirement: 'commands run, tests added, and what was NOT exercised and why',\n },\n {\n heading: 'Notes',\n requirement: 'known limitations, compatibility and migration, follow-up work; delete this section if there is none',\n },\n];\n\n/**\n * How a tool that writes or rewrites a PR body fills the Requirements section of\n * `PULL_REQUEST_SECTIONS`, as markdown bullets for an agent's instructions. Skills that draft PR\n * bodies render this text instead of restating it, so the writers and the reviewers that read the\n * section as the boundary a fix must keep never disagree on what a line means.\n */\nexport const PULL_REQUEST_REQUIREMENTS_RULES = `- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked \\`required\\` (asked for, or an existing contract callers depend on) or \\`chosen\\` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write \\`required: not recorded — ask the requester\\` as the only request-derived line (a \\`required\\` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its \\`required\\` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a \\`chosen\\` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a \\`required: not recorded\\` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a \\`required\\` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.`;\n\n/** Sections of a bug report, in the order they appear in the issue template. */\nexport const BUG_ISSUE_SECTIONS: readonly TemplateSection[] = [\n { heading: 'Problem', requirement: 'what happens, and what should happen instead' },\n { heading: 'Evidence', requirement: 'reproduction steps, logs, run IDs, or links' },\n { heading: 'Impact', requirement: 'who or what is affected, and how badly' },\n { heading: 'Proposal', requirement: 'the fix you have in mind, and the root cause if known' },\n];\n\n/**\n * Sections a change specification must settle before a third party can implement it, defined\n * once so that the issue template and any tool that drafts or reviews specifications against\n * these sections cannot drift apart; checklist consumers render it with `renderSectionChecklist`.\n * The first three sections suffice for a small change, so they come first.\n */\nexport const CHANGE_ISSUE_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Background and goal',\n requirement: 'the problem being solved, for whom, and what outcome counts as success',\n },\n {\n heading: 'Behavior',\n requirement:\n 'every user- or caller-observable behavior, including inputs, outputs, error cases, edge cases, and interactions with existing behavior, stated precisely enough that two implementers would build the same thing',\n },\n {\n heading: 'Acceptance criteria',\n requirement:\n 'checkable conditions (Given/When/Then or an equivalent) that decide whether the implementation is done',\n },\n {\n heading: 'Scope and non-goals',\n requirement: 'what the change covers and what it deliberately leaves out, so an implementer knows where to stop',\n },\n {\n heading: 'Design constraints',\n requirement:\n 'the data, API, schema, UI, and configuration changes, naming, and the existing code or conventions the implementation must fit — as far as the writer intends to constrain them, with everything else explicitly left to the implementer',\n },\n {\n heading: 'Compatibility and migration',\n requirement: 'what existing data, users, callers, or configurations are affected and how the transition happens',\n },\n {\n heading: 'Verification',\n requirement: 'how the change is tested or demonstrated, including what needs no test and why',\n },\n {\n heading: 'Open questions',\n requirement: 'undecided points, each with its options; empty once the specification is implementable',\n },\n];\n\n/** Renders sections as markdown bullets (`- **Heading**: requirement`). */\nexport function renderSectionChecklist(sections: readonly TemplateSection[]): string {\n return sections.map((section) => `- **${section.heading}**: ${section.requirement}`).join('\\n');\n}\n\n/** Renders sections as markdown headings, each followed by its requirement as a placeholder comment. */\nexport function renderSectionTemplate(sections: readonly TemplateSection[]): string {\n return sections\n .map(\n (section) =>\n `## ${section.heading}\\n\\n<!-- ${section.requirement.charAt(0).toUpperCase()}${section.requirement.slice(1)}. -->`\n )\n .join('\\n\\n');\n}\n"],"mappings":"aAWA,MAAa,EAAoD,CAC/D,CACE,QAAS,MACT,YAAa,sGACf,EACA,CACE,QAAS,eACT,YACE,6cACJ,EACA,CACE,QAAS,mBACT,YACE,4GACJ,EACA,CACE,QAAS,oBACT,YACE,yKACJ,EACA,CACE,QAAS,UACT,YAAa,+DACf,EACA,CACE,QAAS,QACT,YAAa,sGACf,CACF,EAca,EAAiD,CAC5D,CAAE,QAAS,UAAW,YAAa,8CAA+C,EAClF,CAAE,QAAS,WAAY,YAAa,6CAA8C,EAClF,CAAE,QAAS,SAAU,YAAa,wCAAyC,EAC3E,CAAE,QAAS,WAAY,YAAa,uDAAwD,CAC9F,EAQa,EAAoD,CAC/D,CACE,QAAS,sBACT,YAAa,wEACf,EACA,CACE,QAAS,WACT,YACE,kNACJ,EACA,CACE,QAAS,sBACT,YACE,wGACJ,EACA,CACE,QAAS,sBACT,YAAa,mGACf,EACA,CACE,QAAS,qBACT,YACE,0OACJ,EACA,CACE,QAAS,8BACT,YAAa,mGACf,EACA,CACE,QAAS,eACT,YAAa,gFACf,EACA,CACE,QAAS,iBACT,YAAa,wFACf,CACF,EAGA,SAAgB,EAAuB,EAA8C,CACnF,OAAO,EAAS,IAAK,GAAY,OAAO,EAAQ,QAAQ,MAAM,EAAQ,aAAa,CAAC,CAAC,KAAK;CAAI,CAChG,CAGA,SAAgB,EAAsB,EAA8C,CAClF,OAAO,EACJ,IACE,GACC,MAAM,EAAQ,QAAQ,WAAW,EAAQ,YAAY,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAQ,YAAY,MAAM,CAAC,EAAE,MAChH,CAAC,CACA,KAAK;;CAAM,CAChB"}
|
|
1
|
+
{"version":3,"file":"githubTemplates.cjs","names":[],"sources":["../src/githubTemplates.ts"],"sourcesContent":["/**\n * A section of a PR or issue body: its heading and what the section must state. `requirement`\n * starts lowercase and ends without punctuation, so that it reads both as a placeholder sentence\n * (capitalized, with a period appended) and as a checklist clause after the heading.\n */\nexport interface TemplateSection {\n readonly heading: string;\n readonly requirement: string;\n}\n\n/** Sections of a pull request body, in the order they appear in the PR template. */\nexport const PULL_REQUEST_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Why',\n requirement: 'the problem, with the numbers or observations behind it, and why this approach over the alternatives',\n },\n {\n heading: 'Requirements',\n requirement:\n \"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed\",\n },\n {\n heading: 'Customer Summary',\n requirement:\n 'behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation',\n },\n {\n heading: 'Technical Summary',\n requirement:\n 'decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven',\n },\n {\n heading: 'Testing',\n requirement: 'commands run, tests added, and what was NOT exercised and why',\n },\n {\n heading: 'Notes',\n requirement: 'known limitations, compatibility and migration, follow-up work; delete this section if there is none',\n },\n];\n\n/**\n * How a tool that writes or rewrites a PR body derives it from the repository's PR template, as\n * markdown bullets for an agent's instructions. Stated once here and rendered by every writer (the\n * generated agent instructions, the PR-drafting skills) so the writers cannot drift apart; the\n * template-less branch lets the same text serve repositories outside the organization.\n */\nconst PULL_REQUEST_TEMPLATE_RULES = `- Base the PR body on \\`.github/pull_request_template.md\\` when creating or updating a PR, even when a skill or workflow supplies its own skeleton: keep the template's headings in order, fill each section with what its placeholder comment asks for at a length fitting the change (a sentence for a small change, numbered subsections for a large one), and delete the placeholder comments and an empty Notes section. Without a template, use no fixed headings: state the scope, the motivation, and the verification concisely.\n- Start the body with \\`Close #<n>\\` only when the PR resolves an existing issue.`;\n\n/**\n * How a tool that writes or rewrites a PR body fills the Requirements section of\n * `PULL_REQUEST_SECTIONS`, as markdown bullets for an agent's instructions. Skills that draft PR\n * bodies render this text instead of restating it, so the writers and the reviewers that read the\n * section as the boundary a fix must keep never disagree on what a line means.\n */\nexport const PULL_REQUEST_REQUIREMENTS_RULES = `- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked \\`required\\` (asked for, or an existing contract callers depend on) or \\`chosen\\` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write \\`required: not recorded — ask the requester\\` as the only request-derived line (a \\`required\\` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its \\`required\\` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a \\`chosen\\` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a \\`required: not recorded\\` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a \\`required\\` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.`;\n\n/** The complete rules for writing a PR body: the template rules followed by the Requirements rules. */\nexport const PULL_REQUEST_BODY_RULES = `${PULL_REQUEST_TEMPLATE_RULES}\\n${PULL_REQUEST_REQUIREMENTS_RULES}`;\n\n/**\n * How a tool that creates an issue derives it from the repository's issue templates, as markdown\n * bullets for an agent's instructions; shared by the same writers as `PULL_REQUEST_BODY_RULES`.\n * Guidance the templates state in their own placeholder comments (which sections to keep, deleting\n * the comments) is deliberately not repeated here, since the writer reads the template anyway.\n */\nexport const ISSUE_TEMPLATE_RULES = `- Follow the closest template under \\`.github/ISSUE_TEMPLATE/\\`: \\`bug.md\\` for wrong behavior, \\`change.md\\` for anything to build or alter; a question or note fitting neither, or a repository without templates, needs no template.\n- Title: a Conventional Commits prefix for the type that fits the change (\\`feat:\\`, \\`fix:\\`, \\`refactor:\\`, \\`docs:\\`, \\`chore:\\`, ...); when it differs from the template's \\`title\\` prefix, replace the template's type label (\\`t: ...\\`) with the one matching the type.\n- The YAML front matter between the \\`---\\` lines is metadata, not body text: pass its \\`labels\\` via \\`--label\\` and submit only the content below the closing \\`---\\` as the body.`;\n\n/** Sections of a bug report, in the order they appear in the issue template. */\nexport const BUG_ISSUE_SECTIONS: readonly TemplateSection[] = [\n { heading: 'Problem', requirement: 'what happens, and what should happen instead' },\n { heading: 'Evidence', requirement: 'reproduction steps, logs, run IDs, or links' },\n { heading: 'Impact', requirement: 'who or what is affected, and how badly' },\n { heading: 'Proposal', requirement: 'the fix you have in mind, and the root cause if known' },\n];\n\n/**\n * Sections a change specification must settle before a third party can implement it, defined\n * once so that the issue template and any tool that drafts or reviews specifications against\n * these sections cannot drift apart; checklist consumers render it with `renderSectionChecklist`.\n * The first three sections suffice for a small change, so they come first.\n */\nexport const CHANGE_ISSUE_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Background and goal',\n requirement: 'the problem being solved, for whom, and what outcome counts as success',\n },\n {\n heading: 'Behavior',\n requirement:\n 'every user- or caller-observable behavior, including inputs, outputs, error cases, edge cases, and interactions with existing behavior, stated precisely enough that two implementers would build the same thing',\n },\n {\n heading: 'Acceptance criteria',\n requirement:\n 'checkable conditions (Given/When/Then or an equivalent) that decide whether the implementation is done',\n },\n {\n heading: 'Scope and non-goals',\n requirement: 'what the change covers and what it deliberately leaves out, so an implementer knows where to stop',\n },\n {\n heading: 'Design constraints',\n requirement:\n 'the data, API, schema, UI, and configuration changes, naming, and the existing code or conventions the implementation must fit — as far as the writer intends to constrain them, with everything else explicitly left to the implementer',\n },\n {\n heading: 'Compatibility and migration',\n requirement: 'what existing data, users, callers, or configurations are affected and how the transition happens',\n },\n {\n heading: 'Verification',\n requirement: 'how the change is tested or demonstrated, including what needs no test and why',\n },\n {\n heading: 'Open questions',\n requirement: 'undecided points, each with its options; empty once the specification is implementable',\n },\n];\n\n/** Renders sections as markdown bullets (`- **Heading**: requirement`). */\nexport function renderSectionChecklist(sections: readonly TemplateSection[]): string {\n return sections.map((section) => `- **${section.heading}**: ${section.requirement}`).join('\\n');\n}\n\n/** Renders sections as markdown headings, each followed by its requirement as a placeholder comment. */\nexport function renderSectionTemplate(sections: readonly TemplateSection[]): string {\n return sections\n .map(\n (section) =>\n `## ${section.heading}\\n\\n<!-- ${section.requirement.charAt(0).toUpperCase()}${section.requirement.slice(1)}. -->`\n )\n .join('\\n\\n');\n}\n"],"mappings":"aAWA,MAAa,EAAoD,CAC/D,CACE,QAAS,MACT,YAAa,sGACf,EACA,CACE,QAAS,eACT,YACE,6cACJ,EACA,CACE,QAAS,mBACT,YACE,4GACJ,EACA,CACE,QAAS,oBACT,YACE,yKACJ,EACA,CACE,QAAS,UACT,YAAa,+DACf,EACA,CACE,QAAS,QACT,YAAa,sGACf,CACF,EAiBa,EAAkC,6/CAMlC,EAA0B;qFAAmC,IAa7D,EAAiD,CAC5D,CAAE,QAAS,UAAW,YAAa,8CAA+C,EAClF,CAAE,QAAS,WAAY,YAAa,6CAA8C,EAClF,CAAE,QAAS,SAAU,YAAa,wCAAyC,EAC3E,CAAE,QAAS,WAAY,YAAa,uDAAwD,CAC9F,EAQa,EAAoD,CAC/D,CACE,QAAS,sBACT,YAAa,wEACf,EACA,CACE,QAAS,WACT,YACE,kNACJ,EACA,CACE,QAAS,sBACT,YACE,wGACJ,EACA,CACE,QAAS,sBACT,YAAa,mGACf,EACA,CACE,QAAS,qBACT,YACE,0OACJ,EACA,CACE,QAAS,8BACT,YAAa,mGACf,EACA,CACE,QAAS,eACT,YAAa,gFACf,EACA,CACE,QAAS,iBACT,YAAa,wFACf,CACF,EAGA,SAAgB,EAAuB,EAA8C,CACnF,OAAO,EAAS,IAAK,GAAY,OAAO,EAAQ,QAAQ,MAAM,EAAQ,aAAa,CAAC,CAAC,KAAK;CAAI,CAChG,CAGA,SAAgB,EAAsB,EAA8C,CAClF,OAAO,EACJ,IACE,GACC,MAAM,EAAQ,QAAQ,WAAW,EAAQ,YAAY,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAQ,YAAY,MAAM,CAAC,EAAE,MAChH,CAAC,CACA,KAAK;;CAAM,CAChB"}
|
|
@@ -16,6 +16,15 @@ export declare const PULL_REQUEST_SECTIONS: readonly TemplateSection[];
|
|
|
16
16
|
* section as the boundary a fix must keep never disagree on what a line means.
|
|
17
17
|
*/
|
|
18
18
|
export declare const PULL_REQUEST_REQUIREMENTS_RULES = "- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked `required` (asked for, or an existing contract callers depend on) or `chosen` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write `required: not recorded \u2014 ask the requester` as the only request-derived line (a `required` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its `required` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a `chosen` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a `required: not recorded` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a `required` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.";
|
|
19
|
+
/** The complete rules for writing a PR body: the template rules followed by the Requirements rules. */
|
|
20
|
+
export declare const PULL_REQUEST_BODY_RULES = "- Base the PR body on `.github/pull_request_template.md` when creating or updating a PR, even when a skill or workflow supplies its own skeleton: keep the template's headings in order, fill each section with what its placeholder comment asks for at a length fitting the change (a sentence for a small change, numbered subsections for a large one), and delete the placeholder comments and an empty Notes section. Without a template, use no fixed headings: state the scope, the motivation, and the verification concisely.\n- Start the body with `Close #<n>` only when the PR resolves an existing issue.\n- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked `required` (asked for, or an existing contract callers depend on) or `chosen` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write `required: not recorded \u2014 ask the requester` as the only request-derived line (a `required` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its `required` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a `chosen` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a `required: not recorded` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a `required` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.";
|
|
21
|
+
/**
|
|
22
|
+
* How a tool that creates an issue derives it from the repository's issue templates, as markdown
|
|
23
|
+
* bullets for an agent's instructions; shared by the same writers as `PULL_REQUEST_BODY_RULES`.
|
|
24
|
+
* Guidance the templates state in their own placeholder comments (which sections to keep, deleting
|
|
25
|
+
* the comments) is deliberately not repeated here, since the writer reads the template anyway.
|
|
26
|
+
*/
|
|
27
|
+
export declare const ISSUE_TEMPLATE_RULES = "- Follow the closest template under `.github/ISSUE_TEMPLATE/`: `bug.md` for wrong behavior, `change.md` for anything to build or alter; a question or note fitting neither, or a repository without templates, needs no template.\n- Title: a Conventional Commits prefix for the type that fits the change (`feat:`, `fix:`, `refactor:`, `docs:`, `chore:`, ...); when it differs from the template's `title` prefix, replace the template's type label (`t: ...`) with the one matching the type.\n- The YAML front matter between the `---` lines is metadata, not body text: pass its `labels` via `--label` and submit only the content below the closing `---` as the body.";
|
|
19
28
|
/** Sections of a bug report, in the order they appear in the issue template. */
|
|
20
29
|
export declare const BUG_ISSUE_SECTIONS: readonly TemplateSection[];
|
|
21
30
|
/**
|
package/dist/githubTemplates.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
const e=[{heading:`Why`,requirement:`the problem, with the numbers or observations behind it, and why this approach over the alternatives`},{heading:`Requirements`,requirement:"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed"},{heading:`Customer Summary`,requirement:`behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation`},{heading:`Technical Summary`,requirement:`decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven`},{heading:`Testing`,requirement:`commands run, tests added, and what was NOT exercised and why`},{heading:`Notes`,requirement:`known limitations, compatibility and migration, follow-up work; delete this section if there is none`}],t="- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked `required` (asked for, or an existing contract callers depend on) or `chosen` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write `required: not recorded — ask the requester` as the only request-derived line (a `required` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its `required` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a `chosen` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a `required: not recorded` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a `required` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.",n
|
|
2
|
-
`)}
|
|
1
|
+
const e=[{heading:`Why`,requirement:`the problem, with the numbers or observations behind it, and why this approach over the alternatives`},{heading:`Requirements`,requirement:"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed"},{heading:`Customer Summary`,requirement:`behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation`},{heading:`Technical Summary`,requirement:`decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven`},{heading:`Testing`,requirement:`commands run, tests added, and what was NOT exercised and why`},{heading:`Notes`,requirement:`known limitations, compatibility and migration, follow-up work; delete this section if there is none`}],t="- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked `required` (asked for, or an existing contract callers depend on) or `chosen` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write `required: not recorded — ask the requester` as the only request-derived line (a `required` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its `required` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a `chosen` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a `required: not recorded` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a `required` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.",n=`- Base the PR body on \`.github/pull_request_template.md\` when creating or updating a PR, even when a skill or workflow supplies its own skeleton: keep the template's headings in order, fill each section with what its placeholder comment asks for at a length fitting the change (a sentence for a small change, numbered subsections for a large one), and delete the placeholder comments and an empty Notes section. Without a template, use no fixed headings: state the scope, the motivation, and the verification concisely.
|
|
2
|
+
- Start the body with \`Close #<n>\` only when the PR resolves an existing issue.\n${t}`,r="- Follow the closest template under `.github/ISSUE_TEMPLATE/`: `bug.md` for wrong behavior, `change.md` for anything to build or alter; a question or note fitting neither, or a repository without templates, needs no template.\n- Title: a Conventional Commits prefix for the type that fits the change (`feat:`, `fix:`, `refactor:`, `docs:`, `chore:`, ...); when it differs from the template's `title` prefix, replace the template's type label (`t: ...`) with the one matching the type.\n- The YAML front matter between the `---` lines is metadata, not body text: pass its `labels` via `--label` and submit only the content below the closing `---` as the body.",i=[{heading:`Problem`,requirement:`what happens, and what should happen instead`},{heading:`Evidence`,requirement:`reproduction steps, logs, run IDs, or links`},{heading:`Impact`,requirement:`who or what is affected, and how badly`},{heading:`Proposal`,requirement:`the fix you have in mind, and the root cause if known`}],a=[{heading:`Background and goal`,requirement:`the problem being solved, for whom, and what outcome counts as success`},{heading:`Behavior`,requirement:`every user- or caller-observable behavior, including inputs, outputs, error cases, edge cases, and interactions with existing behavior, stated precisely enough that two implementers would build the same thing`},{heading:`Acceptance criteria`,requirement:`checkable conditions (Given/When/Then or an equivalent) that decide whether the implementation is done`},{heading:`Scope and non-goals`,requirement:`what the change covers and what it deliberately leaves out, so an implementer knows where to stop`},{heading:`Design constraints`,requirement:`the data, API, schema, UI, and configuration changes, naming, and the existing code or conventions the implementation must fit — as far as the writer intends to constrain them, with everything else explicitly left to the implementer`},{heading:`Compatibility and migration`,requirement:`what existing data, users, callers, or configurations are affected and how the transition happens`},{heading:`Verification`,requirement:`how the change is tested or demonstrated, including what needs no test and why`},{heading:`Open questions`,requirement:`undecided points, each with its options; empty once the specification is implementable`}];function o(e){return e.map(e=>`- **${e.heading}**: ${e.requirement}`).join(`
|
|
3
|
+
`)}function s(e){return e.map(e=>`## ${e.heading}\n\n<!-- ${e.requirement.charAt(0).toUpperCase()}${e.requirement.slice(1)}. -->`).join(`
|
|
3
4
|
|
|
4
|
-
`)}export{
|
|
5
|
+
`)}export{i as BUG_ISSUE_SECTIONS,a as CHANGE_ISSUE_SECTIONS,r as ISSUE_TEMPLATE_RULES,n as PULL_REQUEST_BODY_RULES,t as PULL_REQUEST_REQUIREMENTS_RULES,e as PULL_REQUEST_SECTIONS,o as renderSectionChecklist,s as renderSectionTemplate};
|
|
5
6
|
//# sourceMappingURL=githubTemplates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubTemplates.js","names":[],"sources":["../src/githubTemplates.ts"],"sourcesContent":["/**\n * A section of a PR or issue body: its heading and what the section must state. `requirement`\n * starts lowercase and ends without punctuation, so that it reads both as a placeholder sentence\n * (capitalized, with a period appended) and as a checklist clause after the heading.\n */\nexport interface TemplateSection {\n readonly heading: string;\n readonly requirement: string;\n}\n\n/** Sections of a pull request body, in the order they appear in the PR template. */\nexport const PULL_REQUEST_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Why',\n requirement: 'the problem, with the numbers or observations behind it, and why this approach over the alternatives',\n },\n {\n heading: 'Requirements',\n requirement:\n \"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed\",\n },\n {\n heading: 'Customer Summary',\n requirement:\n 'behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation',\n },\n {\n heading: 'Technical Summary',\n requirement:\n 'decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven',\n },\n {\n heading: 'Testing',\n requirement: 'commands run, tests added, and what was NOT exercised and why',\n },\n {\n heading: 'Notes',\n requirement: 'known limitations, compatibility and migration, follow-up work; delete this section if there is none',\n },\n];\n\n/**\n * How a tool that writes or rewrites a PR body fills the Requirements section of\n * `PULL_REQUEST_SECTIONS`, as markdown bullets for an agent's instructions. Skills that draft PR\n * bodies render this text instead of restating it, so the writers and the reviewers that read the\n * section as the boundary a fix must keep never disagree on what a line means.\n */\nexport const PULL_REQUEST_REQUIREMENTS_RULES = `- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked \\`required\\` (asked for, or an existing contract callers depend on) or \\`chosen\\` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write \\`required: not recorded — ask the requester\\` as the only request-derived line (a \\`required\\` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its \\`required\\` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a \\`chosen\\` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a \\`required: not recorded\\` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a \\`required\\` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.`;\n\n/** Sections of a bug report, in the order they appear in the issue template. */\nexport const BUG_ISSUE_SECTIONS: readonly TemplateSection[] = [\n { heading: 'Problem', requirement: 'what happens, and what should happen instead' },\n { heading: 'Evidence', requirement: 'reproduction steps, logs, run IDs, or links' },\n { heading: 'Impact', requirement: 'who or what is affected, and how badly' },\n { heading: 'Proposal', requirement: 'the fix you have in mind, and the root cause if known' },\n];\n\n/**\n * Sections a change specification must settle before a third party can implement it, defined\n * once so that the issue template and any tool that drafts or reviews specifications against\n * these sections cannot drift apart; checklist consumers render it with `renderSectionChecklist`.\n * The first three sections suffice for a small change, so they come first.\n */\nexport const CHANGE_ISSUE_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Background and goal',\n requirement: 'the problem being solved, for whom, and what outcome counts as success',\n },\n {\n heading: 'Behavior',\n requirement:\n 'every user- or caller-observable behavior, including inputs, outputs, error cases, edge cases, and interactions with existing behavior, stated precisely enough that two implementers would build the same thing',\n },\n {\n heading: 'Acceptance criteria',\n requirement:\n 'checkable conditions (Given/When/Then or an equivalent) that decide whether the implementation is done',\n },\n {\n heading: 'Scope and non-goals',\n requirement: 'what the change covers and what it deliberately leaves out, so an implementer knows where to stop',\n },\n {\n heading: 'Design constraints',\n requirement:\n 'the data, API, schema, UI, and configuration changes, naming, and the existing code or conventions the implementation must fit — as far as the writer intends to constrain them, with everything else explicitly left to the implementer',\n },\n {\n heading: 'Compatibility and migration',\n requirement: 'what existing data, users, callers, or configurations are affected and how the transition happens',\n },\n {\n heading: 'Verification',\n requirement: 'how the change is tested or demonstrated, including what needs no test and why',\n },\n {\n heading: 'Open questions',\n requirement: 'undecided points, each with its options; empty once the specification is implementable',\n },\n];\n\n/** Renders sections as markdown bullets (`- **Heading**: requirement`). */\nexport function renderSectionChecklist(sections: readonly TemplateSection[]): string {\n return sections.map((section) => `- **${section.heading}**: ${section.requirement}`).join('\\n');\n}\n\n/** Renders sections as markdown headings, each followed by its requirement as a placeholder comment. */\nexport function renderSectionTemplate(sections: readonly TemplateSection[]): string {\n return sections\n .map(\n (section) =>\n `## ${section.heading}\\n\\n<!-- ${section.requirement.charAt(0).toUpperCase()}${section.requirement.slice(1)}. -->`\n )\n .join('\\n\\n');\n}\n"],"mappings":"AAWA,MAAa,EAAoD,CAC/D,CACE,QAAS,MACT,YAAa,sGACf,EACA,CACE,QAAS,eACT,YACE,6cACJ,EACA,CACE,QAAS,mBACT,YACE,4GACJ,EACA,CACE,QAAS,oBACT,YACE,yKACJ,EACA,CACE,QAAS,UACT,YAAa,+DACf,EACA,CACE,QAAS,QACT,YAAa,sGACf,CACF,EAQa,EAAkC,6/CAMlC,EAAiD,CAC5D,CAAE,QAAS,UAAW,YAAa,8CAA+C,EAClF,CAAE,QAAS,WAAY,YAAa,6CAA8C,EAClF,CAAE,QAAS,SAAU,YAAa,wCAAyC,EAC3E,CAAE,QAAS,WAAY,YAAa,uDAAwD,CAC9F,EAQa,EAAoD,CAC/D,CACE,QAAS,sBACT,YAAa,wEACf,EACA,CACE,QAAS,WACT,YACE,kNACJ,EACA,CACE,QAAS,sBACT,YACE,wGACJ,EACA,CACE,QAAS,sBACT,YAAa,mGACf,EACA,CACE,QAAS,qBACT,YACE,0OACJ,EACA,CACE,QAAS,8BACT,YAAa,mGACf,EACA,CACE,QAAS,eACT,YAAa,gFACf,EACA,CACE,QAAS,iBACT,YAAa,wFACf,CACF,EAGA,SAAgB,EAAuB,EAA8C,CACnF,OAAO,EAAS,IAAK,GAAY,OAAO,EAAQ,QAAQ,MAAM,EAAQ,aAAa,CAAC,CAAC,KAAK;CAAI,CAChG,CAGA,SAAgB,EAAsB,EAA8C,CAClF,OAAO,EACJ,IACE,GACC,MAAM,EAAQ,QAAQ,WAAW,EAAQ,YAAY,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAQ,YAAY,MAAM,CAAC,EAAE,MAChH,CAAC,CACA,KAAK;;CAAM,CAChB"}
|
|
1
|
+
{"version":3,"file":"githubTemplates.js","names":[],"sources":["../src/githubTemplates.ts"],"sourcesContent":["/**\n * A section of a PR or issue body: its heading and what the section must state. `requirement`\n * starts lowercase and ends without punctuation, so that it reads both as a placeholder sentence\n * (capitalized, with a period appended) and as a checklist clause after the heading.\n */\nexport interface TemplateSection {\n readonly heading: string;\n readonly requirement: string;\n}\n\n/** Sections of a pull request body, in the order they appear in the PR template. */\nexport const PULL_REQUEST_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Why',\n requirement: 'the problem, with the numbers or observations behind it, and why this approach over the alternatives',\n },\n {\n heading: 'Requirements',\n requirement:\n \"the requirements the change must satisfy and the guarantees it must keep, one per line, each marked `required` (asked for by the requester, or an existing contract callers depend on) or `chosen` (the implementer's own decision, which a simpler design may replace); copy the requester's instructions here as given, whether they came from an issue or a conversation, and keep the list when the body is later rewritten unless the requester's instructions changed\",\n },\n {\n heading: 'Customer Summary',\n requirement:\n 'behavior, workflow, or user-visible changes, written for readers who know nothing about the implementation',\n },\n {\n heading: 'Technical Summary',\n requirement:\n 'decisions and their reasons, data flow, where to look (the files that matter most), and what to check hardest: the parts whose correctness is argued rather than proven',\n },\n {\n heading: 'Testing',\n requirement: 'commands run, tests added, and what was NOT exercised and why',\n },\n {\n heading: 'Notes',\n requirement: 'known limitations, compatibility and migration, follow-up work; delete this section if there is none',\n },\n];\n\n/**\n * How a tool that writes or rewrites a PR body derives it from the repository's PR template, as\n * markdown bullets for an agent's instructions. Stated once here and rendered by every writer (the\n * generated agent instructions, the PR-drafting skills) so the writers cannot drift apart; the\n * template-less branch lets the same text serve repositories outside the organization.\n */\nconst PULL_REQUEST_TEMPLATE_RULES = `- Base the PR body on \\`.github/pull_request_template.md\\` when creating or updating a PR, even when a skill or workflow supplies its own skeleton: keep the template's headings in order, fill each section with what its placeholder comment asks for at a length fitting the change (a sentence for a small change, numbered subsections for a large one), and delete the placeholder comments and an empty Notes section. Without a template, use no fixed headings: state the scope, the motivation, and the verification concisely.\n- Start the body with \\`Close #<n>\\` only when the PR resolves an existing issue.`;\n\n/**\n * How a tool that writes or rewrites a PR body fills the Requirements section of\n * `PULL_REQUEST_SECTIONS`, as markdown bullets for an agent's instructions. Skills that draft PR\n * bodies render this text instead of restating it, so the writers and the reviewers that read the\n * section as the boundary a fix must keep never disagree on what a line means.\n */\nexport const PULL_REQUEST_REQUIREMENTS_RULES = `- Requirements section: one line per requirement, taken from the requester's instructions as they were given (the issue, the conversation that asked for the change), each marked \\`required\\` (asked for, or an existing contract callers depend on) or \\`chosen\\` (your own decision, which a simpler design may replace). Never infer a requirement from the diff: when no issue, PR message, or conversation states the request, write \\`required: not recorded — ask the requester\\` as the only request-derived line (a \\`required\\` line for an existing contract callers depend on may still be listed) and say so in Notes.\n- Record rule: an existing Requirements section is a record, not a description of the diff. Keep its \\`required\\` lines as they are, rewriting them only when the requester's instructions changed (then from the updated instructions, dropping a line only when the requester removed it; with no instructions available, keep them unchanged); add a \\`chosen\\` line for a new decision, and replace or remove one when the decision it records changed. A section that merely describes the implementation, or holds only the template's placeholder or a \\`required: not recorded\\` line, is not a record: write it afresh by the rule above.\n- Place the section where the template puts it; when the template has no such heading, right after the issue-closing line, or at the top of the body when there is none.\n- Never drop or weaken a \\`required\\` line to fit what was implemented: when one cannot hold in the diff, keep it and say so in Notes.`;\n\n/** The complete rules for writing a PR body: the template rules followed by the Requirements rules. */\nexport const PULL_REQUEST_BODY_RULES = `${PULL_REQUEST_TEMPLATE_RULES}\\n${PULL_REQUEST_REQUIREMENTS_RULES}`;\n\n/**\n * How a tool that creates an issue derives it from the repository's issue templates, as markdown\n * bullets for an agent's instructions; shared by the same writers as `PULL_REQUEST_BODY_RULES`.\n * Guidance the templates state in their own placeholder comments (which sections to keep, deleting\n * the comments) is deliberately not repeated here, since the writer reads the template anyway.\n */\nexport const ISSUE_TEMPLATE_RULES = `- Follow the closest template under \\`.github/ISSUE_TEMPLATE/\\`: \\`bug.md\\` for wrong behavior, \\`change.md\\` for anything to build or alter; a question or note fitting neither, or a repository without templates, needs no template.\n- Title: a Conventional Commits prefix for the type that fits the change (\\`feat:\\`, \\`fix:\\`, \\`refactor:\\`, \\`docs:\\`, \\`chore:\\`, ...); when it differs from the template's \\`title\\` prefix, replace the template's type label (\\`t: ...\\`) with the one matching the type.\n- The YAML front matter between the \\`---\\` lines is metadata, not body text: pass its \\`labels\\` via \\`--label\\` and submit only the content below the closing \\`---\\` as the body.`;\n\n/** Sections of a bug report, in the order they appear in the issue template. */\nexport const BUG_ISSUE_SECTIONS: readonly TemplateSection[] = [\n { heading: 'Problem', requirement: 'what happens, and what should happen instead' },\n { heading: 'Evidence', requirement: 'reproduction steps, logs, run IDs, or links' },\n { heading: 'Impact', requirement: 'who or what is affected, and how badly' },\n { heading: 'Proposal', requirement: 'the fix you have in mind, and the root cause if known' },\n];\n\n/**\n * Sections a change specification must settle before a third party can implement it, defined\n * once so that the issue template and any tool that drafts or reviews specifications against\n * these sections cannot drift apart; checklist consumers render it with `renderSectionChecklist`.\n * The first three sections suffice for a small change, so they come first.\n */\nexport const CHANGE_ISSUE_SECTIONS: readonly TemplateSection[] = [\n {\n heading: 'Background and goal',\n requirement: 'the problem being solved, for whom, and what outcome counts as success',\n },\n {\n heading: 'Behavior',\n requirement:\n 'every user- or caller-observable behavior, including inputs, outputs, error cases, edge cases, and interactions with existing behavior, stated precisely enough that two implementers would build the same thing',\n },\n {\n heading: 'Acceptance criteria',\n requirement:\n 'checkable conditions (Given/When/Then or an equivalent) that decide whether the implementation is done',\n },\n {\n heading: 'Scope and non-goals',\n requirement: 'what the change covers and what it deliberately leaves out, so an implementer knows where to stop',\n },\n {\n heading: 'Design constraints',\n requirement:\n 'the data, API, schema, UI, and configuration changes, naming, and the existing code or conventions the implementation must fit — as far as the writer intends to constrain them, with everything else explicitly left to the implementer',\n },\n {\n heading: 'Compatibility and migration',\n requirement: 'what existing data, users, callers, or configurations are affected and how the transition happens',\n },\n {\n heading: 'Verification',\n requirement: 'how the change is tested or demonstrated, including what needs no test and why',\n },\n {\n heading: 'Open questions',\n requirement: 'undecided points, each with its options; empty once the specification is implementable',\n },\n];\n\n/** Renders sections as markdown bullets (`- **Heading**: requirement`). */\nexport function renderSectionChecklist(sections: readonly TemplateSection[]): string {\n return sections.map((section) => `- **${section.heading}**: ${section.requirement}`).join('\\n');\n}\n\n/** Renders sections as markdown headings, each followed by its requirement as a placeholder comment. */\nexport function renderSectionTemplate(sections: readonly TemplateSection[]): string {\n return sections\n .map(\n (section) =>\n `## ${section.heading}\\n\\n<!-- ${section.requirement.charAt(0).toUpperCase()}${section.requirement.slice(1)}. -->`\n )\n .join('\\n\\n');\n}\n"],"mappings":"AAWA,MAAa,EAAoD,CAC/D,CACE,QAAS,MACT,YAAa,sGACf,EACA,CACE,QAAS,eACT,YACE,6cACJ,EACA,CACE,QAAS,mBACT,YACE,4GACJ,EACA,CACE,QAAS,oBACT,YACE,yKACJ,EACA,CACE,QAAS,UACT,YAAa,+DACf,EACA,CACE,QAAS,QACT,YAAa,sGACf,CACF,EAiBa,EAAkC,6/CAMlC,EAA0B;qFAAmC,IAQ7D,EAAuB,qpBAKvB,EAAiD,CAC5D,CAAE,QAAS,UAAW,YAAa,8CAA+C,EAClF,CAAE,QAAS,WAAY,YAAa,6CAA8C,EAClF,CAAE,QAAS,SAAU,YAAa,wCAAyC,EAC3E,CAAE,QAAS,WAAY,YAAa,uDAAwD,CAC9F,EAQa,EAAoD,CAC/D,CACE,QAAS,sBACT,YAAa,wEACf,EACA,CACE,QAAS,WACT,YACE,kNACJ,EACA,CACE,QAAS,sBACT,YACE,wGACJ,EACA,CACE,QAAS,sBACT,YAAa,mGACf,EACA,CACE,QAAS,qBACT,YACE,0OACJ,EACA,CACE,QAAS,8BACT,YAAa,mGACf,EACA,CACE,QAAS,eACT,YAAa,gFACf,EACA,CACE,QAAS,iBACT,YAAa,wFACf,CACF,EAGA,SAAgB,EAAuB,EAA8C,CACnF,OAAO,EAAS,IAAK,GAAY,OAAO,EAAQ,QAAQ,MAAM,EAAQ,aAAa,CAAC,CAAC,KAAK;CAAI,CAChG,CAGA,SAAgB,EAAsB,EAA8C,CAClF,OAAO,EACJ,IACE,GACC,MAAM,EAAQ,QAAQ,WAAW,EAAQ,YAAY,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAQ,YAAY,MAAM,CAAC,EAAE,MAChH,CAAC,CACA,KAAK;;CAAM,CAChB"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./appEnv.cjs"),t=require("./assert.cjs"),n=require("./githubTemplates.cjs"),r=require("./sleep.cjs"),i=require("./error.cjs"),a=require("./humanize.cjs"),o=require("./mail.cjs"),s=require("./parseCommandLineArgs.cjs"),c=require("./shuffle.cjs"),l=require("./sqlite.cjs"),u=require("./zenkaku.cjs");exports.BUG_ISSUE_SECTIONS=n.BUG_ISSUE_SECTIONS,exports.CHANGE_ISSUE_SECTIONS=n.CHANGE_ISSUE_SECTIONS,exports.PULL_REQUEST_REQUIREMENTS_RULES=n.PULL_REQUEST_REQUIREMENTS_RULES,exports.PULL_REQUEST_SECTIONS=n.PULL_REQUEST_SECTIONS,exports.ensureTruthy=t.ensureTruthy,exports.errorify=i.errorify,exports.getAppEnv=e.getAppEnv,exports.getConnectionLevelSqlitePragmas=l.getConnectionLevelSqlitePragmas,exports.getPersistentSqlitePragmas=l.getPersistentSqlitePragmas,exports.humanizeNumber=a.humanizeNumber,exports.ignoreEnoent=i.ignoreEnoent,exports.ignoreEnoentAsync=i.ignoreEnoentAsync,exports.ignoreError=i.ignoreError,exports.ignoreErrorAsync=i.ignoreErrorAsync,exports.mailTemplates=o.mailTemplates,exports.parseCommandLineArgs=s.parseCommandLineArgs,exports.renderSectionChecklist=n.renderSectionChecklist,exports.renderSectionTemplate=n.renderSectionTemplate,exports.shuffle=c.shuffle,exports.sleep=r.sleep,exports.withRetry=i.withRetry,exports.zenkakuAlphanumericalsToHankaku=
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./appEnv.cjs"),t=require("./assert.cjs"),n=require("./githubTemplates.cjs"),r=require("./sleep.cjs"),i=require("./error.cjs"),a=require("./humanize.cjs"),o=require("./mail.cjs"),s=require("./parseCommandLineArgs.cjs"),c=require("./shuffle.cjs"),l=require("./sqlite.cjs"),u=require("./text.cjs"),d=require("./testingRules.cjs"),f=require("./zenkaku.cjs");exports.BUG_ISSUE_SECTIONS=n.BUG_ISSUE_SECTIONS,exports.CHANGE_ISSUE_SECTIONS=n.CHANGE_ISSUE_SECTIONS,exports.ISSUE_TEMPLATE_RULES=n.ISSUE_TEMPLATE_RULES,exports.PULL_REQUEST_BODY_RULES=n.PULL_REQUEST_BODY_RULES,exports.PULL_REQUEST_REQUIREMENTS_RULES=n.PULL_REQUEST_REQUIREMENTS_RULES,exports.PULL_REQUEST_SECTIONS=n.PULL_REQUEST_SECTIONS,exports.TEST_WRITING_RULES=d.TEST_WRITING_RULES,exports.ensureTruthy=t.ensureTruthy,exports.errorify=i.errorify,exports.escapeRegExp=u.escapeRegExp,exports.getAppEnv=e.getAppEnv,exports.getConnectionLevelSqlitePragmas=l.getConnectionLevelSqlitePragmas,exports.getPersistentSqlitePragmas=l.getPersistentSqlitePragmas,exports.humanizeNumber=a.humanizeNumber,exports.ignoreEnoent=i.ignoreEnoent,exports.ignoreEnoentAsync=i.ignoreEnoentAsync,exports.ignoreError=i.ignoreError,exports.ignoreErrorAsync=i.ignoreErrorAsync,exports.mailTemplates=o.mailTemplates,exports.parseCommandLineArgs=s.parseCommandLineArgs,exports.quoteForShell=u.quoteForShell,exports.renderSectionChecklist=n.renderSectionChecklist,exports.renderSectionTemplate=n.renderSectionTemplate,exports.shuffle=c.shuffle,exports.sleep=r.sleep,exports.withRetry=i.withRetry,exports.zenkakuAlphanumericalsToHankaku=f.zenkakuAlphanumericalsToHankaku;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { getAppEnv } from './appEnv.js';
|
|
2
2
|
export { ensureTruthy } from './assert.js';
|
|
3
|
-
export { BUG_ISSUE_SECTIONS, CHANGE_ISSUE_SECTIONS, PULL_REQUEST_REQUIREMENTS_RULES, PULL_REQUEST_SECTIONS, renderSectionChecklist, renderSectionTemplate, } from './githubTemplates.js';
|
|
3
|
+
export { BUG_ISSUE_SECTIONS, CHANGE_ISSUE_SECTIONS, ISSUE_TEMPLATE_RULES, PULL_REQUEST_BODY_RULES, PULL_REQUEST_REQUIREMENTS_RULES, PULL_REQUEST_SECTIONS, renderSectionChecklist, renderSectionTemplate, } from './githubTemplates.js';
|
|
4
4
|
export { errorify, ignoreError, ignoreEnoent, ignoreErrorAsync, ignoreEnoentAsync, withRetry } from './error.js';
|
|
5
5
|
export { humanizeNumber } from './humanize.js';
|
|
6
6
|
export { mailTemplates } from './mail.js';
|
|
@@ -8,6 +8,8 @@ export { parseCommandLineArgs } from './parseCommandLineArgs.js';
|
|
|
8
8
|
export { shuffle } from './shuffle.js';
|
|
9
9
|
export { sleep } from './sleep.js';
|
|
10
10
|
export { getConnectionLevelSqlitePragmas, getPersistentSqlitePragmas } from './sqlite.js';
|
|
11
|
+
export { escapeRegExp, quoteForShell } from './text.js';
|
|
12
|
+
export { TEST_WRITING_RULES } from './testingRules.js';
|
|
11
13
|
export { zenkakuAlphanumericalsToHankaku } from './zenkaku.js';
|
|
12
14
|
export type { AppEnv } from './appEnv.js';
|
|
13
15
|
export type { RetryOptions } from './error.js';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getAppEnv as e}from"./appEnv.js";import{ensureTruthy as t}from"./assert.js";import{BUG_ISSUE_SECTIONS as n,CHANGE_ISSUE_SECTIONS as r,
|
|
1
|
+
import{getAppEnv as e}from"./appEnv.js";import{ensureTruthy as t}from"./assert.js";import{BUG_ISSUE_SECTIONS as n,CHANGE_ISSUE_SECTIONS as r,ISSUE_TEMPLATE_RULES as i,PULL_REQUEST_BODY_RULES as a,PULL_REQUEST_REQUIREMENTS_RULES as o,PULL_REQUEST_SECTIONS as s,renderSectionChecklist as c,renderSectionTemplate as l}from"./githubTemplates.js";import{sleep as u}from"./sleep.js";import{errorify as d,ignoreEnoent as f,ignoreEnoentAsync as p,ignoreError as m,ignoreErrorAsync as h,withRetry as g}from"./error.js";import{humanizeNumber as _}from"./humanize.js";import{mailTemplates as v}from"./mail.js";import{parseCommandLineArgs as y}from"./parseCommandLineArgs.js";import{shuffle as b}from"./shuffle.js";import{getConnectionLevelSqlitePragmas as x,getPersistentSqlitePragmas as S}from"./sqlite.js";import{escapeRegExp as C,quoteForShell as w}from"./text.js";import{TEST_WRITING_RULES as T}from"./testingRules.js";import{zenkakuAlphanumericalsToHankaku as E}from"./zenkaku.js";export{n as BUG_ISSUE_SECTIONS,r as CHANGE_ISSUE_SECTIONS,i as ISSUE_TEMPLATE_RULES,a as PULL_REQUEST_BODY_RULES,o as PULL_REQUEST_REQUIREMENTS_RULES,s as PULL_REQUEST_SECTIONS,T as TEST_WRITING_RULES,t as ensureTruthy,d as errorify,C as escapeRegExp,e as getAppEnv,x as getConnectionLevelSqlitePragmas,S as getPersistentSqlitePragmas,_ as humanizeNumber,f as ignoreEnoent,p as ignoreEnoentAsync,m as ignoreError,h as ignoreErrorAsync,v as mailTemplates,y as parseCommandLineArgs,w as quoteForShell,c as renderSectionChecklist,l as renderSectionTemplate,b as shuffle,u as sleep,g as withRetry,E as zenkakuAlphanumericalsToHankaku};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";exports.TEST_WRITING_RULES=`- Write a test only when explicitly requested, or when a behavior is likely to regress and no existing automatic check (type checking, linting, an existing test or CI check) would catch the breakage. Never add a test that merely restates a mapping from conditions to constant outputs (it fails only on intentional edits) or that only confirms an external fact (a library's behavior, whether a version fixes an issue); verify those once manually.
|
|
2
|
+
- Test externally observable behavior (e.g., emitted files, CLI output, rendered results) at the system boundary, not implementation details: do not mirror production logic, assert that a branch is taken, or feed hand-assembled internal objects to internal functions.
|
|
3
|
+
- Prefer actual API calls over mocks, unless actual calls are impractical, have unintended side effects, or mocks are explicitly requested.
|
|
4
|
+
- Ensure tests are idempotent and independent (e.g., reset persistent data) so they can run repeatedly or in parallel.
|
|
5
|
+
- Avoid fixed waits in E2E tests; wait for conditions instead.`;
|
|
6
|
+
//# sourceMappingURL=testingRules.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testingRules.cjs","names":[],"sources":["../src/testingRules.ts"],"sourcesContent":["/**\n * When to write a test and what a test may assert, as markdown bullets for an agent's instructions.\n * Stated once here and rendered by the generated agent instructions and the testing skill so the\n * two cannot drift apart.\n */\nexport const TEST_WRITING_RULES = `- Write a test only when explicitly requested, or when a behavior is likely to regress and no existing automatic check (type checking, linting, an existing test or CI check) would catch the breakage. Never add a test that merely restates a mapping from conditions to constant outputs (it fails only on intentional edits) or that only confirms an external fact (a library's behavior, whether a version fixes an issue); verify those once manually.\n- Test externally observable behavior (e.g., emitted files, CLI output, rendered results) at the system boundary, not implementation details: do not mirror production logic, assert that a branch is taken, or feed hand-assembled internal objects to internal functions.\n- Prefer actual API calls over mocks, unless actual calls are impractical, have unintended side effects, or mocks are explicitly requested.\n- Ensure tests are idempotent and independent (e.g., reset persistent data) so they can run repeatedly or in parallel.\n- Avoid fixed waits in E2E tests; wait for conditions instead.`;\n"],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When to write a test and what a test may assert, as markdown bullets for an agent's instructions.
|
|
3
|
+
* Stated once here and rendered by the generated agent instructions and the testing skill so the
|
|
4
|
+
* two cannot drift apart.
|
|
5
|
+
*/
|
|
6
|
+
export declare const TEST_WRITING_RULES = "- Write a test only when explicitly requested, or when a behavior is likely to regress and no existing automatic check (type checking, linting, an existing test or CI check) would catch the breakage. Never add a test that merely restates a mapping from conditions to constant outputs (it fails only on intentional edits) or that only confirms an external fact (a library's behavior, whether a version fixes an issue); verify those once manually.\n- Test externally observable behavior (e.g., emitted files, CLI output, rendered results) at the system boundary, not implementation details: do not mirror production logic, assert that a branch is taken, or feed hand-assembled internal objects to internal functions.\n- Prefer actual API calls over mocks, unless actual calls are impractical, have unintended side effects, or mocks are explicitly requested.\n- Ensure tests are idempotent and independent (e.g., reset persistent data) so they can run repeatedly or in parallel.\n- Avoid fixed waits in E2E tests; wait for conditions instead.";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const e=`- Write a test only when explicitly requested, or when a behavior is likely to regress and no existing automatic check (type checking, linting, an existing test or CI check) would catch the breakage. Never add a test that merely restates a mapping from conditions to constant outputs (it fails only on intentional edits) or that only confirms an external fact (a library's behavior, whether a version fixes an issue); verify those once manually.
|
|
2
|
+
- Test externally observable behavior (e.g., emitted files, CLI output, rendered results) at the system boundary, not implementation details: do not mirror production logic, assert that a branch is taken, or feed hand-assembled internal objects to internal functions.
|
|
3
|
+
- Prefer actual API calls over mocks, unless actual calls are impractical, have unintended side effects, or mocks are explicitly requested.
|
|
4
|
+
- Ensure tests are idempotent and independent (e.g., reset persistent data) so they can run repeatedly or in parallel.
|
|
5
|
+
- Avoid fixed waits in E2E tests; wait for conditions instead.`;export{e as TEST_WRITING_RULES};
|
|
6
|
+
//# sourceMappingURL=testingRules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testingRules.js","names":[],"sources":["../src/testingRules.ts"],"sourcesContent":["/**\n * When to write a test and what a test may assert, as markdown bullets for an agent's instructions.\n * Stated once here and rendered by the generated agent instructions and the testing skill so the\n * two cannot drift apart.\n */\nexport const TEST_WRITING_RULES = `- Write a test only when explicitly requested, or when a behavior is likely to regress and no existing automatic check (type checking, linting, an existing test or CI check) would catch the breakage. Never add a test that merely restates a mapping from conditions to constant outputs (it fails only on intentional edits) or that only confirms an external fact (a library's behavior, whether a version fixes an issue); verify those once manually.\n- Test externally observable behavior (e.g., emitted files, CLI output, rendered results) at the system boundary, not implementation details: do not mirror production logic, assert that a branch is taken, or feed hand-assembled internal objects to internal functions.\n- Prefer actual API calls over mocks, unless actual calls are impractical, have unintended side effects, or mocks are explicitly requested.\n- Ensure tests are idempotent and independent (e.g., reset persistent data) so they can run repeatedly or in parallel.\n- Avoid fixed waits in E2E tests; wait for conditions instead.`;\n"],"mappings":"AAKA,MAAa,EAAqB"}
|
package/dist/text.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.cjs","names":[],"sources":["../src/text.ts"],"sourcesContent":["/** Escapes every RegExp metacharacter so the text matches itself literally. */\nexport function escapeRegExp(text: string): string {\n return text.replaceAll(/[$()*+.?[\\\\\\]^{|}]/gu, String.raw`\\$&`);\n}\n\n/** A POSIX shell word: safe characters pass through, anything else is single-quoted. */\nexport function quoteForShell(value: string): string {\n return /^[\\w./-]+$/u.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`;\n}\n"],"mappings":"aACA,SAAgB,EAAa,EAAsB,CACjD,OAAO,EAAK,WAAW,uBAAwB,OAAO,GAAG,KAAK,CAChE,CAGA,SAAgB,EAAc,EAAuB,CACnD,MAAO,cAAc,KAAK,CAAK,EAAI,EAAQ,IAAI,EAAM,WAAW,IAAK,OAAO,GAAG,MAAM,EAAE,EACzF"}
|
package/dist/text.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Escapes every RegExp metacharacter so the text matches itself literally. */
|
|
2
|
+
export declare function escapeRegExp(text: string): string;
|
|
3
|
+
/** A POSIX shell word: safe characters pass through, anything else is single-quoted. */
|
|
4
|
+
export declare function quoteForShell(value: string): string;
|
package/dist/text.js
ADDED
package/dist/text.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../src/text.ts"],"sourcesContent":["/** Escapes every RegExp metacharacter so the text matches itself literally. */\nexport function escapeRegExp(text: string): string {\n return text.replaceAll(/[$()*+.?[\\\\\\]^{|}]/gu, String.raw`\\$&`);\n}\n\n/** A POSIX shell word: safe characters pass through, anything else is single-quoted. */\nexport function quoteForShell(value: string): string {\n return /^[\\w./-]+$/u.test(value) ? value : `'${value.replaceAll(\"'\", String.raw`'\\''`)}'`;\n}\n"],"mappings":"AACA,SAAgB,EAAa,EAAsB,CACjD,OAAO,EAAK,WAAW,uBAAwB,OAAO,GAAG,KAAK,CAChE,CAGA,SAAgB,EAAc,EAAuB,CACnD,MAAO,cAAc,KAAK,CAAK,EAAI,EAAQ,IAAI,EAAM,WAAW,IAAK,OAAO,GAAG,MAAM,EAAE,EACzF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@willbooster/shared-lib",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.6.0",
|
|
4
4
|
"description": "Shared library for WillBooster projects",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -45,18 +45,18 @@
|
|
|
45
45
|
"@tsconfig/bun": "1.0.11",
|
|
46
46
|
"@tsconfig/node-lts": "24.0.1",
|
|
47
47
|
"@tsconfig/node-ts": "23.6.4",
|
|
48
|
-
"@types/bun": "1.4.
|
|
49
|
-
"@types/node": "26.4.
|
|
48
|
+
"@types/bun": "1.4.1",
|
|
49
|
+
"@types/node": "26.4.1",
|
|
50
50
|
"@willbooster/oxfmt-config": "1.2.2",
|
|
51
51
|
"@willbooster/oxlint-config": "1.4.8",
|
|
52
|
-
"@willbooster/wb": "22.
|
|
53
|
-
"build-ts": "21.0.
|
|
54
|
-
"oxfmt": "0.
|
|
55
|
-
"oxlint": "1.
|
|
52
|
+
"@willbooster/wb": "22.4.0",
|
|
53
|
+
"build-ts": "21.0.14",
|
|
54
|
+
"oxfmt": "0.66.0",
|
|
55
|
+
"oxlint": "1.81.0",
|
|
56
56
|
"oxlint-tsgolint": "7.0.2001",
|
|
57
57
|
"sort-package-json": "4.0.0",
|
|
58
58
|
"typescript": "7.0.2",
|
|
59
|
-
"vitest": "
|
|
59
|
+
"vitest": "5.0.0"
|
|
60
60
|
},
|
|
61
61
|
"publishConfig": {
|
|
62
62
|
"access": "public",
|