issue-flow 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/{analyze-VSWAEVN3.js → analyze-UZYJAWAP.js} +6 -6
  2. package/dist/{chunk-66ZGYXTH.js → chunk-2LNQL4XH.js} +7 -7
  3. package/dist/{chunk-X7XBF5TS.js → chunk-2Z7OEZZT.js} +6 -6
  4. package/dist/{chunk-VNKSMWDN.js → chunk-652DJBCN.js} +3 -3
  5. package/dist/{chunk-DP43WJY4.js → chunk-67ZO5ROQ.js} +5 -5
  6. package/dist/{chunk-TLSIK656.js → chunk-EWA3OGCM.js} +6 -6
  7. package/dist/{chunk-M72ZEPWD.js → chunk-EZMOEBLU.js} +2 -2
  8. package/dist/{chunk-JGKPSWOA.js → chunk-MXTGCD5C.js} +2 -2
  9. package/dist/{chunk-DTNM3LTO.js → chunk-PPLIXZI5.js} +2 -2
  10. package/dist/{chunk-KXAG24DD.js → chunk-S67Q4I2O.js} +3 -3
  11. package/dist/{chunk-TJMZWRS6.js → chunk-SP7DD4ID.js} +7 -7
  12. package/dist/{chunk-WHEU55ZP.js → chunk-UH4KAJBJ.js} +7 -7
  13. package/dist/{chunk-NB6WKTBL.js → chunk-UUY4PCWW.js} +2 -2
  14. package/dist/{chunk-57MH6RYJ.js → chunk-V5OHFSW4.js} +229 -181
  15. package/dist/chunk-V5OHFSW4.js.map +1 -0
  16. package/dist/{chunk-M37YZYDO.js → chunk-VOKNTBOO.js} +3 -3
  17. package/dist/{chunk-MTJQOOMG.js → chunk-VYFKOUUR.js} +119 -4
  18. package/dist/chunk-VYFKOUUR.js.map +1 -0
  19. package/dist/cli.js +22 -15
  20. package/dist/cli.js.map +1 -1
  21. package/dist/{config-J5DW6HSY.js → config-YCF3HIKR.js} +7 -3
  22. package/dist/execute-QYXA225W.js +14 -0
  23. package/dist/{generate-ERDPOTKX.js → generate-TW6QKSW5.js} +6 -6
  24. package/dist/init-G57UXKDG.js +9 -0
  25. package/dist/plan-YJLGBYBQ.js +16 -0
  26. package/dist/policy-NP4ZAVF6.js +1013 -0
  27. package/dist/policy-NP4ZAVF6.js.map +1 -0
  28. package/dist/pr-V5H65MRW.js +20 -0
  29. package/dist/pr-review-RCMXKXVP.js +16 -0
  30. package/dist/prd-3XR5KYJS.js +16 -0
  31. package/dist/review-ZZG3CSUO.js +14 -0
  32. package/dist/{run-BRBFHVUO.js → run-DIBC3YKX.js} +16 -16
  33. package/dist/{web-WQISLO66.js → web-O2FVOYZW.js} +4 -4
  34. package/package.json +1 -1
  35. package/dist/chunk-57MH6RYJ.js.map +0 -1
  36. package/dist/chunk-MTJQOOMG.js.map +0 -1
  37. package/dist/execute-Z2DKGVLR.js +0 -14
  38. package/dist/init-UY6ZCIFT.js +0 -9
  39. package/dist/plan-REMAMCX4.js +0 -16
  40. package/dist/pr-KERP52TI.js +0 -20
  41. package/dist/pr-review-IU4N3TEK.js +0 -16
  42. package/dist/prd-SHVQW6RM.js +0 -16
  43. package/dist/review-L5F77QAC.js +0 -14
  44. /package/dist/{analyze-VSWAEVN3.js.map → analyze-UZYJAWAP.js.map} +0 -0
  45. /package/dist/{chunk-66ZGYXTH.js.map → chunk-2LNQL4XH.js.map} +0 -0
  46. /package/dist/{chunk-X7XBF5TS.js.map → chunk-2Z7OEZZT.js.map} +0 -0
  47. /package/dist/{chunk-VNKSMWDN.js.map → chunk-652DJBCN.js.map} +0 -0
  48. /package/dist/{chunk-DP43WJY4.js.map → chunk-67ZO5ROQ.js.map} +0 -0
  49. /package/dist/{chunk-TLSIK656.js.map → chunk-EWA3OGCM.js.map} +0 -0
  50. /package/dist/{chunk-M72ZEPWD.js.map → chunk-EZMOEBLU.js.map} +0 -0
  51. /package/dist/{chunk-JGKPSWOA.js.map → chunk-MXTGCD5C.js.map} +0 -0
  52. /package/dist/{chunk-DTNM3LTO.js.map → chunk-PPLIXZI5.js.map} +0 -0
  53. /package/dist/{chunk-KXAG24DD.js.map → chunk-S67Q4I2O.js.map} +0 -0
  54. /package/dist/{chunk-TJMZWRS6.js.map → chunk-SP7DD4ID.js.map} +0 -0
  55. /package/dist/{chunk-WHEU55ZP.js.map → chunk-UH4KAJBJ.js.map} +0 -0
  56. /package/dist/{chunk-NB6WKTBL.js.map → chunk-UUY4PCWW.js.map} +0 -0
  57. /package/dist/{chunk-M37YZYDO.js.map → chunk-VOKNTBOO.js.map} +0 -0
  58. /package/dist/{config-J5DW6HSY.js.map → config-YCF3HIKR.js.map} +0 -0
  59. /package/dist/{execute-Z2DKGVLR.js.map → execute-QYXA225W.js.map} +0 -0
  60. /package/dist/{generate-ERDPOTKX.js.map → generate-TW6QKSW5.js.map} +0 -0
  61. /package/dist/{init-UY6ZCIFT.js.map → init-G57UXKDG.js.map} +0 -0
  62. /package/dist/{plan-REMAMCX4.js.map → plan-YJLGBYBQ.js.map} +0 -0
  63. /package/dist/{pr-KERP52TI.js.map → pr-V5H65MRW.js.map} +0 -0
  64. /package/dist/{pr-review-IU4N3TEK.js.map → pr-review-RCMXKXVP.js.map} +0 -0
  65. /package/dist/{prd-SHVQW6RM.js.map → prd-3XR5KYJS.js.map} +0 -0
  66. /package/dist/{review-L5F77QAC.js.map → review-ZZG3CSUO.js.map} +0 -0
  67. /package/dist/{run-BRBFHVUO.js.map → run-DIBC3YKX.js.map} +0 -0
  68. /package/dist/{web-WQISLO66.js.map → web-O2FVOYZW.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/policy/discovery.ts","../src/policy/parsers/docs.ts","../src/policy/parsers/labels.ts","../src/policy/parsers/templates.ts","../src/policy/parsers/issue-forms.ts","../src/policy/types.ts","../src/policy/resolve.ts","../src/commands/policy.ts"],"sourcesContent":["import { readdir, readFile, stat } from 'node:fs/promises';\nimport { join, relative, sep } from 'node:path';\nimport { run } from '../utils/shell.js';\nimport { classifyDocument, extractReferencedDocuments } from './parsers/docs.js';\nimport { parseIssueTypes, parseLabels } from './parsers/labels.js';\nimport { parseIssueTemplateFile, parseOrganizationTemplates } from './parsers/templates.js';\nimport {\n type IssueTemplate,\n type LabelDefinition,\n MAX_POLICY_DOCUMENT_BYTES,\n type PolicyDocument,\n type PolicyExec,\n type PolicySource,\n type PullRequestTemplate,\n} from './types.js';\n\n/**\n * Locating the policy sources of a repository on disk and, when `gh` can\n * answer, on GitHub.\n *\n * Every function here is best-effort by construction: an unreadable directory,\n * a missing binary, a network that never answers and a repository that simply\n * declares nothing all produce the same thing — an empty result plus, when the\n * source *could* have answered, a `PolicySource` recording why it did not.\n * Discovery must never be able to break a flow that works offline today.\n */\n\n/**\n * Timeout of every `gh` and `git` invocation. Matches the `init` prerequisite\n * probes; the point is that no discovery call can hang a pipeline.\n */\nexport const DISCOVERY_TIMEOUT_MS = 10_000;\n\n/** The directories GitHub itself looks in, in the order it looks. */\nconst POLICY_DIRECTORIES = ['.github', '', 'docs'] as const;\n\nconst defaultExec: PolicyExec = (command, args, options) =>\n run(command, args, { cwd: options.cwd, timeout: options.timeout });\n\n/** Repository-relative path with POSIX separators, for stable output. */\nexport function toRelativePath(root: string, absolute: string): string {\n return relative(root, absolute).split(sep).join('/');\n}\n\n/** Directory entries, or [] when the directory is absent or unreadable. */\nasync function listDirectory(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries.filter((entry) => !entry.isDirectory()).map((entry) => entry.name);\n } catch {\n return [];\n }\n}\n\nasync function isDirectory(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Read a file, capped at {@link MAX_POLICY_DOCUMENT_BYTES}.\n *\n * Returns null when the file is absent or unreadable. The second element says\n * whether the content was truncated, so the caller can record it in `sources`\n * instead of silently handing a half document to an agent.\n */\nasync function readCapped(path: string): Promise<{ content: string; truncated: boolean } | null> {\n let raw: string;\n try {\n raw = await readFile(path, 'utf-8');\n } catch {\n return null;\n }\n\n if (Buffer.byteLength(raw, 'utf-8') <= MAX_POLICY_DOCUMENT_BYTES) {\n return { content: raw, truncated: false };\n }\n const clipped = Buffer.from(raw, 'utf-8')\n .subarray(0, MAX_POLICY_DOCUMENT_BYTES)\n .toString('utf-8');\n return { content: clipped, truncated: true };\n}\n\n/** Find an entry of `dir` whose name matches one of `names`, case-insensitively. */\nasync function findFile(dir: string, names: string[]): Promise<string | null> {\n const entries = await listDirectory(dir);\n const wanted = names.map((name) => name.toLowerCase());\n for (const name of wanted) {\n const hit = entries.find((entry) => entry.toLowerCase() === name);\n if (hit !== undefined) return hit;\n }\n return null;\n}\n\n// ── Issue Templates and Forms ───────────────────────────────────────────────\n\nconst TEMPLATE_EXTENSIONS = ['.yml', '.yaml', '.md', '.markdown'];\n\n/** The chooser configuration is not a template. */\nfunction isTemplateFile(name: string): boolean {\n const lower = name.toLowerCase();\n if (lower === 'config.yml' || lower === 'config.yaml') return false;\n return TEMPLATE_EXTENSIONS.some((extension) => lower.endsWith(extension));\n}\n\nexport interface IssueTemplateDiscovery {\n templates: IssueTemplate[];\n sources: PolicySource[];\n}\n\n/**\n * Issue Templates and Forms of the local tree.\n *\n * Searched in `.github/ISSUE_TEMPLATE/`, the repository root and `docs/`, plus\n * the single-file `ISSUE_TEMPLATE.md` variant of each — the three locations\n * GitHub honours. Files are sorted by name so two runs over the same tree\n * produce the same order.\n */\nexport async function discoverIssueTemplates(root: string): Promise<IssueTemplateDiscovery> {\n const templates: IssueTemplate[] = [];\n const sources: PolicySource[] = [];\n\n for (const base of POLICY_DIRECTORIES) {\n const baseDir = base === '' ? root : join(root, base);\n\n const templateDir = (await findDirectory(baseDir, 'ISSUE_TEMPLATE')) ?? null;\n if (templateDir !== null) {\n const names = (await listDirectory(templateDir)).filter(isTemplateFile).sort();\n for (const name of names) {\n const filePath = join(templateDir, name);\n const file = await readCapped(filePath);\n if (file === null) continue;\n const relPath = toRelativePath(root, filePath);\n templates.push(parseIssueTemplateFile(relPath, file.content));\n sources.push({\n kind: 'issue-templates',\n origin: 'filesystem',\n path: relPath,\n status: 'found',\n detail: file.truncated ? 'content truncated' : null,\n });\n }\n }\n\n const singleFile = await findFile(baseDir, [\n 'ISSUE_TEMPLATE.md',\n 'ISSUE_TEMPLATE.yml',\n 'ISSUE_TEMPLATE.yaml',\n 'ISSUE_TEMPLATE.markdown',\n ]);\n if (singleFile !== null) {\n const filePath = join(baseDir, singleFile);\n const file = await readCapped(filePath);\n if (file !== null) {\n const relPath = toRelativePath(root, filePath);\n templates.push(parseIssueTemplateFile(relPath, file.content));\n sources.push({\n kind: 'issue-templates',\n origin: 'filesystem',\n path: relPath,\n status: 'found',\n detail: file.truncated ? 'content truncated' : null,\n });\n }\n }\n }\n\n return { templates, sources };\n}\n\n/** Case-insensitive lookup of a subdirectory, returning its real path. */\nasync function findDirectory(parent: string, name: string): Promise<string | null> {\n let entries: string[];\n try {\n entries = (await readdir(parent, { withFileTypes: true }))\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n } catch {\n return null;\n }\n const hit = entries.find((entry) => entry.toLowerCase() === name.toLowerCase());\n return hit === undefined ? null : join(parent, hit);\n}\n\n// ── Pull Request template ───────────────────────────────────────────────────\n\nconst PR_TEMPLATE_FILES = [\n 'PULL_REQUEST_TEMPLATE.md',\n 'PULL_REQUEST_TEMPLATE.markdown',\n 'PULL_REQUEST_TEMPLATE.txt',\n 'PULL_REQUEST_TEMPLATE',\n];\n\nexport interface PullRequestTemplateDiscovery {\n templates: PullRequestTemplate[];\n sources: PolicySource[];\n}\n\n/**\n * Pull Request templates, in every layout GitHub supports: the single file in\n * `.github/`, the root or `docs/`, and the `PULL_REQUEST_TEMPLATE/` directory\n * that holds several named ones.\n *\n * The first template found is the default one; the rest are kept so a caller\n * can offer the choice the repository set up.\n */\nexport async function discoverPullRequestTemplates(\n root: string,\n): Promise<PullRequestTemplateDiscovery> {\n const templates: PullRequestTemplate[] = [];\n const sources: PolicySource[] = [];\n\n const collect = async (filePath: string): Promise<void> => {\n const file = await readCapped(filePath);\n if (file === null) return;\n const relPath = toRelativePath(root, filePath);\n templates.push({\n path: relPath,\n name: relPath.split('/').pop() ?? relPath,\n content: file.content,\n });\n sources.push({\n kind: 'pull-request-template',\n origin: 'filesystem',\n path: relPath,\n status: 'found',\n detail: file.truncated ? 'content truncated' : null,\n });\n };\n\n for (const base of POLICY_DIRECTORIES) {\n const baseDir = base === '' ? root : join(root, base);\n\n const single = await findFile(baseDir, PR_TEMPLATE_FILES);\n if (single !== null && !(await isDirectory(join(baseDir, single)))) {\n await collect(join(baseDir, single));\n }\n\n const templateDir = await findDirectory(baseDir, 'PULL_REQUEST_TEMPLATE');\n if (templateDir !== null) {\n for (const name of (await listDirectory(templateDir)).sort()) {\n if (!/\\.(md|markdown|txt)$/i.test(name)) continue;\n await collect(join(templateDir, name));\n }\n }\n }\n\n return { templates, sources };\n}\n\n// ── CODEOWNERS ──────────────────────────────────────────────────────────────\n\nexport interface CodeownersDiscovery {\n content: string | null;\n sources: PolicySource[];\n}\n\nexport async function discoverCodeowners(root: string): Promise<CodeownersDiscovery> {\n for (const base of POLICY_DIRECTORIES) {\n const baseDir = base === '' ? root : join(root, base);\n const name = await findFile(baseDir, ['CODEOWNERS']);\n if (name === null) continue;\n\n const file = await readCapped(join(baseDir, name));\n if (file === null) continue;\n\n const relPath = toRelativePath(root, join(baseDir, name));\n return {\n content: file.content,\n sources: [\n {\n kind: 'codeowners',\n origin: 'filesystem',\n path: relPath,\n status: 'found',\n detail: file.truncated ? 'content truncated' : null,\n },\n ],\n };\n }\n\n return { content: null, sources: [] };\n}\n\n// ── Policy documents ────────────────────────────────────────────────────────\n\n/** Root-only documents: GitHub reads these from one place, not per directory. */\nconst ROOT_DOCUMENT_FILES = ['CONTRIBUTING.md', 'CODE_OF_CONDUCT.md'];\n\n/** Per-directory agent instructions, composed from the root down to the scope. */\nconst SCOPED_DOCUMENT_FILES = ['AGENTS.md', 'CLAUDE.md'];\n\nexport interface DocumentDiscovery {\n documents: PolicyDocument[];\n sources: PolicySource[];\n}\n\n/**\n * The scope ladder: `''`, then every ancestor of `scope`, then `scope` itself.\n * Composing in this order is what makes the more specific document win — it is\n * simply the later one.\n */\nexport function scopeLadder(scope: string | null): string[] {\n if (scope === null || scope === '') return [''];\n\n const segments = scope.split('/').filter((segment) => segment !== '');\n const ladder = [''];\n let current = '';\n for (const segment of segments) {\n current = current === '' ? segment : `${current}/${segment}`;\n ladder.push(current);\n }\n return ladder;\n}\n\n/**\n * Agent instructions and governance documents applying to `scope`.\n *\n * `AGENTS.md` (the open standard) and `CLAUDE.md` are read at every level of\n * the ladder, root first, so a monorepo's `apps/api/AGENTS.md` arrives after —\n * and therefore wins over — the one at the root. `CONTRIBUTING.md` and\n * `CODE_OF_CONDUCT.md` are read once, at the root, because that is where\n * GitHub reads them from.\n *\n * Documents linked from an `AGENTS.md` are followed one level; see\n * {@link extractReferencedDocuments} for why that is a link walk rather than a\n * scan of `docs/`.\n */\nexport async function discoverDocuments(\n root: string,\n scope: string | null,\n): Promise<DocumentDiscovery> {\n const documents: PolicyDocument[] = [];\n const sources: PolicySource[] = [];\n const seen = new Set<string>();\n\n const collect = async (\n filePath: string,\n kind: PolicyDocument['kind'],\n docScope: string,\n referencedFrom: string | null,\n ): Promise<PolicyDocument | null> => {\n const relPath = toRelativePath(root, filePath);\n if (seen.has(relPath)) return null;\n\n const file = await readCapped(filePath);\n if (file === null) return null;\n seen.add(relPath);\n\n const document: PolicyDocument = {\n path: relPath,\n kind,\n scope: docScope,\n referencedFrom,\n content: file.content,\n };\n documents.push(document);\n sources.push({\n kind: 'docs',\n origin: 'filesystem',\n path: relPath,\n status: 'found',\n detail: file.truncated ? 'content truncated' : null,\n });\n return document;\n };\n\n for (const base of POLICY_DIRECTORIES) {\n const baseDir = base === '' ? root : join(root, base);\n for (const wanted of ROOT_DOCUMENT_FILES) {\n const name = await findFile(baseDir, [wanted]);\n if (name === null) continue;\n const kind = classifyDocument(name);\n if (kind === null) continue;\n await collect(join(baseDir, name), kind, '', null);\n }\n }\n\n const indexes: PolicyDocument[] = [];\n for (const level of scopeLadder(scope)) {\n const levelDir = level === '' ? root : join(root, level);\n for (const wanted of SCOPED_DOCUMENT_FILES) {\n const name = await findFile(levelDir, [wanted]);\n if (name === null) continue;\n const kind = classifyDocument(name);\n if (kind === null) continue;\n const document = await collect(join(levelDir, name), kind, level, null);\n if (document !== null && kind === 'agents') {\n indexes.push(document);\n }\n }\n }\n\n // One level only, and only from AGENTS.md: a referenced document that itself\n // links onwards does not drag its own bibliography into the context.\n for (const index of indexes) {\n for (const target of extractReferencedDocuments(index.content, index.path)) {\n await collect(join(root, target), 'referenced', index.scope, index.path);\n }\n }\n\n return { documents, sources };\n}\n\n// ── git ─────────────────────────────────────────────────────────────────────\n\nexport interface BaseBranchDiscovery {\n baseBranch: string | null;\n sources: PolicySource[];\n}\n\n/**\n * The repository's base branch, as git actually knows it.\n *\n * Unlike `utils/git.ts`'s `getBaseBranch()`, this never falls back to `'main'`:\n * a discovery layer that invents a value is indistinguishable from one that\n * found it, and `sources` would be lying. An undetermined base branch is null,\n * and the configuration layer above is free to declare one.\n */\nexport async function discoverBaseBranch(\n root: string,\n exec: PolicyExec = defaultExec,\n): Promise<BaseBranchDiscovery> {\n const options = { cwd: root, timeout: DISCOVERY_TIMEOUT_MS };\n\n try {\n const remoteHead = await exec(\n 'git',\n ['symbolic-ref', '--short', 'refs/remotes/origin/HEAD'],\n options,\n );\n if (remoteHead.exitCode === 0) {\n const name = remoteHead.stdout.trim().replace(/^origin\\//, '');\n if (name !== '') {\n return {\n baseBranch: name,\n sources: [\n {\n kind: 'base-branch',\n origin: 'git',\n path: null,\n status: 'found',\n detail: 'origin/HEAD',\n },\n ],\n };\n }\n }\n\n for (const candidate of ['main', 'master']) {\n const check = await exec(\n 'git',\n ['rev-parse', '--verify', '--quiet', `refs/heads/${candidate}`],\n options,\n );\n if (check.exitCode === 0) {\n return {\n baseBranch: candidate,\n sources: [\n {\n kind: 'base-branch',\n origin: 'git',\n path: null,\n status: 'found',\n detail: `refs/heads/${candidate}`,\n },\n ],\n };\n }\n }\n } catch {\n return {\n baseBranch: null,\n sources: [\n {\n kind: 'base-branch',\n origin: 'git',\n path: null,\n status: 'unavailable',\n detail: 'git could not be executed',\n },\n ],\n };\n }\n\n return { baseBranch: null, sources: [] };\n}\n\n/**\n * `owner` and `repo` of the `origin` remote, with their original case.\n *\n * Deliberately derived from git rather than from `gh repo view`: the identity\n * is already on disk, and spending a network round-trip on it would break the\n * \"at most one `gh` call per kind of data\" budget for nothing.\n */\nexport async function discoverGitHubSlug(\n root: string,\n exec: PolicyExec = defaultExec,\n): Promise<{ owner: string; repo: string } | null> {\n let url = '';\n try {\n const result = await exec('git', ['remote', 'get-url', 'origin'], {\n cwd: root,\n timeout: DISCOVERY_TIMEOUT_MS,\n });\n if (result.exitCode !== 0) return null;\n url = result.stdout.trim();\n } catch {\n return null;\n }\n if (url === '') return null;\n\n // Both the scp-like shorthand and every URL scheme end in `<owner>/<repo>`.\n const match = /[/:]([^/:\\s]+)\\/([^/\\s]+?)(?:\\.git)?\\/?$/.exec(url);\n if (match?.[1] === undefined || match[2] === undefined) return null;\n return { owner: match[1], repo: match[2] };\n}\n\n// ── GitHub, via gh ──────────────────────────────────────────────────────────\n\n/** One `gh` call, JSON-decoded. Returns null for every kind of failure. */\nasync function ghJson(\n root: string,\n args: string[],\n exec: PolicyExec,\n): Promise<{ value: unknown } | { error: string }> {\n let result: { stdout: string; stderr: string; exitCode: number };\n try {\n result = await exec('gh', args, { cwd: root, timeout: DISCOVERY_TIMEOUT_MS });\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) };\n }\n if (result.exitCode !== 0) {\n const stderr = result.stderr.trim().split('\\n')[0] ?? '';\n return { error: stderr === '' ? `gh exited with ${result.exitCode}` : stderr };\n }\n try {\n return { value: JSON.parse(result.stdout) as unknown };\n } catch {\n return { error: 'gh returned unparseable JSON' };\n }\n}\n\n/** How many labels a single `gh label list` page returns. */\nconst LABEL_PAGE_SIZE = 200;\n\nexport interface LabelDiscovery {\n labels: LabelDefinition[];\n sources: PolicySource[];\n}\n\n/**\n * The labels that exist in the repository.\n *\n * A machine with no `gh`, no authentication or no network degrades to an empty\n * list and a single `unavailable` source — never to a warning, and never to a\n * failure: reading labels is an enrichment, not a prerequisite.\n */\nexport async function discoverLabels(\n root: string,\n exec: PolicyExec = defaultExec,\n): Promise<LabelDiscovery> {\n const outcome = await ghJson(\n root,\n ['label', 'list', '--json', 'name,description,color', '--limit', String(LABEL_PAGE_SIZE)],\n exec,\n );\n\n if ('error' in outcome) {\n return {\n labels: [],\n sources: [\n { kind: 'labels', origin: 'gh', path: null, status: 'unavailable', detail: outcome.error },\n ],\n };\n }\n\n const labels = parseLabels(outcome.value);\n return {\n labels,\n sources: [\n {\n kind: 'labels',\n origin: 'gh',\n path: null,\n status: 'found',\n detail: `${labels.length} label(s)`,\n },\n ],\n };\n}\n\nexport interface IssueTypeDiscovery {\n types: string[];\n sources: PolicySource[];\n}\n\n/**\n * Issue Types of the organization owning the repository.\n *\n * Requires the owner, which comes from the git remote; a repository with no\n * remote simply has no organization to ask about, which is an ordinary state\n * and not an `unavailable` source.\n */\nexport async function discoverIssueTypes(\n root: string,\n owner: string | null,\n exec: PolicyExec = defaultExec,\n): Promise<IssueTypeDiscovery> {\n if (owner === null || owner === '') {\n return { types: [], sources: [] };\n }\n\n const outcome = await ghJson(root, ['api', `orgs/${owner}/issue-types`], exec);\n if ('error' in outcome) {\n return {\n types: [],\n sources: [\n {\n kind: 'issue-types',\n origin: 'gh',\n path: null,\n // A personal account (404) and a plan without Issue Types (403) are\n // the common answers here, so the detail carries what gh said.\n status: 'unavailable',\n detail: outcome.error,\n },\n ],\n };\n }\n\n const types = parseIssueTypes(outcome.value);\n return {\n types,\n sources: [\n {\n kind: 'issue-types',\n origin: 'gh',\n path: null,\n status: 'found',\n detail: `${types.length} type(s)`,\n },\n ],\n };\n}\n\n/**\n * The `issueTemplates` connection, as one GraphQL document.\n *\n * Owner and repository travel as GraphQL variables rather than being spliced\n * into the query text: they come from a git remote, which is user-controlled\n * input, and a query built by concatenation is a query someone can rewrite.\n */\nconst ORGANIZATION_TEMPLATES_QUERY = `query($owner:String!,$name:String!){\n repository(owner:$owner,name:$name){\n issueTemplates{\n name\n title\n about\n filename\n body\n assignees(first:10){nodes{login}}\n labels(first:20){nodes{name}}\n }\n }\n}`;\n\n/**\n * Issue Templates served by GitHub, including the ones the organization's\n * `.github` repository provides.\n *\n * Only consulted when the local tree has none: that is precisely the case local\n * discovery cannot see, and consulting it otherwise would spend a round-trip to\n * re-learn what is already on disk.\n *\n * GraphQL, not REST: the REST API exposes no issue-template endpoint at all,\n * and the connection returns the bodies inline, so the organization defaults\n * cost a single round-trip instead of one listing plus one call per template.\n */\nexport async function discoverOrganizationTemplates(\n root: string,\n slug: { owner: string; repo: string } | null,\n exec: PolicyExec = defaultExec,\n): Promise<IssueTemplateDiscovery> {\n if (slug === null) {\n return { templates: [], sources: [] };\n }\n\n const outcome = await ghJson(\n root,\n [\n 'api',\n 'graphql',\n '-f',\n `query=${ORGANIZATION_TEMPLATES_QUERY}`,\n '-f',\n `owner=${slug.owner}`,\n '-f',\n `name=${slug.repo}`,\n ],\n exec,\n );\n if ('error' in outcome) {\n return {\n templates: [],\n sources: [\n {\n kind: 'issue-templates',\n origin: 'gh',\n path: null,\n status: 'unavailable',\n detail: outcome.error,\n },\n ],\n };\n }\n\n const templates = parseOrganizationTemplates(outcome.value);\n if (templates.length === 0) {\n return { templates, sources: [] };\n }\n return {\n templates,\n sources: templates.map((template) => ({\n kind: 'issue-templates' as const,\n origin: 'gh' as const,\n path: null,\n status: 'found' as const,\n detail: `organization default \"${template.name}\"`,\n })),\n };\n}\n","import { posix } from 'node:path';\nimport type { PolicyDocumentKind } from '../types.js';\n\n/**\n * Classification and link extraction for the prose documents that carry\n * repository policy.\n */\n\n/** Which kind of policy document a file name denotes, or null. */\nexport function classifyDocument(fileName: string): PolicyDocumentKind | null {\n switch (fileName.toLowerCase()) {\n case 'agents.md':\n return 'agents';\n case 'claude.md':\n return 'claude';\n case 'contributing.md':\n return 'contributing';\n case 'code_of_conduct.md':\n case 'code-of-conduct.md':\n return 'code-of-conduct';\n default:\n return null;\n }\n}\n\n/** How many referenced documents a single index may pull in. */\nexport const MAX_REFERENCED_DOCUMENTS = 20;\n\nconst MARKDOWN_LINK = /\\[[^\\]\\n]*\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g;\n\n/**\n * Repository-relative paths of the markdown documents an index links to.\n *\n * `AGENTS.md` is an index, not a corpus: following its links one level respects\n * what the repository chose to point at, where scanning `docs/` blindly would\n * pull in changelogs, ADR archives and translated copies — a large context cost\n * for content the repository never nominated as policy.\n *\n * Only in-repository markdown targets survive: an absolute URL, a mailto, an\n * anchor, a path that escapes the root, or a link to a non-markdown asset are\n * all dropped. `fromPath` is the repository-relative path of the linking\n * document, used to resolve relative links.\n */\nexport function extractReferencedDocuments(content: string, fromPath: string): string[] {\n const fromDir = posix.dirname(fromPath.replace(/\\\\/g, '/'));\n const found: string[] = [];\n\n for (const match of content.matchAll(MARKDOWN_LINK)) {\n const raw = match[1];\n if (raw === undefined) continue;\n\n const target = raw.split('#')[0]?.split('?')[0]?.trim() ?? '';\n if (target === '') continue;\n // Absolute URLs, protocol-relative URLs and mail links point outside the\n // repository; a Windows-style drive letter is not a repository path either.\n if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(target) || target.startsWith('//')) continue;\n if (!/\\.(md|markdown)$/i.test(target)) continue;\n\n const resolved = posix.normalize(\n target.startsWith('/')\n ? target.slice(1)\n : fromDir === '.'\n ? target\n : posix.join(fromDir, target),\n );\n if (resolved.startsWith('..') || resolved === '' || resolved === '.') continue;\n if (resolved === fromPath || found.includes(resolved)) continue;\n\n found.push(resolved);\n if (found.length >= MAX_REFERENCED_DOCUMENTS) break;\n }\n\n return found;\n}\n","import type { LabelDefinition } from '../types.js';\n\n/**\n * Parse `gh label list --json name,description,color`.\n *\n * These are the labels that *really exist*. The distinction matters: a pipeline\n * that invents a label either fails to apply it or, worse, creates it — and a\n * taxonomy nobody agreed to is harder to undo than a missing label.\n *\n * Never throws: a payload that is not an array of label-shaped objects yields\n * an empty list, indistinguishable to the caller from \"gh answered nothing\".\n */\nexport function parseLabels(payload: unknown): LabelDefinition[] {\n if (!Array.isArray(payload)) return [];\n\n const labels: LabelDefinition[] = [];\n for (const entry of payload) {\n if (entry === null || typeof entry !== 'object') continue;\n const record = entry as Record<string, unknown>;\n const name = typeof record.name === 'string' ? record.name.trim() : '';\n if (name === '') continue;\n\n const description = typeof record.description === 'string' ? record.description.trim() : '';\n const color = typeof record.color === 'string' ? record.color.trim() : '';\n\n labels.push({\n name,\n description: description === '' ? null : description,\n color: color === '' ? null : color,\n });\n }\n return labels;\n}\n\n/**\n * Parse `gh api orgs/{org}/issue-types`.\n *\n * Issue Types are an organization-level taxonomy exposed only on some plans, so\n * an empty result is the normal case rather than a failure.\n */\nexport function parseIssueTypes(payload: unknown): string[] {\n const entries = Array.isArray(payload)\n ? payload\n : Array.isArray((payload as { issue_types?: unknown })?.issue_types)\n ? (payload as { issue_types: unknown[] }).issue_types\n : [];\n\n const types: string[] = [];\n for (const entry of entries) {\n const name =\n typeof entry === 'string'\n ? entry\n : entry !== null && typeof entry === 'object'\n ? (entry as Record<string, unknown>).name\n : undefined;\n if (typeof name !== 'string') continue;\n const trimmed = name.trim();\n if (trimmed !== '' && !types.includes(trimmed)) {\n types.push(trimmed);\n }\n }\n return types;\n}\n","import { basename, extname } from 'node:path';\nimport type { IssueTemplate } from '../types.js';\nimport { emptyTemplateMetadata, extractFrontMatter, parseTemplateMetadata } from './issue-forms.js';\n\n/**\n * Turn a template file into an {@link IssueTemplate}.\n *\n * The format is decided by the extension, not by the content: `.yml`/`.yaml` is\n * an Issue Form whose whole document is metadata, everything else is a legacy\n * markdown template whose metadata — if any — lives in a front matter block.\n */\nexport function parseIssueTemplateFile(relPath: string, content: string): IssueTemplate {\n const extension = extname(relPath).toLowerCase();\n const isForm = extension === '.yml' || extension === '.yaml';\n\n const metadataSource = isForm ? content : extractFrontMatter(content);\n const metadata =\n metadataSource === null ? emptyTemplateMetadata() : parseTemplateMetadata(metadataSource);\n\n return {\n path: relPath,\n format: isForm ? 'form' : 'markdown',\n origin: 'filesystem',\n // A template with no `name:` is still addressable by its file name, which\n // is what GitHub falls back to for legacy markdown templates.\n name: metadata.name ?? basename(relPath, extension),\n about: metadata.about,\n title: metadata.title,\n labels: metadata.labels,\n type: metadata.type,\n assignees: metadata.assignees,\n content,\n };\n}\n\nfunction asString(value: unknown): string | null {\n return typeof value === 'string' && value.trim() !== '' ? value : null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Read a GraphQL connection (`{ nodes: [{ name }] }`) as a list of names, also\n * accepting a plain array of strings so a shape change does not break parsing.\n */\nfunction asNameList(value: unknown, key: 'name' | 'login'): string[] {\n const entries = Array.isArray(value)\n ? value\n : isRecord(value) && Array.isArray(value.nodes)\n ? value.nodes\n : [];\n\n return entries\n .map((entry) =>\n typeof entry === 'string' ? entry : asString(isRecord(entry) ? entry[key] : null),\n )\n .filter((entry): entry is string => entry !== null && entry !== '');\n}\n\n/**\n * Parse the `repository.issueTemplates` connection of the GitHub GraphQL API.\n *\n * This is what makes the organization's `.github` repository visible: a\n * repository with no `.github/ISSUE_TEMPLATE/` of its own still serves the\n * organization defaults on github.com, and no amount of local filesystem\n * discovery can see them. GraphQL is used rather than REST because REST simply\n * has no endpoint for issue templates — and because the connection answers with\n * the bodies included, which keeps the whole discovery to a single round-trip.\n *\n * Never throws: an error payload, a missing repository or anything that is not\n * a list of template-shaped objects yields an empty list, which the caller\n * treats exactly like \"GitHub answered nothing\".\n */\nexport function parseOrganizationTemplates(payload: unknown): IssueTemplate[] {\n const repository = isRecord(payload) && isRecord(payload.data) ? payload.data.repository : null;\n const entries = isRecord(repository) ? repository.issueTemplates : null;\n if (!Array.isArray(entries)) return [];\n\n const templates: IssueTemplate[] = [];\n for (const entry of entries) {\n if (!isRecord(entry)) continue;\n const name = asString(entry.name);\n if (name === null) continue;\n\n templates.push({\n // The filename is the stable identity; the display name is not unique.\n path: asString(entry.filename) ?? name,\n format: 'markdown',\n origin: 'organization',\n name,\n about: asString(entry.about),\n title: asString(entry.title),\n labels: asNameList(entry.labels, 'name'),\n // GraphQL exposes no Issue Type on a template, so it stays unknown here\n // rather than being guessed from the name.\n type: null,\n assignees: asNameList(entry.assignees, 'login'),\n content: asString(entry.body) ?? '',\n });\n }\n return templates;\n}\n","/**\n * A deliberately small YAML reader for Issue Form and Issue Template metadata.\n *\n * Issue Flow does not need a YAML engine: it needs six top-level keys (`name`,\n * `description`/`about`, `title`, `labels`, `type`, `assignees`) out of a file\n * whose remaining structure — the `body:` array of form elements — it has no\n * use for. Pulling a parser dependency in to read those six keys would trade a\n * supply-chain surface for nothing.\n *\n * The reader therefore works on top-level keys only: it locates every line that\n * starts a key at indentation zero, and parses the region of the ones it cares\n * about. Anything nested (a `body:` element, its `attributes:`) is skipped\n * whole, which is why `- type: markdown` inside `body:` can never be mistaken\n * for the top-level `type:` of an Issue Type.\n */\n\n/** The metadata block shared by Issue Forms (`.yml`) and templates (`.md`). */\nexport interface TemplateMetadata {\n name: string | null;\n about: string | null;\n title: string | null;\n labels: string[];\n type: string | null;\n assignees: string[];\n}\n\nexport function emptyTemplateMetadata(): TemplateMetadata {\n return { name: null, about: null, title: null, labels: [], type: null, assignees: [] };\n}\n\nconst TOP_LEVEL_KEY = /^([A-Za-z_][A-Za-z0-9_-]*):(?:\\s+(.*))?$/;\n\ninterface KeyRegion {\n key: string;\n /** Text on the key's own line, after the colon. Empty when the value is a block. */\n inline: string;\n /** Lines below the key, up to the next top-level key. */\n block: string[];\n}\n\n/**\n * Split a YAML document into its top-level key regions.\n *\n * Exported for the templates parser, which reads the same regions out of a\n * markdown front matter block.\n */\nexport function topLevelRegions(source: string): Map<string, KeyRegion> {\n const regions = new Map<string, KeyRegion>();\n const lines = source.split(/\\r?\\n/);\n\n let current: KeyRegion | null = null;\n for (const line of lines) {\n // A line that begins with whitespace, a dash or a comment can never open a\n // top-level key, so it always belongs to the region already open.\n const match = /^[^\\s#-]/.test(line) ? TOP_LEVEL_KEY.exec(line) : null;\n if (match?.[1] !== undefined) {\n current = { key: match[1], inline: (match[2] ?? '').trim(), block: [] };\n // First occurrence wins, matching how a YAML loader would report a\n // duplicate key as a document error rather than silently taking the last.\n if (!regions.has(current.key)) {\n regions.set(current.key, current);\n }\n continue;\n }\n current?.block.push(line);\n }\n\n return regions;\n}\n\n/** Strip a trailing `# comment` that is not inside quotes. */\nfunction stripComment(value: string): string {\n let quote: string | null = null;\n for (let i = 0; i < value.length; i++) {\n const char = value[i];\n if (quote !== null) {\n if (char === quote) quote = null;\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n continue;\n }\n if (char === '#' && (i === 0 || /\\s/.test(value[i - 1] ?? ''))) {\n return value.slice(0, i);\n }\n }\n return value;\n}\n\n/** Unquote a scalar, handling the two YAML quoting styles. */\nfunction unquote(value: string): string {\n const trimmed = value.trim();\n if (trimmed.length >= 2) {\n const first = trimmed[0];\n const last = trimmed[trimmed.length - 1];\n if (first === '\"' && last === '\"') {\n return trimmed.slice(1, -1).replace(/\\\\([\"\\\\])/g, '$1');\n }\n if (first === \"'\" && last === \"'\") {\n return trimmed.slice(1, -1).replace(/''/g, \"'\");\n }\n }\n return trimmed;\n}\n\n/** Split a flow sequence body (`a, \"b, c\", d`) on its top-level commas. */\nfunction splitFlow(inner: string): string[] {\n const parts: string[] = [];\n let buffer = '';\n let quote: string | null = null;\n\n for (const char of inner) {\n if (quote !== null) {\n if (char === quote) quote = null;\n buffer += char;\n continue;\n }\n if (char === '\"' || char === \"'\") {\n quote = char;\n buffer += char;\n continue;\n }\n if (char === ',') {\n parts.push(buffer);\n buffer = '';\n continue;\n }\n buffer += char;\n }\n parts.push(buffer);\n\n return parts.map(unquote).filter((part) => part !== '');\n}\n\n/** Read a region as a scalar, returning null when it holds no usable value. */\nfunction readScalar(region: KeyRegion | undefined): string | null {\n if (region === undefined) return null;\n\n const inline = stripComment(region.inline).trim();\n if (inline !== '' && inline !== '|' && inline !== '>' && inline !== '|-' && inline !== '>-') {\n const value = unquote(inline);\n return value === '' ? null : value;\n }\n\n // Block scalar (`|`, `>`) or a value that simply starts on the next line.\n const collected = region.block\n .filter((line) => line.trim() !== '')\n .map((line) => line.trim())\n .join(inline.startsWith('>') ? ' ' : '\\n')\n .trim();\n return collected === '' ? null : collected;\n}\n\n/** Read a region as a sequence, accepting both the flow and the block style. */\nfunction readSequence(region: KeyRegion | undefined): string[] {\n if (region === undefined) return [];\n\n const inline = stripComment(region.inline).trim();\n if (inline.startsWith('[')) {\n const closing = inline.lastIndexOf(']');\n return splitFlow(inline.slice(1, closing === -1 ? undefined : closing));\n }\n if (inline !== '') {\n // A bare scalar where a list was expected — GitHub accepts `labels: bug`.\n const single = unquote(inline);\n return single === '' ? [] : [single];\n }\n\n const items: string[] = [];\n for (const line of region.block) {\n const trimmed = line.trim();\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n if (!trimmed.startsWith('- ') && trimmed !== '-') break;\n const value = unquote(stripComment(trimmed.slice(1)).trim());\n // `- key: value` is a mapping, not a label — a list of those is not a\n // taxonomy and taking its first line would invent one.\n if (value === '' || /^[A-Za-z_][A-Za-z0-9_-]*:\\s/.test(value)) continue;\n items.push(value);\n }\n return items;\n}\n\n/**\n * Read the metadata of an Issue Form or Issue Template body.\n *\n * Never throws: a file that is not YAML at all yields empty metadata, which is\n * the same thing the caller does with a template it cannot understand.\n */\nexport function parseTemplateMetadata(source: string): TemplateMetadata {\n const regions = topLevelRegions(source);\n\n return {\n name: readScalar(regions.get('name')),\n // Issue Forms spell it `description`, legacy markdown templates `about`.\n about: readScalar(regions.get('about')) ?? readScalar(regions.get('description')),\n title: readScalar(regions.get('title')),\n labels: readSequence(regions.get('labels')),\n type: readScalar(regions.get('type')),\n assignees: readSequence(regions.get('assignees')),\n };\n}\n\n/**\n * Extract the YAML front matter of a markdown template.\n *\n * Returns null when the file does not open with a `---` fence, which is the\n * common case for a plain `.md` template with no metadata at all.\n */\nexport function extractFrontMatter(source: string): string | null {\n const normalized = source.replace(/^\\uFEFF/, '');\n if (!/^---[ \\t]*\\r?\\n/.test(normalized)) return null;\n\n const rest = normalized.slice(normalized.indexOf('\\n') + 1);\n const closing = /^---[ \\t]*$/m.exec(rest);\n if (closing?.index === undefined) return null;\n\n return rest.slice(0, closing.index);\n}\n","/**\n * The repository policy layer: what the *consumer* repository already declares\n * about how issues, Pull Requests, branches and agents are supposed to work.\n *\n * Every field is discovered, never invented. A repository that declares nothing\n * produces an empty policy — which is exactly the behaviour Issue Flow had\n * before this layer existed.\n */\n\n/**\n * Version of the {@link RepositoryPolicy} shape. Bumped whenever a consumer\n * reading `issue-flow policy --json` would have to change to keep working;\n * purely additive fields do not bump it.\n */\nexport const POLICY_SCHEMA_VERSION = 1;\n\n/** What a {@link PolicySource} is accounting for. */\nexport type PolicySourceKind =\n | 'issue-templates'\n | 'issue-types'\n | 'labels'\n | 'pull-request-template'\n | 'base-branch'\n | 'docs'\n | 'codeowners';\n\n/** Where a {@link PolicySource} came from. */\nexport type PolicySourceOrigin = 'filesystem' | 'gh' | 'git' | 'config' | 'env' | 'cli';\n\n/**\n * Outcome of consulting a source.\n *\n * `found` and `disabled` are ordinary states. `unavailable` is the one that\n * matters for debugging: the source *could* have answered but did not — no\n * `gh`, no network, a timeout — and the policy is therefore incomplete rather\n * than empty. Nothing absent is recorded: a repository without a\n * `CONTRIBUTING.md` would otherwise drown `sources` in negative entries.\n */\nexport type PolicySourceStatus = 'found' | 'unavailable' | 'disabled';\n\n/**\n * Provenance of one piece of the resolved policy.\n *\n * Not an accessory: without it there is no way to explain why a decision was\n * taken, nor to debug a wrong discovery.\n */\nexport interface PolicySource {\n kind: PolicySourceKind;\n origin: PolicySourceOrigin;\n /** Repository-relative path (POSIX separators), or null for non-file sources. */\n path: string | null;\n status: PolicySourceStatus;\n /** Human-readable note: the gh command that failed, the reason, a count. */\n detail: string | null;\n}\n\n/** An Issue Template or Issue Form declared by the repository. */\nexport interface IssueTemplate {\n /** Repository-relative path, or the org-level template name when remote. */\n path: string;\n /** `form` for a GitHub Issue Form (`.yml`), `markdown` for a legacy template. */\n format: 'form' | 'markdown';\n /** Where the template was found — the local tree or the organization defaults. */\n origin: 'filesystem' | 'organization';\n name: string | null;\n about: string | null;\n /** Pre-filled title, which is also the closest thing to a title convention. */\n title: string | null;\n labels: string[];\n /** GitHub Issue Type declared by the template (`type:` key), when present. */\n type: string | null;\n assignees: string[];\n /** Raw file content, truncated at {@link MAX_POLICY_DOCUMENT_BYTES}. */\n content: string;\n}\n\n/** A label that really exists in the repository. */\nexport interface LabelDefinition {\n name: string;\n description: string | null;\n color: string | null;\n}\n\n/** A Pull Request template file. */\nexport interface PullRequestTemplate {\n path: string;\n name: string;\n content: string;\n}\n\n/** What a {@link PolicyDocument} is. */\nexport type PolicyDocumentKind =\n | 'agents'\n | 'claude'\n | 'contributing'\n | 'code-of-conduct'\n | 'referenced';\n\n/** A prose document that carries repository policy. */\nexport interface PolicyDocument {\n path: string;\n kind: PolicyDocumentKind;\n /**\n * Directory the document governs, repository-relative; `''` is the root.\n * Documents are ordered from the root down to the requested scope, so the\n * later entry is the more specific one.\n */\n scope: string;\n /** Repository-relative path of the document that linked to this one. */\n referencedFrom: string | null;\n /** File content, truncated at {@link MAX_POLICY_DOCUMENT_BYTES}. */\n content: string;\n}\n\n/** Conventions of the repository around issues. */\nexport interface PolicyIssues {\n templates: IssueTemplate[];\n /** Issue Types of the organization, when the plan exposes them. */\n types: string[];\n /** Labels that really exist in the repository, never a guessed taxonomy. */\n labels: LabelDefinition[];\n titleConvention: string | null;\n}\n\n/** Conventions of the repository around Pull Requests. */\nexport interface PolicyPullRequests {\n /** Content of the default Pull Request template, or null. */\n template: string | null;\n /** Every template found, for the multi-template directory layout. */\n templates: PullRequestTemplate[];\n baseBranch: string | null;\n titleConvention: string | null;\n}\n\n/** Conventions of the repository around git itself. */\nexport interface PolicyGit {\n branchConvention: string | null;\n commitConvention: string | null;\n}\n\n/** The resolved policy of a repository, at a given scope. */\nexport interface RepositoryPolicy {\n schemaVersion: typeof POLICY_SCHEMA_VERSION;\n /** Absolute path of the repository root the policy was resolved against. */\n root: string;\n /** Repository-relative subdirectory the policy was resolved for, or null. */\n scope: string | null;\n /** False when `policy.enabled` is off — every section is then empty. */\n enabled: boolean;\n issues: PolicyIssues;\n pullRequests: PolicyPullRequests;\n git: PolicyGit;\n docs: PolicyDocument[];\n /** Content of the CODEOWNERS file, or null. */\n codeowners: string | null;\n sources: PolicySource[];\n}\n\n/** Result of an external command, mirroring `utils/shell.ts`'s ExecResult. */\nexport interface PolicyExecResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n/**\n * Seam for every external command the discovery shells out to (`gh`, `git`).\n * Injectable so the suite can exercise both the answer and the absence without\n * a real binary.\n */\nexport type PolicyExec = (\n command: string,\n args: string[],\n options: { cwd: string; timeout: number },\n) => Promise<PolicyExecResult>;\n\n/**\n * Upper bound on the bytes read from any single policy document or template.\n *\n * Discovery feeds an agent's context window: an unbounded `AGENTS.md` would\n * cost more than it explains. Truncation is recorded in `sources`.\n */\nexport const MAX_POLICY_DOCUMENT_BYTES = 64 * 1024;\n","import { isAbsolute, normalize, sep } from 'node:path';\nimport { loadPolicyConfig, mergeConfigLayers } from '../config.js';\nimport type { PolicyConfig, PolicyConfigInput } from '../schemas.js';\nimport { printWarning } from '../ui/logger.js';\nimport { getProjectRoot } from '../utils/git.js';\nimport {\n discoverBaseBranch,\n discoverCodeowners,\n discoverDocuments,\n discoverGitHubSlug,\n discoverIssueTemplates,\n discoverIssueTypes,\n discoverLabels,\n discoverOrganizationTemplates,\n discoverPullRequestTemplates,\n} from './discovery.js';\nimport {\n POLICY_SCHEMA_VERSION,\n type PolicyExec,\n type PolicyGit,\n type PolicyIssues,\n type PolicyPullRequests,\n type PolicySource,\n type RepositoryPolicy,\n} from './types.js';\n\n/**\n * Resolution of the repository policy: discovery, precedence, scope and cache.\n */\n\nexport interface LoadRepositoryPolicyOptions {\n /** Repository root. Defaults to the git project root. */\n root?: string;\n /** Subdirectory the policy applies to, for monorepos. Root when omitted. */\n scope?: string | null;\n /** CLI overrides of the `policy` key. */\n cli?: PolicyConfigInput;\n /** Environment source. Defaults to process.env. */\n env?: NodeJS.ProcessEnv;\n /** Warning sink. Defaults to printWarning. */\n warn?: (message: string) => void;\n /** External command seam, for tests. Defaults to `utils/shell.ts`'s `run`. */\n exec?: PolicyExec;\n /** Set to false to bypass the per-process cache. Defaults to true. */\n cache?: boolean;\n}\n\n/**\n * Normalize a scope into a repository-relative POSIX path, or null.\n *\n * An absolute path, a path escaping the root and `.` all mean \"the root\": a\n * scope is a hint about where in a monorepo the work is happening, never a way\n * to read outside the repository.\n */\nexport function normalizeScope(scope: string | null | undefined): string | null {\n if (scope === null || scope === undefined) return null;\n\n const trimmed = scope.trim();\n if (trimmed === '' || trimmed === '.' || isAbsolute(trimmed)) return null;\n\n const normalized = normalize(trimmed)\n .split(sep)\n .join('/')\n .replace(/^\\.\\//, '')\n .replace(/\\/+$/, '');\n if (normalized === '' || normalized === '.' || normalized.startsWith('..')) return null;\n\n return normalized;\n}\n\n/** An enabled policy with nothing in it — also the shape of a disabled one. */\nfunction emptyPolicy(\n root: string,\n scope: string | null,\n enabled: boolean,\n sources: PolicySource[],\n): RepositoryPolicy {\n return {\n schemaVersion: POLICY_SCHEMA_VERSION,\n root,\n scope,\n enabled,\n issues: { templates: [], types: [], labels: [], titleConvention: null },\n pullRequests: { template: null, templates: [], baseBranch: null, titleConvention: null },\n git: { branchConvention: null, commitConvention: null },\n docs: [],\n codeowners: null,\n sources,\n };\n}\n\n/** Provenance entry for a discovery pass the configuration turned off. */\nfunction disabledSource(kind: PolicySource['kind']): PolicySource {\n return {\n kind,\n origin: 'config',\n path: null,\n status: 'disabled',\n detail: 'disabled by configuration',\n };\n}\n\n/** Which `sources` entry a declared configuration key is accounted under. */\nconst DECLARATION_KINDS = {\n issues: 'issue-templates',\n pullRequests: 'pull-request-template',\n git: 'base-branch',\n} as const satisfies Record<string, PolicySource['kind']>;\n\n/**\n * Resolve the policy of `root` for `scope`, uncached.\n *\n * The ladder, exactly as `mergeConfigLayers` applies it:\n *\n * Issue Flow defaults < discovered repository policies\n * < \"policy\" key of .issue-flow.json < ISSUE_FLOW_POLICY_* < CLI flags\n *\n * The three explicit layers are already collapsed by `loadPolicyConfig()`, so\n * what arrives here is \"the defaults\" and \"what the user declared\", with the\n * discovery in between. A declaration therefore corrects a wrong discovery\n * without having to disable it, and `discovery.*: false` turns a whole pass off\n * for the case where the discovery is not merely wrong but unwanted.\n */\nasync function resolvePolicy(\n root: string,\n scope: string | null,\n options: LoadRepositoryPolicyOptions,\n): Promise<RepositoryPolicy> {\n const warn = options.warn ?? printWarning;\n const config: PolicyConfig = await loadPolicyConfig({\n projectRoot: root,\n env: options.env,\n cli: options.cli,\n warn,\n });\n\n if (!config.enabled) {\n // Not a single stat() or round-trip: \"off\" has to be free, otherwise it is\n // not really a way out of a discovery that is misbehaving.\n return emptyPolicy(root, scope, false, [\n { kind: 'docs', origin: 'config', path: null, status: 'disabled', detail: 'policy.enabled' },\n ]);\n }\n\n const toggles = config.discovery;\n\n const [templateDiscovery, prTemplates, documents, codeowners] = await Promise.all([\n toggles.issueTemplates\n ? discoverIssueTemplates(root)\n : Promise.resolve({ templates: [], sources: [disabledSource('issue-templates')] }),\n toggles.pullRequestTemplate\n ? discoverPullRequestTemplates(root)\n : Promise.resolve({ templates: [], sources: [disabledSource('pull-request-template')] }),\n toggles.docs\n ? discoverDocuments(root, scope)\n : Promise.resolve({ documents: [], sources: [disabledSource('docs')] }),\n toggles.codeowners\n ? discoverCodeowners(root)\n : Promise.resolve({ content: null, sources: [disabledSource('codeowners')] }),\n ]);\n\n // The organization defaults are only worth asking for when the local tree has\n // none — that is precisely the case local discovery cannot see.\n const wantsOrgTemplates = toggles.issueTemplates && templateDiscovery.templates.length === 0;\n const [baseBranch, slug] = await Promise.all([\n discoverBaseBranch(root, options.exec),\n toggles.issueTypes || wantsOrgTemplates\n ? discoverGitHubSlug(root, options.exec)\n : Promise.resolve(null),\n ]);\n\n const [labels, issueTypes, orgTemplates] = await Promise.all([\n toggles.labels\n ? discoverLabels(root, options.exec)\n : Promise.resolve({ labels: [], sources: [disabledSource('labels')] }),\n toggles.issueTypes\n ? discoverIssueTypes(root, slug?.owner ?? null, options.exec)\n : Promise.resolve({ types: [], sources: [disabledSource('issue-types')] }),\n wantsOrgTemplates\n ? discoverOrganizationTemplates(root, slug, options.exec)\n : Promise.resolve({ templates: [], sources: [] }),\n ]);\n\n const sources: PolicySource[] = [\n ...templateDiscovery.sources,\n ...orgTemplates.sources,\n ...issueTypes.sources,\n ...labels.sources,\n ...prTemplates.sources,\n ...baseBranch.sources,\n ...documents.sources,\n ...codeowners.sources,\n ];\n\n // Only the base branch is inferable today; the conventions have no reliable\n // signal in a repository and are therefore declared, never guessed.\n const discoveredPullRequests: Partial<PolicyPullRequests> = {};\n if (baseBranch.baseBranch !== null) {\n discoveredPullRequests.baseBranch = baseBranch.baseBranch;\n }\n\n const issues = mergeConfigLayers<PolicyIssues>({\n defaults: { titleConvention: null },\n project: config.issues,\n });\n const pullRequests = mergeConfigLayers<PolicyPullRequests>({\n defaults: { baseBranch: null, titleConvention: null },\n discovered: discoveredPullRequests,\n project: config.pullRequests,\n });\n const git = mergeConfigLayers<PolicyGit>({\n defaults: { branchConvention: null, commitConvention: null },\n project: config.git,\n });\n\n for (const group of ['issues', 'pullRequests', 'git'] as const) {\n for (const key of Object.keys(config[group])) {\n sources.push({\n kind: DECLARATION_KINDS[group],\n origin: 'config',\n path: null,\n status: 'found',\n detail: `${group}.${key} declared`,\n });\n }\n }\n\n return {\n schemaVersion: POLICY_SCHEMA_VERSION,\n root,\n scope,\n enabled: true,\n issues: {\n templates: [...templateDiscovery.templates, ...orgTemplates.templates],\n types: issueTypes.types,\n labels: labels.labels,\n titleConvention: issues.titleConvention ?? null,\n },\n pullRequests: {\n template: prTemplates.templates[0]?.content ?? null,\n templates: prTemplates.templates,\n baseBranch: pullRequests.baseBranch ?? null,\n titleConvention: pullRequests.titleConvention ?? null,\n },\n git: {\n branchConvention: git.branchConvention ?? null,\n commitConvention: git.commitConvention ?? null,\n },\n docs: documents.documents,\n codeowners: codeowners.content,\n sources,\n };\n}\n\n/**\n * Per-process cache, keyed by `(root, scope)`.\n *\n * Discovery walks the filesystem and may talk to `gh`; a pipeline that resolved\n * it once per phase would pay that several times over for an answer that cannot\n * change mid-run. The promise — not its result — is cached, so two concurrent\n * callers share a single discovery instead of racing two.\n */\nconst cache = new Map<string, Promise<RepositoryPolicy>>();\n\n/** Drop every cached resolution. Exported for tests and long-lived processes. */\nexport function resetPolicyCache(): void {\n cache.clear();\n}\n\n/**\n * The repository policy applying to `scope`, resolved once per process.\n *\n * Never throws for a repository that declares nothing: the result is an empty\n * policy, with no warning, and every consumer keeps its own defaults. The only\n * error it can raise is the one `getProjectRoot()` already raises when there is\n * no repository at all — and passing `root` avoids even that.\n */\nexport async function loadRepositoryPolicy(\n options: LoadRepositoryPolicyOptions = {},\n): Promise<RepositoryPolicy> {\n const root = options.root ?? (await getProjectRoot());\n const scope = normalizeScope(options.scope);\n\n if (options.cache === false) {\n return resolvePolicy(root, scope, options);\n }\n\n const key = `${root}\u0000${scope ?? ''}`;\n const cached = cache.get(key);\n if (cached !== undefined) {\n return cached;\n }\n\n const pending = resolvePolicy(root, scope, options);\n cache.set(key, pending);\n try {\n return await pending;\n } catch (err) {\n // A rejected promise must not be served to every later caller.\n cache.delete(key);\n throw err;\n }\n}\n","import type { PolicySource, RepositoryPolicy } from '../policy/index.js';\nimport { loadRepositoryPolicy } from '../policy/index.js';\nimport { printError, printInfo, printWarning } from '../ui/logger.js';\n\n/**\n * `issue-flow policy [--scope <dir>] [--json]`.\n *\n * The inspection surface of the policy layer, and the only one for now: this\n * issue delivers the foundation, so no prompt and no skill consumes\n * `loadRepositoryPolicy()` yet.\n *\n * It exists for two audiences. A human debugging a wrong discovery reads the\n * default output, where every section names the files it came from. The Agent\n * Skills read `--json`: they are markdown and cannot import TypeScript, so a\n * versioned JSON document on stdout is the only bridge available to them —\n * which is why `schemaVersion` is part of the payload rather than of the CLI.\n */\n\nexport interface PolicyCommandOptions {\n scope?: string;\n json?: boolean;\n}\n\n/** Group the provenance entries by kind, preserving discovery order. */\nfunction groupSources(sources: PolicySource[]): Map<PolicySource['kind'], PolicySource[]> {\n const grouped = new Map<PolicySource['kind'], PolicySource[]>();\n for (const source of sources) {\n const bucket = grouped.get(source.kind);\n if (bucket === undefined) {\n grouped.set(source.kind, [source]);\n } else {\n bucket.push(source);\n }\n }\n return grouped;\n}\n\nfunction describeSource(source: PolicySource): string {\n const where = source.path ?? source.origin;\n const detail = source.detail === null ? '' : ` — ${source.detail}`;\n return `${source.status === 'found' ? '' : `[${source.status}] `}${where}${detail}`;\n}\n\n/**\n * Human-readable rendering.\n *\n * Content is deliberately never printed: a resolved policy carries whole\n * `AGENTS.md` and template bodies, and dumping them would bury the one thing\n * this view is for — which file each value came from. `--json` is where the\n * content lives.\n */\nfunction render(policy: RepositoryPolicy): void {\n const lines: string[] = [];\n const push = (line = ''): void => {\n lines.push(line);\n };\n\n push(`Repository: ${policy.root}`);\n push(`Scope: ${policy.scope ?? '(root)'}`);\n if (!policy.enabled) {\n push();\n push('Policy discovery is disabled (policy.enabled = false).');\n console.log(lines.join('\\n'));\n return;\n }\n\n push();\n push('Issues');\n push(` templates: ${policy.issues.templates.length}`);\n for (const template of policy.issues.templates) {\n const labels = template.labels.length > 0 ? ` labels=[${template.labels.join(', ')}]` : '';\n const type = template.type === null ? '' : ` type=${template.type}`;\n push(` - ${template.path} (${template.format}, ${template.origin})${type}${labels}`);\n }\n push(` types: ${policy.issues.types.length > 0 ? policy.issues.types.join(', ') : '(none)'}`);\n push(` labels: ${policy.issues.labels.length}`);\n for (const label of policy.issues.labels) {\n push(` - ${label.name}${label.description === null ? '' : ` — ${label.description}`}`);\n }\n push(` titleConvention: ${policy.issues.titleConvention ?? '(none)'}`);\n\n push();\n push('Pull Requests');\n push(` template: ${policy.pullRequests.templates[0]?.path ?? '(none)'}`);\n for (const template of policy.pullRequests.templates.slice(1)) {\n push(` - ${template.path}`);\n }\n push(` baseBranch: ${policy.pullRequests.baseBranch ?? '(none)'}`);\n push(` titleConvention: ${policy.pullRequests.titleConvention ?? '(none)'}`);\n\n push();\n push('Git');\n push(` branchConvention: ${policy.git.branchConvention ?? '(none)'}`);\n push(` commitConvention: ${policy.git.commitConvention ?? '(none)'}`);\n\n push();\n push(`Documents: ${policy.docs.length}`);\n for (const doc of policy.docs) {\n const scope = doc.scope === '' ? 'root' : doc.scope;\n const from = doc.referencedFrom === null ? '' : ` ← ${doc.referencedFrom}`;\n push(` - ${doc.path} (${doc.kind}, scope=${scope})${from}`);\n }\n\n push();\n push(`CODEOWNERS: ${policy.codeowners === null ? '(none)' : 'found'}`);\n\n push();\n push('Sources');\n for (const [kind, entries] of groupSources(policy.sources)) {\n push(` ${kind}`);\n for (const entry of entries) {\n push(` - ${describeSource(entry)}`);\n }\n }\n\n console.log(lines.join('\\n'));\n}\n\n/**\n * Resolve and print the repository policy. Returns the process exit code.\n *\n * Only a repository that cannot be located at all is a failure: an empty policy\n * is a legitimate — and common — answer, printed like any other.\n */\nexport async function runPolicy(options: PolicyCommandOptions = {}): Promise<number> {\n let policy: RepositoryPolicy;\n try {\n policy = await loadRepositoryPolicy({ scope: options.scope ?? null });\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n return 1;\n }\n\n if (options.json === true) {\n console.log(JSON.stringify(policy, null, 2));\n return 0;\n }\n\n render(policy);\n\n const unavailable = policy.sources.filter((source) => source.status === 'unavailable');\n if (unavailable.length > 0) {\n console.log('');\n printWarning(\n `${unavailable.length} source(s) could not be consulted; the policy above is incomplete.`,\n );\n } else if (policy.sources.length === 0) {\n console.log('');\n printInfo('This repository declares no policy sources; Issue Flow defaults apply.');\n }\n\n return 0;\n}\n"],"mappings":"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","names":["sep","sep"]}
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ issueClosesLines,
4
+ multiIssueContext,
5
+ runPr
6
+ } from "./chunk-2LNQL4XH.js";
7
+ import "./chunk-UUY4PCWW.js";
8
+ import "./chunk-S67Q4I2O.js";
9
+ import "./chunk-HDV3YDTG.js";
10
+ import "./chunk-MXTGCD5C.js";
11
+ import "./chunk-PPLIXZI5.js";
12
+ import "./chunk-SLHZPB3C.js";
13
+ import "./chunk-VYFKOUUR.js";
14
+ import "./chunk-V5OHFSW4.js";
15
+ export {
16
+ issueClosesLines,
17
+ multiIssueContext,
18
+ runPr
19
+ };
20
+ //# sourceMappingURL=pr-V5H65MRW.js.map
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ exitCodeFor,
4
+ runPrReview
5
+ } from "./chunk-EWA3OGCM.js";
6
+ import "./chunk-VOKNTBOO.js";
7
+ import "./chunk-MXTGCD5C.js";
8
+ import "./chunk-PPLIXZI5.js";
9
+ import "./chunk-SLHZPB3C.js";
10
+ import "./chunk-VYFKOUUR.js";
11
+ import "./chunk-V5OHFSW4.js";
12
+ export {
13
+ exitCodeFor,
14
+ runPrReview
15
+ };
16
+ //# sourceMappingURL=pr-review-RCMXKXVP.js.map
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runPrd
4
+ } from "./chunk-UH4KAJBJ.js";
5
+ import "./chunk-UUY4PCWW.js";
6
+ import "./chunk-S67Q4I2O.js";
7
+ import "./chunk-HDV3YDTG.js";
8
+ import "./chunk-MXTGCD5C.js";
9
+ import "./chunk-PPLIXZI5.js";
10
+ import "./chunk-SLHZPB3C.js";
11
+ import "./chunk-VYFKOUUR.js";
12
+ import "./chunk-V5OHFSW4.js";
13
+ export {
14
+ runPrd
15
+ };
16
+ //# sourceMappingURL=prd-3XR5KYJS.js.map
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runReview
4
+ } from "./chunk-2Z7OEZZT.js";
5
+ import "./chunk-S67Q4I2O.js";
6
+ import "./chunk-MXTGCD5C.js";
7
+ import "./chunk-PPLIXZI5.js";
8
+ import "./chunk-SLHZPB3C.js";
9
+ import "./chunk-VYFKOUUR.js";
10
+ import "./chunk-V5OHFSW4.js";
11
+ export {
12
+ runReview
13
+ };
14
+ //# sourceMappingURL=review-ZZG3CSUO.js.map
@@ -1,50 +1,50 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runPrd
4
- } from "./chunk-WHEU55ZP.js";
4
+ } from "./chunk-UH4KAJBJ.js";
5
5
  import {
6
6
  runReview
7
- } from "./chunk-X7XBF5TS.js";
7
+ } from "./chunk-2Z7OEZZT.js";
8
8
  import {
9
9
  ensureWebMonitor
10
- } from "./chunk-VNKSMWDN.js";
10
+ } from "./chunk-652DJBCN.js";
11
11
  import {
12
12
  runInit
13
- } from "./chunk-M72ZEPWD.js";
13
+ } from "./chunk-EZMOEBLU.js";
14
14
  import {
15
15
  printQueueSummary,
16
16
  printRunSummary,
17
17
  runExecute
18
- } from "./chunk-DP43WJY4.js";
18
+ } from "./chunk-67ZO5ROQ.js";
19
19
  import {
20
20
  runPlan
21
- } from "./chunk-TJMZWRS6.js";
21
+ } from "./chunk-SP7DD4ID.js";
22
22
  import {
23
23
  runPr
24
- } from "./chunk-66ZGYXTH.js";
25
- import "./chunk-NB6WKTBL.js";
24
+ } from "./chunk-2LNQL4XH.js";
25
+ import "./chunk-UUY4PCWW.js";
26
26
  import {
27
27
  emptyRelations,
28
28
  getProvider,
29
29
  resolveCommandIssue,
30
30
  uniqueIds
31
- } from "./chunk-KXAG24DD.js";
31
+ } from "./chunk-S67Q4I2O.js";
32
32
  import "./chunk-HDV3YDTG.js";
