gh-inari 0.10.2 → 0.11.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 (146) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +11 -0
  3. package/branch-naming-authority.d.mts +8 -0
  4. package/branch-naming-authority.mjs +28 -0
  5. package/dist/artifact-contract-governance.d.ts +44 -0
  6. package/dist/artifact-contract-governance.js +138 -0
  7. package/dist/artifact-contract-governance.js.map +1 -0
  8. package/dist/artifact.d.ts +23 -1
  9. package/dist/artifact.js +42 -7
  10. package/dist/artifact.js.map +1 -1
  11. package/dist/change/machine/abort-execution-machine.d.ts +105 -0
  12. package/dist/change/machine/abort-execution-machine.js +391 -0
  13. package/dist/change/machine/abort-execution-machine.js.map +1 -0
  14. package/dist/change/machine/issuance-execution-machine.d.ts +125 -0
  15. package/dist/change/machine/issuance-execution-machine.js +576 -0
  16. package/dist/change/machine/issuance-execution-machine.js.map +1 -0
  17. package/dist/change/machine/lifecycle-machine.d.ts +28 -0
  18. package/dist/change/machine/lifecycle-machine.js +157 -0
  19. package/dist/change/machine/lifecycle-machine.js.map +1 -0
  20. package/dist/change/machine/ready-execution-machine.d.ts +69 -0
  21. package/dist/change/machine/ready-execution-machine.js +404 -0
  22. package/dist/change/machine/ready-execution-machine.js.map +1 -0
  23. package/dist/change-executor.d.ts +90 -0
  24. package/dist/change-executor.js +250 -0
  25. package/dist/change-executor.js.map +1 -0
  26. package/dist/change-failure-diagnostics.d.ts +10 -0
  27. package/dist/change-failure-diagnostics.js +59 -0
  28. package/dist/change-failure-diagnostics.js.map +1 -0
  29. package/dist/change-trusted-executor.d.ts +59 -0
  30. package/dist/change-trusted-executor.js +760 -0
  31. package/dist/change-trusted-executor.js.map +1 -0
  32. package/dist/change.d.ts +883 -0
  33. package/dist/change.js +4909 -0
  34. package/dist/change.js.map +1 -0
  35. package/dist/cli-core.d.ts +10 -0
  36. package/dist/cli-core.js +598 -8
  37. package/dist/cli-core.js.map +1 -1
  38. package/dist/command-contract.d.ts +7 -6
  39. package/dist/command-contract.js +36 -4
  40. package/dist/command-contract.js.map +1 -1
  41. package/dist/contract/artifact-contract.d.ts +193 -0
  42. package/dist/contract/artifact-contract.js +951 -0
  43. package/dist/contract/artifact-contract.js.map +1 -0
  44. package/dist/contract/effective-artifact-contract.d.ts +47 -0
  45. package/dist/contract/effective-artifact-contract.js +251 -0
  46. package/dist/contract/effective-artifact-contract.js.map +1 -0
  47. package/dist/contract/index.d.ts +4 -0
  48. package/dist/contract/index.js +4 -0
  49. package/dist/contract/index.js.map +1 -1
  50. package/dist/contract/ir.d.ts +30 -0
  51. package/dist/contract/ir.js +31 -1
  52. package/dist/contract/ir.js.map +1 -1
  53. package/dist/contract/native-template-projection.d.ts +60 -0
  54. package/dist/contract/native-template-projection.js +295 -0
  55. package/dist/contract/native-template-projection.js.map +1 -0
  56. package/dist/contract/schema.d.ts +3 -1
  57. package/dist/contract/schema.js.map +1 -1
  58. package/dist/contract/semantic-artifact.d.ts +53 -0
  59. package/dist/contract/semantic-artifact.js +649 -0
  60. package/dist/contract/semantic-artifact.js.map +1 -0
  61. package/dist/github/actions-change-executor.d.ts +144 -0
  62. package/dist/github/actions-change-executor.js +1367 -0
  63. package/dist/github/actions-change-executor.js.map +1 -0
  64. package/dist/github/adapter.d.ts +34 -1
  65. package/dist/github/adapter.js +398 -2
  66. package/dist/github/adapter.js.map +1 -1
  67. package/dist/github/capability.d.ts +7 -1
  68. package/dist/github/capability.js +52 -0
  69. package/dist/github/capability.js.map +1 -1
  70. package/dist/github/change-actions-remote-executor.d.ts +43 -0
  71. package/dist/github/change-actions-remote-executor.js +532 -0
  72. package/dist/github/change-actions-remote-executor.js.map +1 -0
  73. package/dist/github/change-effect-adapter.d.ts +108 -0
  74. package/dist/github/change-effect-adapter.js +386 -0
  75. package/dist/github/change-effect-adapter.js.map +1 -0
  76. package/dist/github/index.d.ts +5 -0
  77. package/dist/github/index.js +5 -0
  78. package/dist/github/index.js.map +1 -1
  79. package/dist/github/issue-relation-observation-adapter.d.ts +88 -0
  80. package/dist/github/issue-relation-observation-adapter.js +264 -0
  81. package/dist/github/issue-relation-observation-adapter.js.map +1 -0
  82. package/dist/github/issuer-authority.d.ts +197 -0
  83. package/dist/github/issuer-authority.js +779 -0
  84. package/dist/github/issuer-authority.js.map +1 -0
  85. package/dist/github/types.d.ts +58 -1
  86. package/dist/governance.d.ts +39 -2
  87. package/dist/governance.js +86 -4
  88. package/dist/governance.js.map +1 -1
  89. package/dist/index.d.ts +15 -0
  90. package/dist/index.js +15 -0
  91. package/dist/index.js.map +1 -1
  92. package/dist/issuer-identity.d.ts +12 -0
  93. package/dist/issuer-identity.js +14 -0
  94. package/dist/issuer-identity.js.map +1 -0
  95. package/dist/legacy-artifact-convergence.d.ts +77 -0
  96. package/dist/legacy-artifact-convergence.js +515 -0
  97. package/dist/legacy-artifact-convergence.js.map +1 -0
  98. package/dist/mcp/index.d.ts +2 -0
  99. package/dist/mcp/index.js +3 -0
  100. package/dist/mcp/index.js.map +1 -0
  101. package/dist/mcp/server.d.ts +18 -0
  102. package/dist/mcp/server.js +25 -0
  103. package/dist/mcp/server.js.map +1 -0
  104. package/dist/mcp/stdio.d.ts +13 -0
  105. package/dist/mcp/stdio.js +109 -0
  106. package/dist/mcp/stdio.js.map +1 -0
  107. package/dist/mcp/tools.d.ts +293 -0
  108. package/dist/mcp/tools.js +772 -0
  109. package/dist/mcp/tools.js.map +1 -0
  110. package/dist/semantic-branch-executor.d.ts +82 -0
  111. package/dist/semantic-branch-executor.js +281 -0
  112. package/dist/semantic-branch-executor.js.map +1 -0
  113. package/dist/semantic-branch-observation.d.ts +90 -0
  114. package/dist/semantic-branch-observation.js +278 -0
  115. package/dist/semantic-branch-observation.js.map +1 -0
  116. package/dist/semantic-branch-projection.d.ts +103 -0
  117. package/dist/semantic-branch-projection.js +528 -0
  118. package/dist/semantic-branch-projection.js.map +1 -0
  119. package/dist/semantic-issue-executor.d.ts +97 -0
  120. package/dist/semantic-issue-executor.js +311 -0
  121. package/dist/semantic-issue-executor.js.map +1 -0
  122. package/dist/semantic-issue-lifecycle.d.ts +118 -0
  123. package/dist/semantic-issue-lifecycle.js +498 -0
  124. package/dist/semantic-issue-lifecycle.js.map +1 -0
  125. package/dist/semantic-issue-observation.d.ts +145 -0
  126. package/dist/semantic-issue-observation.js +960 -0
  127. package/dist/semantic-issue-observation.js.map +1 -0
  128. package/dist/semantic-issue-projection.d.ts +155 -0
  129. package/dist/semantic-issue-projection.js +838 -0
  130. package/dist/semantic-issue-projection.js.map +1 -0
  131. package/dist/semantic-pr-executor.d.ts +103 -0
  132. package/dist/semantic-pr-executor.js +340 -0
  133. package/dist/semantic-pr-executor.js.map +1 -0
  134. package/dist/semantic-pr-observation.d.ts +153 -0
  135. package/dist/semantic-pr-observation.js +1214 -0
  136. package/dist/semantic-pr-observation.js.map +1 -0
  137. package/dist/semantic-pr-projection.d.ts +146 -0
  138. package/dist/semantic-pr-projection.js +857 -0
  139. package/dist/semantic-pr-projection.js.map +1 -0
  140. package/dist/semantic-template.js +31 -4
  141. package/dist/semantic-template.js.map +1 -1
  142. package/dist/skill.d.ts +1 -1
  143. package/dist/skill.js +21 -1
  144. package/dist/skill.js.map +1 -1
  145. package/package.json +56 -3
  146. package/skills/inari/SKILL.md +4 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inari",
