gh-inari 0.8.0 → 0.10.2
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 +35 -11
- package/dist/artifact.d.ts +29 -2
- package/dist/artifact.js +266 -26
- package/dist/artifact.js.map +1 -1
- package/dist/cli-core.d.ts +24 -0
- package/dist/cli-core.js +1463 -0
- package/dist/cli-core.js.map +1 -0
- package/dist/cli.d.ts +9 -13
- package/dist/cli.js +123 -1365
- package/dist/cli.js.map +1 -1
- package/dist/command-contract.d.ts +128 -0
- package/dist/command-contract.js +343 -0
- package/dist/command-contract.js.map +1 -0
- package/dist/contract/index.d.ts +1 -0
- package/dist/contract/index.js +1 -0
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/ir.d.ts +6 -0
- package/dist/contract/ir.js +24 -2
- package/dist/contract/ir.js.map +1 -1
- package/dist/contract/issue-form.js +2 -2
- package/dist/contract/issue-form.js.map +1 -1
- package/dist/contract/issue-reference.d.ts +58 -0
- package/dist/contract/issue-reference.js +157 -0
- package/dist/contract/issue-reference.js.map +1 -0
- package/dist/contract/schema.d.ts +4 -0
- package/dist/contract/schema.js +42 -1
- package/dist/contract/schema.js.map +1 -1
- package/dist/contract/validation.d.ts +1 -1
- package/dist/contract/validation.js +1 -1
- package/dist/contract/validation.js.map +1 -1
- package/dist/github/adapter.d.ts +2 -0
- package/dist/github/adapter.js +80 -32
- package/dist/github/adapter.js.map +1 -1
- package/dist/github/types.d.ts +7 -0
- package/dist/governance.d.ts +12 -7
- package/dist/governance.js +92 -20
- package/dist/governance.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/reconciliation.d.ts +11 -8
- package/dist/reconciliation.js +170 -30
- package/dist/reconciliation.js.map +1 -1
- package/dist/semantic-template.js +23 -32
- package/dist/semantic-template.js.map +1 -1
- package/dist/skill.d.ts +8 -0
- package/dist/skill.js +68 -43
- 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 +7 -3
- package/skills/inari/SKILL.md +4 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inari",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.2",
|
|
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
|
|
@@ -166,8 +168,8 @@ inari issue get <number> [--template <template>] --json
|
|
|
166
168
|
inari pr get <number> [--template <template>] --json
|
|
167
169
|
inari issue check <number> [--template <template>]
|
|
168
170
|
inari pr check <number> [--template <template>]
|
|
169
|
-
inari issue edit <number> --from patch.json [--dry-run]
|
|
170
|
-
inari pr edit <number> --from patch.json [--dry-run]
|
|
171
|
+
inari issue edit <number> [--from patch.json] [--field name=value] [--title title] [--dry-run]
|
|
172
|
+
inari pr edit <number> [--from patch.json] [--field name=value] [--title title] [--base branch] [--maintainer-can-modify] [--dry-run]
|
|
171
173
|
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]
|
|
@@ -184,12 +186,14 @@ inari pr sync <number> --from desired.json [--dry-run]
|
|
|
184
186
|
}
|
|
185
187
|
```
|
|
186
188
|
|
|
187
|
-
The `fields` object is the semantic input contract shown by `schema
|
|
189
|
+
The `fields` object is the semantic input contract shown by `schema`; the same schema output exposes the separate required create metadata schema. Issue creation also accepts `assignees`; pull request creation accepts `head`, `base`, `draft`, and `maintainerCanModify`. Caller-supplied `title` metadata is required for both create commands, and `--title`, `--head`, and `--base` override envelope metadata. Existing `edit` commands use the remote artifact as their patch base: `--title` is supported for Issues and pull requests, while pull requests also support `--base` and `--maintainer-can-modify`; `--draft` is rejected for edit because pull-request PATCH does not accept it. Omitted values are preserved and unsupported or immutable metadata is rejected.
|
|
188
190
|
|
|
189
191
|
`pr sync --from` accepts a complete pull-request desired-state envelope. Use
|
|
190
192
|
`inari pr sync --help` for the top-level contract, or
|
|
191
193
|
`inari pr schema <template> --json` for its machine-readable `syncInput.schema`
|
|
192
194
|
and a valid `syncInput.minimalExample`.
|
|
195
|
+
`issue sync --from` overlays supplied semantic fields and metadata onto the
|
|
196
|
+
current artifact, preserving values omitted from the input.
|
|
193
197
|
|
|
194
198
|
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`.
|
|
195
199
|
|
|
@@ -211,18 +215,22 @@ boilerplate and raw Markdown are intentionally absent from successful output.
|
|
|
211
215
|
Existing artifact remediation uses one semantic pipeline for both Issues and
|
|
212
216
|
pull requests. `check` is read-only and classifies an artifact as
|
|
213
217
|
`valid-current`, `non-canonical`, `semantically-invalid`, `unsupported`, or
|
|
214
|
-
`ambiguous`. `edit` applies
|
|
215
|
-
accepts raw Markdown as the mutation contract. `normalize` re-renders a
|
|
218
|
+
`ambiguous`. `edit` applies an explicit semantic/metadata patch from JSON or
|
|
219
|
+
direct CLI options; it never accepts raw Markdown as the mutation contract. `normalize` re-renders a
|
|
216
220
|
parseable, semantically valid artifact and fails closed when preservation is
|
|
217
|
-
not proven. `sync`
|
|
218
|
-
|
|
221
|
+
not proven. `issue sync` overlays its input onto the current canonical state,
|
|
222
|
+
while `pr sync` treats its input as the complete desired semantic state; both
|
|
223
|
+
reconcile the canonical projection deterministically. A successful no-op is
|
|
219
224
|
reported explicitly, and `--dry-run` returns a bounded semantic/rendered diff
|
|
220
|
-
|
|
225
|
+
plus the validated resulting fields, metadata, and canonical body without
|
|
226
|
+
calling a GitHub mutation.
|
|
221
227
|
|
|
222
228
|
## Source of truth and supported semantics
|
|
223
229
|
|
|
224
230
|
`.github/ISSUE_TEMPLATE/**` remains the Issue source of truth. For pull requests, Inari discovers GitHub's supported repository locations: `pull_request_template` files under the repository root, `docs/`, or `.github/`, plus `PULL_REQUEST_TEMPLATE/` directories under each location. Native PR template filenames and the `.md`/`.txt` extensions supported by Inari are matched case-insensitively. Other PR-template extension surfaces are intentionally unsupported in v1 and fail closed. Inari discovers and compiles those files; it does not replace them with a proprietary body schema. Supported Issue Form nodes are `input`, `textarea` (including native `render` code fences), single- and multi-select `dropdown`, `checkboxes`, and `markdown`. Browser-only or ambiguous behavior, such as uploads or unsupported textarea rendering modes, fails closed. Markdown nodes are retained for contract/schema explainability but never emitted into an Issue body.
|
|
225
231
|
|
|
232
|
+
Issue dependencies are a separate, template-independent semantic object. Structured Issue envelopes may provide `dependencies.blockedBy` and `dependencies.blocks`; each reference is the canonical `{ "repositoryHost": "github.com", "repositoryId": "<decimal REST repository database id>", "repository": "owner/name", "number": N }` identity. `repositoryHost` plus `repositoryId` is authoritative: the host/install boundary prevents IDs from different GH_HOST/GHES installations colliding. Within one host, rename/transfer preserves the repository identity tuple and changes only the optional locator; cross-host migration is a different identity. The GitHub adapter obtains this decimal ID from the REST repository endpoint through `gh api`, including for repository overrides through a read-only identity lookup; a context that cannot obtain it does not synthesize one from owner/name. Inari sorts and validates these references (including duplicate, self, malformed, and contradictory declarations) before rendering. Non-empty dependencies are preserved in a bounded reserved body marker and projected back as normalized JSON; ordinary Markdown and GitHub-native dependency metadata are never inferred as semantic input. GitHub-native dependency state is not currently mutated by Inari, so there is no competing authority or implicit drift reconciliation.
|
|
233
|
+
|
|
226
234
|
Native PR Markdown expresses structure but not policy. A small versioned overlay may add constraints unavailable in Markdown without changing section order or content. The supported v1 form is:
|
|
227
235
|
|
|
228
236
|
```yaml
|
|
@@ -254,7 +262,23 @@ templates:
|
|
|
254
262
|
|
|
255
263
|
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.
|
|
256
264
|
|
|
257
|
-
|
|
265
|
+
When `issue create` or `pr create` omits `--template`, the shared resolver uses
|
|
266
|
+
the repository's optional `.github/inari/template-resolution.yml` authority:
|
|
267
|
+
|
|
268
|
+
```yaml
|
|
269
|
+
version: 1
|
|
270
|
+
defaults:
|
|
271
|
+
issue: feature
|
|
272
|
+
pr: default
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The precedence is explicit selector, configured default, sole candidate,
|
|
276
|
+
interactive TTY selection, then bounded failure. Non-interactive execution never
|
|
277
|
+
guesses among multiple candidates. An invalid or unavailable configured default
|
|
278
|
+
also fails closed. Candidate identifiers and an explicit `--template` recovery
|
|
279
|
+
action are included in structured ambiguity diagnostics.
|
|
280
|
+
|
|
281
|
+
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.
|
|
258
282
|
|
|
259
283
|
## Scope
|
|
260
284
|
|
package/dist/artifact.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type PartialSemanticValidationResult, type PartialSemanticRepairResult, type SemanticValidationResult, type SemanticViolation } from "./contract/validation.js";
|
|
2
2
|
import { type ArtifactDiagnostic, type ArtifactDiagnosticReport } from "./diagnostics.js";
|
|
3
3
|
import { type ArtifactKind, type CanonicalContract } from "./contract/ir.js";
|
|
4
|
+
import { type IssueDependencies, type IssueReference } from "./contract/issue-reference.js";
|
|
4
5
|
import { type ValidatedRenderedIssueArtifact, type ValidatedRenderedPullRequestArtifact } from "./github/types.js";
|
|
5
6
|
export interface ArtifactInputMetadata {
|
|
6
7
|
readonly title?: string;
|
|
@@ -14,6 +15,8 @@ export interface ArtifactInputMetadata {
|
|
|
14
15
|
export interface ArtifactInputDocument {
|
|
15
16
|
readonly fields: Readonly<Record<string, unknown>>;
|
|
16
17
|
readonly metadata: ArtifactInputMetadata;
|
|
18
|
+
/** Generic Issue relationships, independent of template-specific fields. */
|
|
19
|
+
readonly dependencies?: IssueDependencies;
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
19
22
|
* A representation-independent candidate entering the canonical contract.
|
|
@@ -26,6 +29,7 @@ export interface ArtifactCandidate {
|
|
|
26
29
|
readonly fields: unknown;
|
|
27
30
|
readonly metadata: ArtifactInputMetadata;
|
|
28
31
|
readonly source: ArtifactCandidateSource;
|
|
32
|
+
readonly dependencies?: IssueDependencies;
|
|
29
33
|
}
|
|
30
34
|
export interface ArtifactCandidateAdapterResult {
|
|
31
35
|
readonly parsed: boolean;
|
|
@@ -48,13 +52,14 @@ export interface CanonicalArtifactLoadResult {
|
|
|
48
52
|
readonly invalidFields: PartialSemanticValidationResult["invalidFields"];
|
|
49
53
|
readonly diagnostics: ArtifactDiagnosticReport;
|
|
50
54
|
readonly violations: readonly SemanticViolation[];
|
|
55
|
+
readonly dependencies?: IssueDependencies;
|
|
51
56
|
}
|
|
52
57
|
export interface ArtifactMetadataViolation {
|
|
53
58
|
readonly code: "INPUT_METADATA_INVALID";
|
|
54
59
|
readonly path: string;
|
|
55
60
|
readonly message: string;
|
|
56
61
|
}
|
|
57
|
-
export type ArtifactInputErrorCode = "INPUT_DOCUMENT_INVALID" | "INPUT_METADATA_INVALID";
|
|
62
|
+
export type ArtifactInputErrorCode = "INPUT_DOCUMENT_INVALID" | "INPUT_METADATA_INVALID" | "INPUT_DEPENDENCIES_INVALID";
|
|
58
63
|
export declare class ArtifactInputError extends Error {
|
|
59
64
|
readonly code: ArtifactInputErrorCode;
|
|
60
65
|
readonly path: string;
|
|
@@ -92,6 +97,9 @@ export interface ExistingArtifactDiagnostic {
|
|
|
92
97
|
export interface ExistingArtifactParseResult {
|
|
93
98
|
readonly parsed: boolean;
|
|
94
99
|
readonly values: Readonly<Record<string, unknown>>;
|
|
100
|
+
readonly dependencies?: IssueDependencies;
|
|
101
|
+
/** Raw dependency declaration retained for the semantic validation boundary. */
|
|
102
|
+
readonly dependencyInput?: unknown;
|
|
95
103
|
readonly diagnostics: readonly ExistingArtifactDiagnostic[];
|
|
96
104
|
}
|
|
97
105
|
/**
|
|
@@ -101,6 +109,7 @@ export interface ExistingArtifactParseResult {
|
|
|
101
109
|
*/
|
|
102
110
|
export interface RecoverableArtifactValues {
|
|
103
111
|
readonly values: Readonly<Record<string, unknown>>;
|
|
112
|
+
readonly dependencies?: IssueDependencies;
|
|
104
113
|
readonly diagnostics: readonly ExistingArtifactDiagnostic[];
|
|
105
114
|
}
|
|
106
115
|
export interface ExistingArtifactValidationResult {
|
|
@@ -115,6 +124,8 @@ export interface ExistingIssueReader {
|
|
|
115
124
|
getIssue(issueNumber: number): Promise<{
|
|
116
125
|
readonly body: string | null;
|
|
117
126
|
readonly url: string;
|
|
127
|
+
readonly repositoryId?: string;
|
|
128
|
+
readonly repositoryHost?: string;
|
|
118
129
|
}>;
|
|
119
130
|
}
|
|
120
131
|
export interface ExistingPullRequestReader {
|
|
@@ -132,6 +143,7 @@ export interface ExistingPullRequestReader {
|
|
|
132
143
|
* repository governance/provenance that resolves the actual contract.
|
|
133
144
|
*/
|
|
134
145
|
export declare const TEMPLATE_IDENTITY_MARKER_VERSION: "1";
|
|
146
|
+
export declare const ISSUE_DEPENDENCY_MARKER_VERSION: "1";
|
|
135
147
|
export interface TemplateIdentityMarker {
|
|
136
148
|
readonly version: string;
|
|
137
149
|
readonly kind: ArtifactKind;
|
|
@@ -144,6 +156,18 @@ export interface TemplateIdentityMarkerExtraction {
|
|
|
144
156
|
/** Body with a recognized trailing marker line removed; unchanged when none is present. */
|
|
145
157
|
readonly body: string;
|
|
146
158
|
}
|
|
159
|
+
export type IssueDependencyMarkerStatus = "absent" | "valid" | "malformed" | "unsupported-version";
|
|
160
|
+
export interface IssueDependencyMarkerExtraction {
|
|
161
|
+
readonly status: IssueDependencyMarkerStatus;
|
|
162
|
+
readonly dependencies?: IssueDependencies;
|
|
163
|
+
/** Body with a recognized trailing dependency marker removed. */
|
|
164
|
+
readonly body: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Read only the reserved trailing dependency marker emitted by Inari. No
|
|
168
|
+
* ordinary Markdown is interpreted as a relationship declaration.
|
|
169
|
+
*/
|
|
170
|
+
export declare function extractIssueDependencyMarker(body: string): IssueDependencyMarkerExtraction;
|
|
147
171
|
/**
|
|
148
172
|
* Recognize and remove a trailing template identity marker line without
|
|
149
173
|
* applying semantic parsing. Only a line starting with the exact reserved
|
|
@@ -212,7 +236,7 @@ export declare function parseExistingPullRequestArtifact(contractInput: unknown,
|
|
|
212
236
|
* selected repair target.
|
|
213
237
|
*/
|
|
214
238
|
export declare function recoverExistingArtifactValues(contractInput: unknown, body: string | null | undefined): RecoverableArtifactValues;
|
|
215
|
-
export declare function validateExistingIssueArtifact(contractInput: unknown, body: string | null | undefined): ExistingArtifactValidationResult;
|
|
239
|
+
export declare function validateExistingIssueArtifact(contractInput: unknown, body: string | null | undefined, subject?: IssueReference): ExistingArtifactValidationResult;
|
|
216
240
|
export declare function validateExistingPullRequestArtifact(contractInput: unknown, body: string | null | undefined): ExistingArtifactValidationResult;
|
|
217
241
|
export interface ExistingArtifactCandidate {
|
|
218
242
|
readonly contract: CanonicalContract;
|
|
@@ -227,6 +251,7 @@ export interface ExistingArtifactProjection {
|
|
|
227
251
|
readonly projection: "canonical" | "unavailable";
|
|
228
252
|
readonly classification: ExistingArtifactClassification;
|
|
229
253
|
readonly fields?: Readonly<Record<string, unknown>>;
|
|
254
|
+
readonly dependencies?: IssueDependencies;
|
|
230
255
|
readonly diagnostics: readonly ExistingArtifactDiagnostic[];
|
|
231
256
|
readonly violations?: readonly SemanticViolation[];
|
|
232
257
|
readonly attemptedTemplates?: readonly string[];
|
|
@@ -239,6 +264,8 @@ export declare function selectExistingArtifactCandidate(candidates: readonly Exi
|
|
|
239
264
|
export declare function validateRequiredMetadataString(value: unknown, key: string): ArtifactMetadataViolation | undefined;
|
|
240
265
|
export declare function validateExistingIssueFromAdapter(reader: ExistingIssueReader, contract: unknown, issueNumber: number): Promise<FetchedExistingArtifact>;
|
|
241
266
|
export declare function validateExistingPullRequestFromAdapter(reader: ExistingPullRequestReader, contract: unknown, pullRequestNumber: number): Promise<FetchedExistingArtifact>;
|
|
267
|
+
/** @internal Validate the canonical Issue metadata handoff before mutation. */
|
|
268
|
+
export declare function verifyIssueMetadataRoundTrip(expected: Readonly<Record<string, unknown>>, artifact: ValidatedRenderedIssueArtifact): void;
|
|
242
269
|
/** Escape only Markdown constructs that could change the canonical section structure. */
|
|
243
270
|
export declare function escapeMarkdownValue(value: string): string;
|
|
244
271
|
export declare function removeHtmlComments(value: string): string;
|