33
33
  import {
34
34
  mostRecent,
35
35
  prReviewDir,
36
36
  readPrReviewIndex,
37
37
  runPrReview
38
- } from "./chunk-TLSIK656.js";
38
+ } from "./chunk-EWA3OGCM.js";
39
39
  import {
40
40
  listPullRequests,
41
41
  publishGitState
42
- } from "./chunk-M37YZYDO.js";
43
- import "./chunk-JGKPSWOA.js";
42
+ } from "./chunk-VOKNTBOO.js";
43
+ import "./chunk-MXTGCD5C.js";
44
44
  import {
45
45
  beginUsageScope,
46
46
  getRunUsageTotals
47
- } from "./chunk-DTNM3LTO.js";
47
+ } from "./chunk-PPLIXZI5.js";
48
48
  import "./chunk-SLHZPB3C.js";
49
49
  import {
50
50
  executionPlanSchema,
@@ -53,7 +53,7 @@ import {
53
53
  resolveIssuePaths,
54
54
  resolveProjectPaths,
55
55
  resolveQueuePaths
56
- } from "./chunk-MTJQOOMG.js";
56
+ } from "./chunk-VYFKOUUR.js";
57
57
  import {
58
58
  FilePublisher,
59
59
  NullPublisher,
@@ -70,7 +70,7 @@ import {
70
70
  setStoryStageCallback,
71
71
  setStoryUpdateCallback,
72
72
  writeFileAtomic
73
- } from "./chunk-57MH6RYJ.js";
73
+ } from "./chunk-V5OHFSW4.js";
74
74
 
