gh-inari 0.9.0 → 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.
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +31 -2
- package/branch-naming-authority.d.mts +8 -0
- package/branch-naming-authority.mjs +28 -0
- package/dist/artifact-contract-governance.d.ts +44 -0
- package/dist/artifact-contract-governance.js +138 -0
- package/dist/artifact-contract-governance.js.map +1 -0
- package/dist/artifact.d.ts +23 -1
- package/dist/artifact.js +42 -7
- package/dist/artifact.js.map +1 -1
- package/dist/change/machine/abort-execution-machine.d.ts +105 -0
- package/dist/change/machine/abort-execution-machine.js +391 -0
- package/dist/change/machine/abort-execution-machine.js.map +1 -0
- package/dist/change/machine/issuance-execution-machine.d.ts +125 -0
- package/dist/change/machine/issuance-execution-machine.js +576 -0
- package/dist/change/machine/issuance-execution-machine.js.map +1 -0
- package/dist/change/machine/lifecycle-machine.d.ts +28 -0
- package/dist/change/machine/lifecycle-machine.js +157 -0
- package/dist/change/machine/lifecycle-machine.js.map +1 -0
- package/dist/change/machine/ready-execution-machine.d.ts +69 -0
- package/dist/change/machine/ready-execution-machine.js +404 -0
- package/dist/change/machine/ready-execution-machine.js.map +1 -0
- package/dist/change-executor.d.ts +90 -0
- package/dist/change-executor.js +250 -0
- package/dist/change-executor.js.map +1 -0
- package/dist/change-failure-diagnostics.d.ts +10 -0
- package/dist/change-failure-diagnostics.js +59 -0
- package/dist/change-failure-diagnostics.js.map +1 -0
- package/dist/change-trusted-executor.d.ts +59 -0
- package/dist/change-trusted-executor.js +760 -0
- package/dist/change-trusted-executor.js.map +1 -0
- package/dist/change.d.ts +883 -0
- package/dist/change.js +4909 -0
- package/dist/change.js.map +1 -0
- package/dist/cli-core.d.ts +34 -0
- package/dist/cli-core.js +2053 -0
- package/dist/cli-core.js.map +1 -0
- package/dist/cli.d.ts +9 -13
- package/dist/cli.js +122 -1536
- package/dist/cli.js.map +1 -1
- package/dist/command-contract.d.ts +129 -0
- package/dist/command-contract.js +375 -0
- package/dist/command-contract.js.map +1 -0
- package/dist/contract/artifact-contract.d.ts +193 -0
- package/dist/contract/artifact-contract.js +951 -0
- package/dist/contract/artifact-contract.js.map +1 -0
- package/dist/contract/effective-artifact-contract.d.ts +47 -0
- package/dist/contract/effective-artifact-contract.js +251 -0
- package/dist/contract/effective-artifact-contract.js.map +1 -0
- package/dist/contract/index.d.ts +4 -0
- package/dist/contract/index.js +4 -0
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/ir.d.ts +32 -0
- package/dist/contract/ir.js +37 -1
- package/dist/contract/ir.js.map +1 -1
- package/dist/contract/native-template-projection.d.ts +60 -0
- package/dist/contract/native-template-projection.js +295 -0
- package/dist/contract/native-template-projection.js.map +1 -0
- package/dist/contract/schema.d.ts +3 -1
- package/dist/contract/schema.js.map +1 -1
- package/dist/contract/semantic-artifact.d.ts +53 -0
- package/dist/contract/semantic-artifact.js +649 -0
- package/dist/contract/semantic-artifact.js.map +1 -0
- package/dist/github/actions-change-executor.d.ts +144 -0
- package/dist/github/actions-change-executor.js +1367 -0
- package/dist/github/actions-change-executor.js.map +1 -0
- package/dist/github/adapter.d.ts +34 -1
- package/dist/github/adapter.js +398 -2
- package/dist/github/adapter.js.map +1 -1
- package/dist/github/capability.d.ts +7 -1
- package/dist/github/capability.js +52 -0
- package/dist/github/capability.js.map +1 -1
- package/dist/github/change-actions-remote-executor.d.ts +43 -0
- package/dist/github/change-actions-remote-executor.js +532 -0
- package/dist/github/change-actions-remote-executor.js.map +1 -0
- package/dist/github/change-effect-adapter.d.ts +108 -0
- package/dist/github/change-effect-adapter.js +386 -0
- package/dist/github/change-effect-adapter.js.map +1 -0
- package/dist/github/index.d.ts +5 -0
- package/dist/github/index.js +5 -0
- package/dist/github/index.js.map +1 -1
- package/dist/github/issue-relation-observation-adapter.d.ts +88 -0
- package/dist/github/issue-relation-observation-adapter.js +264 -0
- package/dist/github/issue-relation-observation-adapter.js.map +1 -0
- package/dist/github/issuer-authority.d.ts +197 -0
- package/dist/github/issuer-authority.js +779 -0
- package/dist/github/issuer-authority.js.map +1 -0
- package/dist/github/types.d.ts +58 -1
- package/dist/governance.d.ts +51 -9
- package/dist/governance.js +175 -23
- package/dist/governance.js.map +1 -1
- package/dist/index.d.ts +17 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- package/dist/issuer-identity.d.ts +12 -0
- package/dist/issuer-identity.js +14 -0
- package/dist/issuer-identity.js.map +1 -0
- package/dist/legacy-artifact-convergence.d.ts +77 -0
- package/dist/legacy-artifact-convergence.js +515 -0
- package/dist/legacy-artifact-convergence.js.map +1 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +18 -0
- package/dist/mcp/server.js +25 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +13 -0
- package/dist/mcp/stdio.js +109 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/mcp/tools.d.ts +293 -0
- package/dist/mcp/tools.js +772 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/semantic-branch-executor.d.ts +82 -0
- package/dist/semantic-branch-executor.js +281 -0
- package/dist/semantic-branch-executor.js.map +1 -0
- package/dist/semantic-branch-observation.d.ts +90 -0
- package/dist/semantic-branch-observation.js +278 -0
- package/dist/semantic-branch-observation.js.map +1 -0
- package/dist/semantic-branch-projection.d.ts +103 -0
- package/dist/semantic-branch-projection.js +528 -0
- package/dist/semantic-branch-projection.js.map +1 -0
- package/dist/semantic-issue-executor.d.ts +97 -0
- package/dist/semantic-issue-executor.js +311 -0
- package/dist/semantic-issue-executor.js.map +1 -0
- package/dist/semantic-issue-lifecycle.d.ts +118 -0
- package/dist/semantic-issue-lifecycle.js +498 -0
- package/dist/semantic-issue-lifecycle.js.map +1 -0
- package/dist/semantic-issue-observation.d.ts +145 -0
- package/dist/semantic-issue-observation.js +960 -0
- package/dist/semantic-issue-observation.js.map +1 -0
- package/dist/semantic-issue-projection.d.ts +155 -0
- package/dist/semantic-issue-projection.js +838 -0
- package/dist/semantic-issue-projection.js.map +1 -0
- package/dist/semantic-pr-executor.d.ts +103 -0
- package/dist/semantic-pr-executor.js +340 -0
- package/dist/semantic-pr-executor.js.map +1 -0
- package/dist/semantic-pr-observation.d.ts +153 -0
- package/dist/semantic-pr-observation.js +1214 -0
- package/dist/semantic-pr-observation.js.map +1 -0
- package/dist/semantic-pr-projection.d.ts +146 -0
- package/dist/semantic-pr-projection.js +857 -0
- package/dist/semantic-pr-projection.js.map +1 -0
- package/dist/semantic-template.js +47 -35
- package/dist/semantic-template.js.map +1 -1
- package/dist/skill.d.ts +9 -1
- package/dist/skill.js +75 -64
- package/dist/skill.js.map +1 -1
- package/dist/template-discovery.js +26 -50
- package/dist/template-discovery.js.map +1 -1
- package/dist/template-resolver.d.ts +76 -0
- package/dist/template-resolver.js +344 -0
- package/dist/template-resolver.js.map +1 -0
- package/package.json +62 -5
- package/skills/inari/SKILL.md +8 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inari",
|
|
3
|
-
"version": "0.
|
|
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
|
@@ -90,8 +90,10 @@ recovery command. The current capability identifiers are
|
|
|
90
90
|
`canonical-invocation`, `machine-readable-version`, `capability-diagnostics`,
|
|
91
91
|
and `extension-bootstrap`.
|
|
92
92
|
|
|
93
|
-
The `inari
|
|
94
|
-
|
|
93
|
+
The `inari` executable is canonical. The direct package executable
|
|
94
|
+
`gh-inari` and the `gh inari` extension form are compatibility paths with the
|
|
95
|
+
same governed command semantics; prefer `inari` for agent and human-facing
|
|
96
|
+
commands:
|
|
95
97
|
|
|
96
98
|
```bash
|
|
97
99
|
inari issue schema feature --json
|
|
@@ -172,6 +174,10 @@ inari issue normalize <number> [--dry-run]
|
|
|
172
174
|
inari pr normalize <number> [--dry-run]
|
|
173
175
|
inari issue sync <number> --from desired.json [--dry-run]
|
|
174
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
|
|
175
181
|
```
|
|
176
182
|
|
|
177
183
|
`--from -` reads JSON from stdin. Create input uses an envelope when mutation metadata is needed:
|
|
@@ -193,6 +199,13 @@ and a valid `syncInput.minimalExample`.
|
|
|
193
199
|
`issue sync --from` overlays supplied semantic fields and metadata onto the
|
|
194
200
|
current artifact, preserving values omitted from the input.
|
|
195
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
|
+
|
|
196
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`.
|
|
197
210
|
|
|
198
211
|
`issue get` and `pr get` are canonical-only v1 reads. They resolve the target
|
|
@@ -260,6 +273,22 @@ templates:
|
|
|
260
273
|
|
|
261
274
|
Template and section bindings are deterministic. Stale, unknown, or ambiguous template/section references fail closed. `linkedIssue: true` means that the field contains a GitHub closing reference: `close`, `closes`, `closed`, `fix`, `fixes`, `fixed`, `resolve`, `resolves`, or `resolved`, followed by `#ISSUE-NUMBER` or `OWNER/REPOSITORY#ISSUE-NUMBER`, with an optional colon and case-insensitive keyword. This validates syntax only; GitHub applies automatic linking/closure only under its own contextual rules, including the target default branch.
|
|
262
275
|
|
|
276
|
+
When `issue create` or `pr create` omits `--template`, the shared resolver uses
|
|
277
|
+
the repository's optional `.github/inari/template-resolution.yml` authority:
|
|
278
|
+
|
|
279
|
+
```yaml
|
|
280
|
+
version: 1
|
|
281
|
+
defaults:
|
|
282
|
+
issue: feature
|
|
283
|
+
pr: default
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The precedence is explicit selector, configured default, sole candidate,
|
|
287
|
+
interactive TTY selection, then bounded failure. Non-interactive execution never
|
|
288
|
+
guesses among multiple candidates. An invalid or unavailable configured default
|
|
289
|
+
also fails closed. Candidate identifiers and an explicit `--template` recovery
|
|
290
|
+
action are included in structured ambiguity diagnostics.
|
|
291
|
+
|
|
263
292
|
Issue Form top-level `title` is a fixed native prefix for create validation, but it does not satisfy the caller's required title metadata by itself. An explicit caller title is used as supplied without inferred prefix concatenation or automatic generation. Top-level `labels` are repository-governed defaults and are always retained; caller-supplied labels are appended in order with duplicates removed. Top-level `assignees`, `projects`, and `type`, and upload fields remain unsupported and fail closed rather than being approximated.
|
|
264
293
|
|
|
265
294
|
## Scope
|
|
@@ -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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"}
|
package/dist/artifact.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
-
|
|
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" : " "}] ${
|
|
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
|
-
/**
|
|
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")
|