3
- "version": "0.10.2",
3
+ "version": "0.11.0",
4
4
  "description": "Governed GitHub Issue/PR/template workflows via the inari CLI. Prefer inari over raw gh for operations it owns; use inari skill for operational playbooks.",
5
5
  "skills": "skills/inari"
6
6
  }
package/README.md CHANGED
@@ -174,6 +174,10 @@ inari issue normalize <number> [--dry-run]
174
174
  inari pr normalize <number> [--dry-run]
175
175
  inari issue sync <number> --from desired.json [--dry-run]
176
176
  inari pr sync <number> --from desired.json [--dry-run]
177
+ inari change issue <number> [--repository <owner/name>] --json
178
+ inari change show <number> [--repository <owner/name>] --json
179
+ inari change ready <number> [--repository <owner/name>] --json
180
+ inari change abort <number> [--repository <owner/name>] --json
177
181
  ```
178
182
 
179
183
  `--from -` reads JSON from stdin. Create input uses an envelope when mutation metadata is needed:
@@ -195,6 +199,13 @@ and a valid `syncInput.minimalExample`.
195
199
  `issue sync --from` overlays supplied semantic fields and metadata onto the
196
200
  current artifact, preserving values omitted from the input.
197
201
 
202
+ Change commands use the semantic Change contract and return bounded JSON
203
+ projections. Mutation commands request a configured remote executor; workflow
204
+ names, dispatch inputs, Actions jobs, and privileged App credentials are not
205
+ CLI inputs. `change show` is read-only. Existing Issue/PR artifact-level
206
+ commands remain available as explicit migration-compatible direct mutation
207
+ paths while the Change workflow is rolled out.
208
+
198
209
  Schema and validation output is JSON. `--json` makes render and create output JSON as well. Validation failures return exit status `2`; usage errors return `1`; GitHub/transport failures return `3`. Error objects contain stable `code`, `path` where applicable, and ordered `violations`.
199
210
 
200
211
  `issue get` and `pr get` are canonical-only v1 reads. They resolve the target
@@ -0,0 +1,8 @@
1
+ export interface BranchNameParts {
2
+ readonly type: string;
3
+ readonly issueNumber: number;
4
+ readonly slug: string;
5
+ }
6
+
7
+ export function validateBranchName(branch: string): readonly string[];
8
+ export function deriveBranchName(parts: BranchNameParts): string;
@@ -0,0 +1,28 @@
1
+ // Shared executable authority for repository branch naming.
2
+ // Consumers validate or assemble names through this module instead of
3
+ // reimplementing the repository's branch grammar.
4
+
5
+ const BRANCH_PATTERN = /^(feat|fix|docs|refactor|test|chore)\/\d+-[a-z0-9-]+$/;
6
+ const EXEMPT_BRANCHES = new Set(["main"]);
7
+
8
+ export function validateBranchName(branch) {
9
+ if (EXEMPT_BRANCHES.has(branch)) return [];
10
+ if (BRANCH_PATTERN.test(branch)) return [];
11
+ return [
12
+ `branch name "${branch}" does not match <type>/<issue-number>-<slug>` +
13
+ ' (e.g. "feat/42-add-init-command"); type must be one of feat, fix, docs, refactor, test, chore',
14
+ ];
15
+ }
16
+
17
+ export function deriveBranchName({ type, issueNumber, slug }) {
18
+ if (typeof type !== "string" || type.length === 0) throw new TypeError("Branch type must be a non-empty string.");
19
+ if (!Number.isSafeInteger(issueNumber) || issueNumber < 1) {
20
+ throw new TypeError("Branch issue number must be a positive safe integer.");
21
+ }
22
+ if (typeof slug !== "string" || slug.length === 0) throw new TypeError("Branch slug must be a non-empty string.");
23
+
24
+ const branch = `${type}/${issueNumber}-${slug}`;
25
+ const errors = validateBranchName(branch);
26
+ if (errors.length > 0) throw new TypeError(errors[0]);
27
+ return branch;
28
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Repository Canon resolution for the Semantic Artifact pipeline.
3
+ *
4
+ * This module is the repository-facing Core adapter boundary. It resolves an
5
+ * Artifact Contract Canon from the authoritative default branch and compiles
6
+ * it through the shared Effective Artifact Contract compiler. It
7
+ * does not select semantic values, derive identities, or project GitHub
8
+ * representations, and it does not define its own Canon location or
9
+ * selector policy: discovery and template-resolution precedence are
10
+ * delegated to the same repository governance authority every other
11
+ * governed artifact uses (`governance.ts`, `template-resolver.ts`).
12
+ */
13
+ import { type EffectiveArtifactContract } from "./contract/index.js";
14
+ import { GitHubAdapter } from "./github/index.js";
15
+ export type RepositoryEffectiveArtifactKind = "issue" | "branch" | "pull_request";
16
+ export type ArtifactContractResolutionErrorCode = "ARTIFACT_CONTRACT_NOT_FOUND" | "ARTIFACT_CONTRACT_SELECTOR_AMBIGUOUS" | "ARTIFACT_CONTRACT_SOURCE_INVALID" | "ARTIFACT_CONTRACT_KIND_INVALID";
17
+ export interface ArtifactContractResolutionDiagnostic {
18
+ readonly code: ArtifactContractResolutionErrorCode;
19
+ readonly path: string;
20
+ readonly message: string;
21
+ }
22
+ /** Stable machine-readable failure for repository Canon resolution. */
23
+ export declare class ArtifactContractResolutionError extends Error {
24
+ readonly code: ArtifactContractResolutionErrorCode;
25
+ readonly path: string;
26
+ readonly diagnostics: readonly unknown[];
27
+ readonly details?: Readonly<Record<string, unknown>>;
28
+ constructor(code: ArtifactContractResolutionErrorCode, path: string, message: string, details?: Readonly<Record<string, unknown>>, diagnostics?: readonly unknown[]);
29
+ }
30
+ export interface RepositoryEffectiveArtifactContractOptions {
31
+ readonly capabilities?: readonly string[];
32
+ }
33
+ /**
34
+ * Resolve the authoritative Artifact Contract Canon and compile its Effective
35
+ * Artifact Contract. All repository identity and generation fields come from
36
+ * the adapter's default-branch/tree/blob reads.
37
+ */
38
+ export declare function compileRepositoryEffectiveArtifactContract(adapter: GitHubAdapter, kind: RepositoryEffectiveArtifactKind, selector?: string, options?: RepositoryEffectiveArtifactContractOptions): Promise<EffectiveArtifactContract>;
39
+ /** Resolve and compile a pull-request Artifact Contract from the repository Canon. */
40
+ export declare function compileRepositoryEffectivePullRequestContract(adapter: GitHubAdapter, selector?: string, options?: RepositoryEffectiveArtifactContractOptions): Promise<EffectiveArtifactContract>;
41
+ /** Resolve and compile an Issue Artifact Contract from the repository Canon. */
42
+ export declare function compileRepositoryEffectiveIssueContract(adapter: GitHubAdapter, selector?: string, options?: RepositoryEffectiveArtifactContractOptions): Promise<EffectiveArtifactContract>;
43
+ /** Resolve and compile a Branch Artifact Contract from the repository Canon. */
44
+ export declare function compileRepositoryEffectiveBranchContract(adapter: GitHubAdapter, selector?: string, options?: RepositoryEffectiveArtifactContractOptions): Promise<EffectiveArtifactContract>;
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Repository Canon resolution for the Semantic Artifact pipeline.
3
+ *
4
+ * This module is the repository-facing Core adapter boundary. It resolves an
5
+ * Artifact Contract Canon from the authoritative default branch and compiles
6
+ * it through the shared Effective Artifact Contract compiler. It
7
+ * does not select semantic values, derive identities, or project GitHub
8
+ * representations, and it does not define its own Canon location or
9
+ * selector policy: discovery and template-resolution precedence are
10
+ * delegated to the same repository governance authority every other
11
+ * governed artifact uses (`governance.ts`, `template-resolver.ts`).
12
+ */
13
+ import { createHash } from "node:crypto";
14
+ import { ArtifactContractValidationError, parseArtifactContract, compileEffectiveArtifactContract, } from "./contract/index.js";
15
+ import { resolveRemoteArtifactContractIdentity } from "./governance.js";
16
+ import { TemplateResolutionError } from "./template-resolver.js";
17
+ /** Stable machine-readable failure for repository Canon resolution. */
18
+ export class ArtifactContractResolutionError extends Error {
19
+ code;
20
+ path;
21
+ diagnostics;
22
+ details;
23
+ constructor(code, path, message, details, diagnostics = [{ code, path, message }]) {
24
+ super(message);
25
+ this.name = "ArtifactContractResolutionError";
26
+ this.code = code;
27
+ this.path = path;
28
+ this.diagnostics = Object.freeze([...diagnostics]);
29
+ this.details = details;
30
+ }
31
+ }
32
+ /**
33
+ * Resolve the authoritative Artifact Contract Canon identity using the same
34
+ * repository governance discovery and template-resolution precedence as every
35
+ * other governed artifact. This module does not read arbitrary repository
36
+ * files.
37
+ */
38
+ async function selectCanonIdentity(tree, kind, selector, context, ref) {
39
+ try {
40
+ return await resolveRemoteArtifactContractIdentity(tree, kind, selector);
41
+ }
42
+ catch (error) {
43
+ if (!(error instanceof TemplateResolutionError))
44
+ throw error;
45
+ throw artifactContractResolutionErrorFromTemplateResolution(error, context, ref);
46
+ }
47
+ }
48
+ function artifactContractResolutionErrorFromTemplateResolution(error, context, ref) {
49
+ const details = { repository: context.nameWithOwner, ref, ...error.details };
50
+ switch (error.code) {
51
+ case "TEMPLATE_RESOLUTION_SELECTOR_AMBIGUOUS":
52
+ case "TEMPLATE_RESOLUTION_DEFAULT_AMBIGUOUS":
53
+ case "TEMPLATE_RESOLUTION_AMBIGUOUS":
54
+ return new ArtifactContractResolutionError("ARTIFACT_CONTRACT_SELECTOR_AMBIGUOUS", "$.selector", error.message, details);
55
+ default:
56
+ return new ArtifactContractResolutionError("ARTIFACT_CONTRACT_NOT_FOUND", "$.selector", error.message, details);
57
+ }
58
+ }
59
+ function findCanonEntry(tree, identity, context, ref) {
60
+ const entry = tree.find((candidate) => candidate.path === identity.sourcePath && candidate.type === "blob");
61
+ if (entry === undefined) {
62
+ throw new ArtifactContractResolutionError("ARTIFACT_CONTRACT_NOT_FOUND", "$.source", `Artifact Contract Canon "${identity.sourcePath}" was not found for ${context.nameWithOwner} at ref "${ref}".`, { repository: context.nameWithOwner, ref, path: identity.sourcePath });
63
+ }
64
+ return entry;
65
+ }
66
+ function sourceProvenance(context, ref, treeSha, entry, source) {
67
+ return {
68
+ authority: "repository-default-branch",
69
+ repository: {
70
+ host: context.hostname,
71
+ owner: context.owner,
72
+ name: context.name,
73
+ nameWithOwner: context.nameWithOwner,
74
+ ...(context.repositoryId === undefined ? {} : { repositoryId: context.repositoryId }),
75
+ },
76
+ ref,
77
+ treeSha,
78
+ source: {
79
+ path: entry.path,
80
+ ref,
81
+ sha: entry.sha,
82
+ digest: createHash("sha256").update(source, "utf8").digest("hex"),
83
+ },
84
+ };
85
+ }
86
+ function parseCanonSource(source, path, kind) {
87
+ let raw;
88
+ try {
89
+ raw = JSON.parse(source);
90
+ }
91
+ catch (error) {
92
+ throw new ArtifactContractResolutionError("ARTIFACT_CONTRACT_SOURCE_INVALID", path, `Artifact Contract Canon "${path}" is not valid JSON.`, { reason: error instanceof Error ? error.message : "invalid JSON" });
93
+ }
94
+ try {
95
+ const contract = parseArtifactContract(raw);
96
+ if (contract.kind !== kind) {
97
+ throw new ArtifactContractResolutionError("ARTIFACT_CONTRACT_KIND_INVALID", "$.kind", `Artifact Contract Canon "${path}" must declare kind "${kind}".`, { kind: contract.kind });
98
+ }
99
+ return contract;
100
+ }
101
+ catch (error) {
102
+ if (error instanceof ArtifactContractResolutionError)
103
+ throw error;
104
+ if (error instanceof ArtifactContractValidationError) {
105
+ throw new ArtifactContractResolutionError("ARTIFACT_CONTRACT_SOURCE_INVALID", path, `Artifact Contract Canon "${path}" failed Core validation.`, { violations: error.violations }, error.violations);
106
+ }
107
+ throw new ArtifactContractResolutionError("ARTIFACT_CONTRACT_SOURCE_INVALID", path, `Artifact Contract Canon "${path}" failed Core validation.`, { reason: error instanceof Error ? error.message : "invalid contract" });
108
+ }
109
+ }
110
+ /**
111
+ * Resolve the authoritative Artifact Contract Canon and compile its Effective
112
+ * Artifact Contract. All repository identity and generation fields come from
113
+ * the adapter's default-branch/tree/blob reads.
114
+ */
115
+ export async function compileRepositoryEffectiveArtifactContract(adapter, kind, selector, options = {}) {
116
+ const context = await adapter.resolveRepositoryContext();
117
+ const ref = await adapter.getRepositoryDefaultBranch();
118
+ const tree = await adapter.getRepositoryTree(ref);
119
+ const identity = await selectCanonIdentity(tree.entries, kind, selector, context, ref);
120
+ const entry = findCanonEntry(tree.entries, identity, context, ref);
121
+ const source = await adapter.getRepositoryBlob(entry.sha);
122
+ const contract = parseCanonSource(source, entry.path, kind);
123
+ const provenance = sourceProvenance(context, ref, tree.sha, entry, source);
124
+ return compileEffectiveArtifactContract(contract, { provenance, capabilities: options.capabilities });
125
+ }
126
+ /** Resolve and compile a pull-request Artifact Contract from the repository Canon. */
127
+ export async function compileRepositoryEffectivePullRequestContract(adapter, selector, options = {}) {
128
+ return compileRepositoryEffectiveArtifactContract(adapter, "pull_request", selector, options);
129
+ }
130
+ /** Resolve and compile an Issue Artifact Contract from the repository Canon. */
131
+ export async function compileRepositoryEffectiveIssueContract(adapter, selector, options = {}) {
132
+ return compileRepositoryEffectiveArtifactContract(adapter, "issue", selector, options);
133
+ }
134
+ /** Resolve and compile a Branch Artifact Contract from the repository Canon. */
135
+ export async function compileRepositoryEffectiveBranchContract(adapter, selector, options = {}) {
136
+ return compileRepositoryEffectiveArtifactContract(adapter, "branch", selector, options);
137
+ }
138
+ //# sourceMappingURL=artifact-contract-governance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-contract-governance.js","sourceRoot":"","sources":["../src/artifact-contract-governance.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ import { type ArtifactDiagnostic, type ArtifactDiagnosticReport } from "./diagno
3
3
  import { type ArtifactKind, type CanonicalContract } from "./contract/ir.js";
4
4
  import { type IssueDependencies, type IssueReference } from "./contract/issue-reference.js";
5
5
  import { type ValidatedRenderedIssueArtifact, type ValidatedRenderedPullRequestArtifact } from "./github/types.js";
6
+ export { artifactContractFromLegacyCanonical, compileLegacyEffectiveArtifactContract, convergeLegacyArtifactInput, mapLegacyArtifactCandidate, materializeLegacyArtifact, tryMaterializeLegacyArtifact, validateLegacyBranchProjection, } from "./legacy-artifact-convergence.js";
7
+ export type { LegacyArtifactCompatibilitySource, LegacyArtifactConvergenceCode, LegacyArtifactConvergenceDiagnostic, LegacyArtifactConvergenceOptions, LegacyArtifactConvergenceResult, LegacyLinkedIssueRepository, LegacySemanticArtifactMaterializationResult, } from "./legacy-artifact-convergence.js";
6
8
  export interface ArtifactInputMetadata {
7
9
  readonly title?: string;
8
10
  readonly labels?: readonly string[];
@@ -163,6 +165,8 @@ export interface IssueDependencyMarkerExtraction {
163
165
  /** Body with a recognized trailing dependency marker removed. */
164
166
  readonly body: string;
165
167
  }
168
+ /** Render the bounded compatibility marker used for Issue dependency projections. */
169
+ export declare function renderIssueDependencyMarker(dependencies: IssueDependencies): string;
166
170
  /**
167
171
  * Read only the reserved trailing dependency marker emitted by Inari. No
168
172
  * ordinary Markdown is interpreted as a relationship declaration.
@@ -266,6 +270,24 @@ export declare function validateExistingIssueFromAdapter(reader: ExistingIssueRe
266
270
  export declare function validateExistingPullRequestFromAdapter(reader: ExistingPullRequestReader, contract: unknown, pullRequestNumber: number): Promise<FetchedExistingArtifact>;
267
271
  /** @internal Validate the canonical Issue metadata handoff before mutation. */
268
272
  export declare function verifyIssueMetadataRoundTrip(expected: Readonly<Record<string, unknown>>, artifact: ValidatedRenderedIssueArtifact): void;
269
- /** Escape only Markdown constructs that could change the canonical section structure. */
273
+ /**
274
+ * Escape only Markdown constructs that can change the compiled canonical
275
+ * structure when a field value is spliced verbatim into a rendered body:
276
+ *
277
+ * - a heading line would be mistaken for the next section boundary
278
+ * (`isHeading` / `headingBlocks` scan headings only to find where a
279
+ * field's content ends);
280
+ * - a fence marker would shift the fence-tracking state those same scans use
281
+ * to skip over heading-look-alikes inside embedded code;
282
+ * - a line matching the reserved `<!-- inari:... -->` marker prefix could be
283
+ * read back as the trailing template-identity/dependency marker.
284
+ *
285
+ * Task-list (`- [ ]`) and blockquote (`>`) prefixes are not used by any
286
+ * section/field boundary detection in this file, so they are left as
287
+ * intentional Markdown rather than escaped merely because they resemble a
288
+ * construct (see #275). Checklist item labels get their own additional
289
+ * escape in `escapeChecklistLabel` because those *are* line-delimited by a
290
+ * task-list prefix during parsing.
291
+ */
270
292
  export declare function escapeMarkdownValue(value: string): string;
271
293
  export declare function removeHtmlComments(value: string): string;
package/dist/artifact.js CHANGED
@@ -3,6 +3,10 @@ import { createArtifactDiagnostic, createArtifactDiagnosticReport, createFieldEv
3
3
  import { assertCanonicalContract, } from "./contract/ir.js";
4
4
  import { EMPTY_ISSUE_DEPENDENCIES, validateIssueDependencies, } from "./contract/issue-reference.js";
5
5
  import { createValidatedRenderedIssueArtifact, createValidatedRenderedPullRequestArtifact, } from "./github/capability.js";
6
+ // v1 artifact APIs remain available during migration. Their explicit
7
+ // convergence adapter is re-exported here so callers do not need a second
8
+ // legacy-specific package entrypoint.
9
+ export { artifactContractFromLegacyCanonical, compileLegacyEffectiveArtifactContract, convergeLegacyArtifactInput, mapLegacyArtifactCandidate, materializeLegacyArtifact, tryMaterializeLegacyArtifact, validateLegacyBranchProjection, } from "./legacy-artifact-convergence.js";
6
10
  export class ArtifactInputError extends Error {
7
11
  code;
8
12
  path;
@@ -55,7 +59,8 @@ function renderTemplateIdentityMarker(contract) {
55
59
  };
56
60
  return `${TEMPLATE_IDENTITY_MARKER_PREFIX}${JSON.stringify(marker)}${TEMPLATE_IDENTITY_MARKER_SUFFIX}`;
57
61
  }
58
- function renderIssueDependencyMarker(dependencies) {
62
+ /** Render the bounded compatibility marker used for Issue dependency projections. */
63
+ export function renderIssueDependencyMarker(dependencies) {
59
64
  return `${ISSUE_DEPENDENCY_MARKER_PREFIX}${JSON.stringify({
60
65
  version: ISSUE_DEPENDENCY_MARKER_VERSION,
61
66
  dependencies,
@@ -1048,7 +1053,7 @@ function renderFieldValue(field, value, kind) {
1048
1053
  }
1049
1054
  const selected = new Set(Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : []);
1050
1055
  const placeholder = kind === "pull_request" ? field.nativeMetadata.placeholder : undefined;
1051
- const lines = field.items.map((item) => `- [${selected.has(item.id) ? "x" : " "}] ${escapeMarkdownValue(item.label)}`);
1056
+ const lines = field.items.map((item) => `- [${selected.has(item.id) ? "x" : " "}] ${escapeChecklistLabel(item.label)}`);
1052
1057
  return [placeholder === undefined ? "" : placeholder, lines.join("\n")].filter(Boolean).join("\n\n");
1053
1058
  }
1054
1059
  /** Map canonical Issue semantic values to the labels shown by GitHub Issue Forms. */
@@ -1410,25 +1415,55 @@ function stringArray(value, key) {
1410
1415
  function escapeHeading(value) {
1411
1416
  return value.replace(/[\r\n]+/gu, " ").trim();
1412
1417
  }
1413
- /** Escape only Markdown constructs that could change the canonical section structure. */
1418
+ /**
1419
+ * Escape only Markdown constructs that can change the compiled canonical
1420
+ * structure when a field value is spliced verbatim into a rendered body:
1421
+ *
1422
+ * - a heading line would be mistaken for the next section boundary
1423
+ * (`isHeading` / `headingBlocks` scan headings only to find where a
1424
+ * field's content ends);
1425
+ * - a fence marker would shift the fence-tracking state those same scans use
1426
+ * to skip over heading-look-alikes inside embedded code;
1427
+ * - a line matching the reserved `<!-- inari:... -->` marker prefix could be
1428
+ * read back as the trailing template-identity/dependency marker.
1429
+ *
1430
+ * Task-list (`- [ ]`) and blockquote (`>`) prefixes are not used by any
1431
+ * section/field boundary detection in this file, so they are left as
1432
+ * intentional Markdown rather than escaped merely because they resemble a
1433
+ * construct (see #275). Checklist item labels get their own additional
1434
+ * escape in `escapeChecklistLabel` because those *are* line-delimited by a
1435
+ * task-list prefix during parsing.
1436
+ */
1414
1437
  export function escapeMarkdownValue(value) {
1415
1438
  return normalizeSource(value)
1416
1439
  .split("\n")
1417
1440
  .map((line) => {
1418
1441
  if (/^ {0,3}(?:#{1,6})(?:[ \t]+|$)/u.test(line))
1419
1442
  return line.replace(/^( {0,3})(#)/u, "$1\\$2");
1420
- if (/^ {0,3}(?:[-+*]|\d+[.)])[ \t]+\[[ xX]\]/u.test(line))
1421
- return line.replace(/^( {0,3})([-+*]|\d+[.)])/u, "$1\\$2");
1422
1443
  if (/^ {0,3}(?:```|~~~)/u.test(line))
1423
1444
  return line.replace(/^([ \t]{0,3})([`~])/u, "$1\\$2");
1424
- if (/^ {0,3}>[ \t]?/u.test(line))
1425
- return line.replace(/^( {0,3})(>)/u, "$1\\$2");
1426
1445
  if (/^ {0,3}<!--/u.test(line))
1427
1446
  return line.replace(/^( {0,3})(<!--)/u, "$1\\$2");
1428
1447
  return line;
1429
1448
  })
1430
1449
  .join("\n");
1431
1450
  }
1451
+ /**
1452
+ * Checklist item labels are rendered one-per-line under a shared `- [ ] `/
1453
+ * `- [x] ` prefix, and parsing re-splits that same block back into items by
1454
+ * matching the task-list prefix on each line. An embedded, unescaped
1455
+ * task-list-look-alike line inside a label would therefore be read back as a
1456
+ * separate checklist entry, so (unlike free-form string/array fields) the
1457
+ * task-list prefix is structural here and must stay escaped.
1458
+ */
1459
+ function escapeChecklistLabel(value) {
1460
+ return escapeMarkdownValue(value)
1461
+ .split("\n")
1462
+ .map((line) => /^ {0,3}(?:[-+*]|\d+[.)])[ \t]+\[[ xX]\]/u.test(line)
1463
+ ? line.replace(/^( {0,3})([-+*]|\d+[.)])/u, "$1\\$2")
1464
+ : line)
1465
+ .join("\n");
1466
+ }
1432
1467
  function unescapeMarkdownValue(value) {
1433
1468
  return normalizeSource(value)
1434
1469
  .split("\n")