75
75
  // src/commands/run.ts
76
76
  import { randomUUID } from "crypto";
@@ -1857,4 +1857,4 @@ export {
1857
1857
  publishStorySeed,
1858
1858
  runPipeline
1859
1859
  };
1860
- //# sourceMappingURL=run-BRBFHVUO.js.map
1860
+ //# sourceMappingURL=run-DIBC3YKX.js.map
@@ -4,20 +4,20 @@ import {
4
4
  getWebLockFile,
5
5
  readWebLock,
6
6
  removeWebLock
7
- } from "./chunk-VNKSMWDN.js";
7
+ } from "./chunk-652DJBCN.js";
8
8
  import "./chunk-SLHZPB3C.js";
9
9
  import {
10
10
  ISSUES_DIR_NAME,
11
11
  PROJECTS_DIR_NAME,
12
12
  getGlobalRoot,
13
13
  loadWebConfig
14
- } from "./chunk-MTJQOOMG.js";
14
+ } from "./chunk-VYFKOUUR.js";
15
15
  import {
16
16
  printError,
17
17
  printInfo,
18
18
  printWarning,
19
19
  sessionSnapshotSchema
20
- } from "./chunk-57MH6RYJ.js";
20
+ } from "./chunk-V5OHFSW4.js";
21
21
 
22
22
  // src/web/session-directory.ts
23
23
  import { readdir, readFile, stat as statFile } from "fs/promises";
@@ -185,4 +185,4 @@ export {
185
185
  runWebServe,
186
186
  runWebStop
187
187
  };
188
- //# sourceMappingURL=web-WQISLO66.js.map
188
+ //# sourceMappingURL=web-O2FVOYZW.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "issue-flow",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Unified CLI for orchestrating the full issue-flow pipeline via Claude Code Headless",
5
5
  "type": "module",
6
6
  "bin": {