gh-inari 0.7.0 → 0.8.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 +20 -1
- package/dist/artifact.d.ts +129 -13
- package/dist/artifact.js +579 -63
- package/dist/artifact.js.map +1 -1
- package/dist/cli.js +300 -53
- package/dist/cli.js.map +1 -1
- 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 +11 -0
- package/dist/contract/ir.js +23 -1
- package/dist/contract/ir.js.map +1 -1
- package/dist/contract/issue-form.js +15 -2
- package/dist/contract/issue-form.js.map +1 -1
- package/dist/contract/normalization.d.ts +31 -0
- package/dist/contract/normalization.js +73 -0
- package/dist/contract/normalization.js.map +1 -0
- package/dist/contract/validation.d.ts +120 -2
- package/dist/contract/validation.js +476 -3
- package/dist/contract/validation.js.map +1 -1
- package/dist/diagnostics.d.ts +133 -0
- package/dist/diagnostics.js +421 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/github/capability.js +1 -0
- package/dist/github/capability.js.map +1 -1
- package/dist/governance.d.ts +8 -2
- package/dist/governance.js +54 -4
- 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/pr-policy.d.ts +9 -0
- package/dist/pr-policy.js +36 -16
- package/dist/pr-policy.js.map +1 -1
- package/dist/pr-sync-input.d.ts +74 -0
- package/dist/pr-sync-input.js +231 -0
- package/dist/pr-sync-input.js.map +1 -0
- package/dist/reconciliation.d.ts +16 -12
- package/dist/reconciliation.js +361 -28
- package/dist/reconciliation.js.map +1 -1
- package/dist/semantic-template.js +25 -4
- package/dist/semantic-template.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inari",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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
|
@@ -129,6 +129,16 @@ marketplace registration and installation via Codex plugin commands to
|
|
|
129
129
|
activate the skill; standard `npm install` alone does not automatically
|
|
130
130
|
surface the plugin to Codex-aware agents.
|
|
131
131
|
|
|
132
|
+
To discover and install it from this repository's marketplace:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
codex plugin marketplace add .
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
In Codex, run `/plugins`, select the `gh-inari` marketplace, and install
|
|
139
|
+
`inari`. Start a new Codex session after installation so the bundled Skill
|
|
140
|
+
is available.
|
|
141
|
+
|
|
132
142
|
The Skill is deliberately thin: it identifies governed GitHub Issue/PR/
|
|
133
143
|
template workflows as Inari-owned and routes agents to `inari skill` /
|
|
134
144
|
`inari skill <scenario>` for the actual operational playbooks, and to
|
|
@@ -176,6 +186,11 @@ inari pr sync <number> --from desired.json [--dry-run]
|
|
|
176
186
|
|
|
177
187
|
The `fields` object is the semantic input contract shown by `schema`. Issue creation also accepts `assignees`; pull request creation accepts `head`, `base`, `draft`, and `maintainerCanModify`. `--title`, `--head`, and `--base` override envelope metadata.
|
|
178
188
|
|
|
189
|
+
`pr sync --from` accepts a complete pull-request desired-state envelope. Use
|
|
190
|
+
`inari pr sync --help` for the top-level contract, or
|
|
191
|
+
`inari pr schema <template> --json` for its machine-readable `syncInput.schema`
|
|
192
|
+
and a valid `syncInput.minimalExample`.
|
|
193
|
+
|
|
179
194
|
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`.
|
|
180
195
|
|
|
181
196
|
`issue get` and `pr get` are canonical-only v1 reads. They resolve the target
|
|
@@ -185,7 +200,11 @@ parse the existing artifact with the same parser and semantic validator as
|
|
|
185
200
|
metadata. Successful reads report `projection: "canonical"`; wrong-template,
|
|
186
201
|
unparseable, ambiguous, and semantically invalid artifacts report structured
|
|
187
202
|
diagnostics with `projection: "unavailable"` and never return guessed fields.
|
|
188
|
-
When `--template` is omitted,
|
|
203
|
+
When `--template` is omitted, Inari first looks for the bounded invisible
|
|
204
|
+
template identity marker every rendered artifact now carries. A valid marker
|
|
205
|
+
resolves the contract directly; an unknown, stale, or wrong-kind marker fails
|
|
206
|
+
closed with a diagnostic instead of guessing another template. Artifacts
|
|
207
|
+
without a marker fall back to evaluating all supported candidates
|
|
189
208
|
deterministically; multiple structural matches fail closed. Native template
|
|
190
209
|
boilerplate and raw Markdown are intentionally absent from successful output.
|
|
191
210
|
|
package/dist/artifact.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type SemanticValidationResult, type SemanticViolation } from "./contract/validation.js";
|
|
2
|
-
import { type
|
|
1
|
+
import { type PartialSemanticValidationResult, type PartialSemanticRepairResult, type SemanticValidationResult, type SemanticViolation } from "./contract/validation.js";
|
|
2
|
+
import { type ArtifactDiagnostic, type ArtifactDiagnosticReport } from "./diagnostics.js";
|
|
3
|
+
import { type ArtifactKind, type CanonicalContract } from "./contract/ir.js";
|
|
3
4
|
import { type ValidatedRenderedIssueArtifact, type ValidatedRenderedPullRequestArtifact } from "./github/types.js";
|
|
4
5
|
export interface ArtifactInputMetadata {
|
|
5
6
|
readonly title?: string;
|
|
@@ -14,6 +15,40 @@ export interface ArtifactInputDocument {
|
|
|
14
15
|
readonly fields: Readonly<Record<string, unknown>>;
|
|
15
16
|
readonly metadata: ArtifactInputMetadata;
|
|
16
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* A representation-independent candidate entering the canonical contract.
|
|
20
|
+
* Adapters may decode JSON, native Markdown, an existing GitHub body, or
|
|
21
|
+
* internal field input, but they never validate or materialize contract
|
|
22
|
+
* semantics themselves.
|
|
23
|
+
*/
|
|
24
|
+
export type ArtifactCandidateSource = "json" | "markdown" | "existing" | "fields";
|
|
25
|
+
export interface ArtifactCandidate {
|
|
26
|
+
readonly fields: unknown;
|
|
27
|
+
readonly metadata: ArtifactInputMetadata;
|
|
28
|
+
readonly source: ArtifactCandidateSource;
|
|
29
|
+
}
|
|
30
|
+
export interface ArtifactCandidateAdapterResult {
|
|
31
|
+
readonly parsed: boolean;
|
|
32
|
+
readonly candidate?: ArtifactCandidate;
|
|
33
|
+
readonly diagnostics: readonly ExistingArtifactDiagnostic[];
|
|
34
|
+
}
|
|
35
|
+
/** Result of the one candidate -> selected contract -> canonical JSON boundary. */
|
|
36
|
+
export interface CanonicalArtifactLoadResult {
|
|
37
|
+
readonly valid: boolean;
|
|
38
|
+
readonly complete: boolean;
|
|
39
|
+
/** Canonical contract-shaped semantic JSON. Never contains rejected fields. */
|
|
40
|
+
readonly canonical: Readonly<Record<string, unknown>>;
|
|
41
|
+
/** Explicit alias for callers that name the output canonical JSON. */
|
|
42
|
+
readonly canonicalJson: Readonly<Record<string, unknown>>;
|
|
43
|
+
/** Backward-compatible semantic value name used by renderer callers. */
|
|
44
|
+
readonly values: Readonly<Record<string, unknown>>;
|
|
45
|
+
readonly candidate: ArtifactCandidate;
|
|
46
|
+
readonly acceptedFields: readonly string[];
|
|
47
|
+
readonly missingFields: PartialSemanticValidationResult["missingFields"];
|
|
48
|
+
readonly invalidFields: PartialSemanticValidationResult["invalidFields"];
|
|
49
|
+
readonly diagnostics: ArtifactDiagnosticReport;
|
|
50
|
+
readonly violations: readonly SemanticViolation[];
|
|
51
|
+
}
|
|
17
52
|
export interface ArtifactMetadataViolation {
|
|
18
53
|
readonly code: "INPUT_METADATA_INVALID";
|
|
19
54
|
readonly path: string;
|
|
@@ -23,21 +58,18 @@ export type ArtifactInputErrorCode = "INPUT_DOCUMENT_INVALID" | "INPUT_METADATA_
|
|
|
23
58
|
export declare class ArtifactInputError extends Error {
|
|
24
59
|
readonly code: ArtifactInputErrorCode;
|
|
25
60
|
readonly path: string;
|
|
26
|
-
|
|
61
|
+
readonly details?: unknown;
|
|
62
|
+
constructor(code: ArtifactInputErrorCode, message: string, path?: string, details?: unknown);
|
|
27
63
|
}
|
|
28
64
|
export type ArtifactPreparationErrorCode = "ARTIFACT_PROVENANCE_MISSING" | "ARTIFACT_ROUND_TRIP_INVALID";
|
|
29
|
-
|
|
30
|
-
export
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
readonly message: string;
|
|
34
|
-
readonly expected?: unknown;
|
|
35
|
-
readonly actual?: unknown;
|
|
36
|
-
}
|
|
65
|
+
/** @deprecated Round-trip diagnostics use the shared #118 diagnostic contract. */
|
|
66
|
+
export type ArtifactRoundTripDiagnostic = ArtifactDiagnostic;
|
|
67
|
+
/** @deprecated Use ArtifactDiagnosticCode/ArtifactDiagnosticDetailCode. */
|
|
68
|
+
export type ArtifactRoundTripDiagnosticCode = ArtifactDiagnostic["code"];
|
|
37
69
|
/** Stable failures raised before a mutation-capable artifact is created. */
|
|
38
70
|
export declare class ArtifactPreparationError extends Error {
|
|
39
71
|
readonly code: ArtifactPreparationErrorCode;
|
|
40
|
-
readonly diagnostics: readonly
|
|
72
|
+
readonly diagnostics: readonly ArtifactDiagnostic[];
|
|
41
73
|
constructor(code: ArtifactPreparationErrorCode, message: string, diagnostics?: readonly ArtifactRoundTripDiagnostic[]);
|
|
42
74
|
}
|
|
43
75
|
export interface PreparedIssueArtifact {
|
|
@@ -51,7 +83,7 @@ export interface PreparedPullRequestArtifact {
|
|
|
51
83
|
readonly artifact: ValidatedRenderedPullRequestArtifact;
|
|
52
84
|
}
|
|
53
85
|
export type ExistingArtifactClassification = "valid" | "semantic" | "wrong-template" | "unparseable" | "ambiguous";
|
|
54
|
-
export type ExistingArtifactDiagnosticCode = "EXISTING_WRONG_TEMPLATE" | "EXISTING_UNPARSEABLE" | "EXISTING_EXTRA_CONTENT" | "EXISTING_UNKNOWN_CHECKLIST_ITEM" | "EXISTING_AMBIGUOUS_TEMPLATE" | "EXISTING_NON_CANONICAL" | "EXISTING_TEMPLATE_COMPILE_FAILED";
|
|
86
|
+
export type ExistingArtifactDiagnosticCode = "EXISTING_WRONG_TEMPLATE" | "EXISTING_UNPARSEABLE" | "EXISTING_EXTRA_CONTENT" | "EXISTING_UNKNOWN_CHECKLIST_ITEM" | "EXISTING_AMBIGUOUS_TEMPLATE" | "EXISTING_NON_CANONICAL" | "EXISTING_TEMPLATE_COMPILE_FAILED" | "EXISTING_TEMPLATE_MARKER_INVALID";
|
|
55
87
|
export interface ExistingArtifactDiagnostic {
|
|
56
88
|
readonly code: ExistingArtifactDiagnosticCode;
|
|
57
89
|
readonly path: string;
|
|
@@ -62,6 +94,15 @@ export interface ExistingArtifactParseResult {
|
|
|
62
94
|
readonly values: Readonly<Record<string, unknown>>;
|
|
63
95
|
readonly diagnostics: readonly ExistingArtifactDiagnostic[];
|
|
64
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Semantic values recovered from an artifact that did not pass the strict
|
|
99
|
+
* structural parser. Values are extracted only from unambiguous contract
|
|
100
|
+
* sections and are still subject to the canonical semantic loader before use.
|
|
101
|
+
*/
|
|
102
|
+
export interface RecoverableArtifactValues {
|
|
103
|
+
readonly values: Readonly<Record<string, unknown>>;
|
|
104
|
+
readonly diagnostics: readonly ExistingArtifactDiagnostic[];
|
|
105
|
+
}
|
|
65
106
|
export interface ExistingArtifactValidationResult {
|
|
66
107
|
readonly valid: boolean;
|
|
67
108
|
readonly classification: ExistingArtifactClassification;
|
|
@@ -82,6 +123,38 @@ export interface ExistingPullRequestReader {
|
|
|
82
123
|
readonly url: string;
|
|
83
124
|
}>;
|
|
84
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Bounded invisible template identity marker embedded in newly rendered
|
|
128
|
+
* artifacts. It is the primary template-selection signal for governed
|
|
129
|
+
* read/repair/validation; legacy artifacts without a marker (or with one
|
|
130
|
+
* that cannot be trusted) fall back to deterministic structural matching.
|
|
131
|
+
* The marker is metadata only: it never substitutes for the authoritative
|
|
132
|
+
* repository governance/provenance that resolves the actual contract.
|
|
133
|
+
*/
|
|
134
|
+
export declare const TEMPLATE_IDENTITY_MARKER_VERSION: "1";
|
|
135
|
+
export interface TemplateIdentityMarker {
|
|
136
|
+
readonly version: string;
|
|
137
|
+
readonly kind: ArtifactKind;
|
|
138
|
+
readonly path: string;
|
|
139
|
+
}
|
|
140
|
+
export type TemplateIdentityMarkerStatus = "absent" | "valid" | "malformed" | "unsupported-version";
|
|
141
|
+
export interface TemplateIdentityMarkerExtraction {
|
|
142
|
+
readonly status: TemplateIdentityMarkerStatus;
|
|
143
|
+
readonly marker?: TemplateIdentityMarker;
|
|
144
|
+
/** Body with a recognized trailing marker line removed; unchanged when none is present. */
|
|
145
|
+
readonly body: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Recognize and remove a trailing template identity marker line without
|
|
149
|
+
* applying semantic parsing. Only a line starting with the exact reserved
|
|
150
|
+
* marker prefix is treated as a marker attempt at all; ordinary trailing
|
|
151
|
+
* HTML comments (e.g. PR template scaffolding) are left untouched here and
|
|
152
|
+
* handled by the existing comment-stripping path. Once the reserved prefix
|
|
153
|
+
* is detected, the line is never silently ignored as "absent" again: an
|
|
154
|
+
* oversized, truncated, or otherwise broken marker attempt fails closed as
|
|
155
|
+
* "malformed" instead of falling through to structural matching.
|
|
156
|
+
*/
|
|
157
|
+
export declare function extractTemplateIdentityMarker(body: string): TemplateIdentityMarkerExtraction;
|
|
85
158
|
export interface FetchedExistingArtifact {
|
|
86
159
|
readonly number: number;
|
|
87
160
|
readonly url: string;
|
|
@@ -89,6 +162,41 @@ export interface FetchedExistingArtifact {
|
|
|
89
162
|
}
|
|
90
163
|
/** Parse the documented JSON input envelope while keeping field semantics adapter-independent. */
|
|
91
164
|
export declare function parseArtifactInputDocument(input: unknown): ArtifactInputDocument;
|
|
165
|
+
/** Adapt a parsed JSON envelope without granting it canonical status. */
|
|
166
|
+
export declare function adaptJsonArtifactCandidate(input: unknown): ArtifactCandidate;
|
|
167
|
+
/** Adapt internal structured fields to the same candidate shape as JSON. */
|
|
168
|
+
export declare function adaptFieldArtifactCandidate(fields: unknown, metadata?: ArtifactInputMetadata): ArtifactCandidate;
|
|
169
|
+
/** Alias used by command adapters that call this input the CLI field path. */
|
|
170
|
+
export declare const adaptCliFieldCandidate: typeof adaptFieldArtifactCandidate;
|
|
171
|
+
/** Generic adapter spelling for callers that already hold structured fields. */
|
|
172
|
+
export declare const adaptArtifactCandidate: typeof adaptFieldArtifactCandidate;
|
|
173
|
+
/** Adapt an existing native artifact body through the repository parser. */
|
|
174
|
+
export declare function adaptMarkdownArtifactCandidate(contractInput: unknown, body: string | null | undefined): ArtifactCandidateAdapterResult;
|
|
175
|
+
/** Existing GitHub bodies use the same native Markdown adapter by design. */
|
|
176
|
+
export declare function adaptExistingArtifactCandidate(contractInput: unknown, body: string | null | undefined): ArtifactCandidateAdapterResult;
|
|
177
|
+
/**
|
|
178
|
+
* Reload a candidate against the selected canonical contract. Complete input
|
|
179
|
+
* takes the normal one-pass validator (and therefore may materialize contract
|
|
180
|
+
* defaults); incomplete/invalid input uses the bounded partial contract and
|
|
181
|
+
* exposes only accepted semantic values.
|
|
182
|
+
*/
|
|
183
|
+
export declare function loadCanonicalArtifact(contractInput: unknown, candidateInput: unknown): CanonicalArtifactLoadResult;
|
|
184
|
+
/** Explicitly named alias for callers that pass a candidate object. */
|
|
185
|
+
export declare const loadCanonicalCandidate: typeof loadCanonicalArtifact;
|
|
186
|
+
/** Load a JSON representation through the canonical contract boundary. */
|
|
187
|
+
export declare function loadCanonicalJsonArtifact(contractInput: unknown, input: unknown): CanonicalArtifactLoadResult;
|
|
188
|
+
/** Load native Markdown through the same parser and canonical contract. */
|
|
189
|
+
export declare function loadCanonicalMarkdownArtifact(contractInput: unknown, body: string | null | undefined): CanonicalArtifactLoadResult;
|
|
190
|
+
/** Existing-body spelling retained so read/repair callers share one boundary. */
|
|
191
|
+
export declare function loadCanonicalExistingArtifact(contractInput: unknown, body: string | null | undefined): CanonicalArtifactLoadResult;
|
|
192
|
+
/** Classify an artifact input envelope without applying semantic defaults. */
|
|
193
|
+
export declare function validatePartialArtifactInput(contractInput: unknown, input: unknown): PartialSemanticValidationResult;
|
|
194
|
+
/** Terminology alias for callers that treat validation as classification. */
|
|
195
|
+
export declare const classifyPartialArtifactInput: typeof validatePartialArtifactInput;
|
|
196
|
+
/** Merge only a targeted field patch into a prior stateless partial result. */
|
|
197
|
+
export declare function repairPartialArtifactInput(contractInput: unknown, previous: unknown, patch?: unknown): PartialSemanticRepairResult;
|
|
198
|
+
/** Terminology alias for callers that describe targeted repair as a merge. */
|
|
199
|
+
export declare const mergePartialArtifactInput: typeof repairPartialArtifactInput;
|
|
92
200
|
export declare function renderIssueArtifact(contractInput: unknown, input: unknown): string;
|
|
93
201
|
export declare function renderPullRequestArtifact(contractInput: unknown, input: unknown): string;
|
|
94
202
|
/** Construct the only values accepted by the GitHub mutation adapter. */
|
|
@@ -96,6 +204,14 @@ export declare function prepareIssueArtifact(contractInput: unknown, input: Arti
|
|
|
96
204
|
export declare function preparePullRequestArtifact(contractInput: unknown, input: ArtifactInputDocument): PreparedPullRequestArtifact;
|
|
97
205
|
export declare function parseExistingIssueArtifact(contractInput: unknown, body: string | null | undefined): ExistingArtifactParseResult;
|
|
98
206
|
export declare function parseExistingPullRequestArtifact(contractInput: unknown, body: string | null | undefined): ExistingArtifactParseResult;
|
|
207
|
+
/**
|
|
208
|
+
* Recover field values from a malformed or wrong-template body without
|
|
209
|
+
* weakening the strict existing-artifact parser. The section boundaries and
|
|
210
|
+
* field decoding are the same parser primitives used by strict parsing; only
|
|
211
|
+
* the order/complete-structure requirement is relaxed for an explicitly
|
|
212
|
+
* selected repair target.
|
|
213
|
+
*/
|
|
214
|
+
export declare function recoverExistingArtifactValues(contractInput: unknown, body: string | null | undefined): RecoverableArtifactValues;
|
|
99
215
|
export declare function validateExistingIssueArtifact(contractInput: unknown, body: string | null | undefined): ExistingArtifactValidationResult;
|
|
100
216
|
export declare function validateExistingPullRequestArtifact(contractInput: unknown, body: string | null | undefined): ExistingArtifactValidationResult;
|
|
101
217
|
export interface ExistingArtifactCandidate {
|