@jeger-ai/opengantry 3.0.1 → 3.1.1
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/LICENSE +10 -27
- package/README.md +64 -16
- package/dist/cli/commands/attest.d.ts +8 -0
- package/dist/cli/commands/attest.d.ts.map +1 -0
- package/dist/cli/commands/attest.js +20 -0
- package/dist/cli/commands/attest.js.map +1 -0
- package/dist/cli/commands/check-imports.d.ts.map +1 -1
- package/dist/cli/commands/check-imports.js +4 -7
- package/dist/cli/commands/check-imports.js.map +1 -1
- package/dist/cli/commands/context-feed.d.ts.map +1 -1
- package/dist/cli/commands/context-feed.js +7 -10
- package/dist/cli/commands/context-feed.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +4 -2
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +3 -2
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/metrics.d.ts.map +1 -1
- package/dist/cli/commands/metrics.js +5 -8
- package/dist/cli/commands/metrics.js.map +1 -1
- package/dist/cli/commands/pin.d.ts +6 -0
- package/dist/cli/commands/pin.d.ts.map +1 -0
- package/dist/cli/commands/pin.js +31 -0
- package/dist/cli/commands/pin.js.map +1 -0
- package/dist/cli/commands/receipt.d.ts +11 -0
- package/dist/cli/commands/receipt.d.ts.map +1 -0
- package/dist/cli/commands/receipt.js +45 -0
- package/dist/cli/commands/receipt.js.map +1 -0
- package/dist/cli/commands/runtime.d.ts +1 -1
- package/dist/cli/commands/runtime.d.ts.map +1 -1
- package/dist/cli/commands/runtime.js +20 -26
- package/dist/cli/commands/runtime.js.map +1 -1
- package/dist/cli/commands/scan.d.ts.map +1 -1
- package/dist/cli/commands/scan.js +17 -15
- package/dist/cli/commands/scan.js.map +1 -1
- package/dist/cli/commands/tmvc-guard.d.ts.map +1 -1
- package/dist/cli/commands/tmvc-guard.js +8 -15
- package/dist/cli/commands/tmvc-guard.js.map +1 -1
- package/dist/cli/commands/verify.d.ts.map +1 -1
- package/dist/cli/commands/verify.js +1 -6
- package/dist/cli/commands/verify.js.map +1 -1
- package/dist/cli/lib/attest-mission.d.ts +17 -0
- package/dist/cli/lib/attest-mission.d.ts.map +1 -0
- package/dist/cli/lib/attest-mission.js +23 -0
- package/dist/cli/lib/attest-mission.js.map +1 -0
- package/dist/cli/lib/attestation-receipt.d.ts +40 -0
- package/dist/cli/lib/attestation-receipt.d.ts.map +1 -0
- package/dist/cli/lib/attestation-receipt.js +110 -0
- package/dist/cli/lib/attestation-receipt.js.map +1 -0
- package/dist/cli/lib/canonical-json.d.ts +3 -0
- package/dist/cli/lib/canonical-json.d.ts.map +1 -0
- package/dist/cli/lib/canonical-json.js +13 -0
- package/dist/cli/lib/canonical-json.js.map +1 -0
- package/dist/cli/lib/command-boundary.d.ts +18 -0
- package/dist/cli/lib/command-boundary.d.ts.map +1 -1
- package/dist/cli/lib/command-boundary.js +50 -4
- package/dist/cli/lib/command-boundary.js.map +1 -1
- package/dist/cli/lib/constants.d.ts +2 -0
- package/dist/cli/lib/constants.d.ts.map +1 -1
- package/dist/cli/lib/constants.js +2 -0
- package/dist/cli/lib/constants.js.map +1 -1
- package/dist/cli/lib/doctor-core.d.ts +1 -1
- package/dist/cli/lib/doctor-core.d.ts.map +1 -1
- package/dist/cli/lib/doctor-core.js +25 -3
- package/dist/cli/lib/doctor-core.js.map +1 -1
- package/dist/cli/lib/draft-token.d.ts +1 -2
- package/dist/cli/lib/draft-token.d.ts.map +1 -1
- package/dist/cli/lib/draft-token.js +2 -12
- package/dist/cli/lib/draft-token.js.map +1 -1
- package/dist/cli/lib/errors.d.ts +1 -0
- package/dist/cli/lib/errors.d.ts.map +1 -1
- package/dist/cli/lib/errors.js +3 -0
- package/dist/cli/lib/errors.js.map +1 -1
- package/dist/cli/lib/flight-telemetry-doctor.d.ts +3 -0
- package/dist/cli/lib/flight-telemetry-doctor.d.ts.map +1 -0
- package/dist/cli/lib/flight-telemetry-doctor.js +25 -0
- package/dist/cli/lib/flight-telemetry-doctor.js.map +1 -0
- package/dist/cli/lib/gxt-config.d.ts +11 -0
- package/dist/cli/lib/gxt-config.d.ts.map +1 -1
- package/dist/cli/lib/gxt-config.js +10 -0
- package/dist/cli/lib/gxt-config.js.map +1 -1
- package/dist/cli/lib/gxt-error-codes.d.ts.map +1 -1
- package/dist/cli/lib/gxt-error-codes.js +3 -0
- package/dist/cli/lib/gxt-error-codes.js.map +1 -1
- package/dist/cli/lib/kpi-advisory-findings.d.ts +5 -0
- package/dist/cli/lib/kpi-advisory-findings.d.ts.map +1 -0
- package/dist/cli/lib/kpi-advisory-findings.js +16 -0
- package/dist/cli/lib/kpi-advisory-findings.js.map +1 -0
- package/dist/cli/lib/kpi-engine.d.ts +2 -1
- package/dist/cli/lib/kpi-engine.d.ts.map +1 -1
- package/dist/cli/lib/kpi-engine.js +36 -20
- package/dist/cli/lib/kpi-engine.js.map +1 -1
- package/dist/cli/lib/kpi-scan.d.ts.map +1 -1
- package/dist/cli/lib/kpi-scan.js +4 -3
- package/dist/cli/lib/kpi-scan.js.map +1 -1
- package/dist/cli/lib/mcp-attest.d.ts +6 -0
- package/dist/cli/lib/mcp-attest.d.ts.map +1 -0
- package/dist/cli/lib/mcp-attest.js +22 -0
- package/dist/cli/lib/mcp-attest.js.map +1 -0
- package/dist/cli/lib/mcp-governance-shared.d.ts +2 -0
- package/dist/cli/lib/mcp-governance-shared.d.ts.map +1 -1
- package/dist/cli/lib/mcp-governance-shared.js +10 -0
- package/dist/cli/lib/mcp-governance-shared.js.map +1 -1
- package/dist/cli/lib/mcp-pin-mission.d.ts.map +1 -1
- package/dist/cli/lib/mcp-pin-mission.js +10 -10
- package/dist/cli/lib/mcp-pin-mission.js.map +1 -1
- package/dist/cli/lib/mcp-start-orchestration.d.ts.map +1 -1
- package/dist/cli/lib/mcp-start-orchestration.js +8 -4
- package/dist/cli/lib/mcp-start-orchestration.js.map +1 -1
- package/dist/cli/lib/mcp-tools-register.d.ts.map +1 -1
- package/dist/cli/lib/mcp-tools-register.js +13 -0
- package/dist/cli/lib/mcp-tools-register.js.map +1 -1
- package/dist/cli/lib/mission-arg.d.ts +18 -0
- package/dist/cli/lib/mission-arg.d.ts.map +1 -0
- package/dist/cli/lib/mission-arg.js +45 -0
- package/dist/cli/lib/mission-arg.js.map +1 -0
- package/dist/cli/lib/missions/parser.d.ts +4 -0
- package/dist/cli/lib/missions/parser.d.ts.map +1 -1
- package/dist/cli/lib/missions/parser.js +16 -0
- package/dist/cli/lib/missions/parser.js.map +1 -1
- package/dist/cli/lib/policy-digest-doctor.d.ts +11 -0
- package/dist/cli/lib/policy-digest-doctor.d.ts.map +1 -0
- package/dist/cli/lib/policy-digest-doctor.js +37 -0
- package/dist/cli/lib/policy-digest-doctor.js.map +1 -0
- package/dist/cli/lib/receipt-inspect.d.ts +27 -0
- package/dist/cli/lib/receipt-inspect.d.ts.map +1 -0
- package/dist/cli/lib/receipt-inspect.js +104 -0
- package/dist/cli/lib/receipt-inspect.js.map +1 -0
- package/dist/cli/lib/receipt-signing.d.ts +12 -0
- package/dist/cli/lib/receipt-signing.d.ts.map +1 -0
- package/dist/cli/lib/receipt-signing.js +150 -0
- package/dist/cli/lib/receipt-signing.js.map +1 -0
- package/dist/cli/lib/runtime-exec.d.ts +1 -0
- package/dist/cli/lib/runtime-exec.d.ts.map +1 -1
- package/dist/cli/lib/runtime-exec.js +21 -17
- package/dist/cli/lib/runtime-exec.js.map +1 -1
- package/dist/cli/lib/types.d.ts +1 -0
- package/dist/cli/lib/types.d.ts.map +1 -1
- package/dist/cli/lib/verify-context.d.ts +15 -0
- package/dist/cli/lib/verify-context.d.ts.map +1 -0
- package/dist/cli/lib/verify-context.js +2 -0
- package/dist/cli/lib/verify-context.js.map +1 -0
- package/dist/cli/lib/verify-engine.d.ts +2 -1
- package/dist/cli/lib/verify-engine.d.ts.map +1 -1
- package/dist/cli/lib/verify-engine.js +13 -2
- package/dist/cli/lib/verify-engine.js.map +1 -1
- package/dist/cli/lib/verify-options.d.ts +4 -2
- package/dist/cli/lib/verify-options.d.ts.map +1 -1
- package/dist/cli/lib/verify-options.js +1 -12
- package/dist/cli/lib/verify-options.js.map +1 -1
- package/dist/cli/lib/verify-payload.d.ts +8 -2
- package/dist/cli/lib/verify-payload.d.ts.map +1 -1
- package/dist/cli/lib/verify-payload.js +7 -3
- package/dist/cli/lib/verify-payload.js.map +1 -1
- package/dist/cli/lib/verify-presenters.d.ts +29 -16
- package/dist/cli/lib/verify-presenters.d.ts.map +1 -1
- package/dist/cli/lib/verify-presenters.js +69 -66
- package/dist/cli/lib/verify-presenters.js.map +1 -1
- package/dist/cli/lib/verify-receipt.d.ts +11 -0
- package/dist/cli/lib/verify-receipt.d.ts.map +1 -0
- package/dist/cli/lib/verify-receipt.js +40 -0
- package/dist/cli/lib/verify-receipt.js.map +1 -0
- package/dist/cli/lib/verify-run.d.ts +1 -0
- package/dist/cli/lib/verify-run.d.ts.map +1 -1
- package/dist/cli/lib/verify-run.js +86 -25
- package/dist/cli/lib/verify-run.js.map +1 -1
- package/dist/cli/lib/version.gen.d.ts +1 -1
- package/dist/cli/lib/version.gen.js +1 -1
- package/dist/cli/lib/working-digests.d.ts +8 -0
- package/dist/cli/lib/working-digests.d.ts.map +1 -0
- package/dist/cli/lib/working-digests.js +21 -0
- package/dist/cli/lib/working-digests.js.map +1 -0
- package/dist/cli/program-core.d.ts.map +1 -1
- package/dist/cli/program-core.js +37 -2
- package/dist/cli/program-core.js.map +1 -1
- package/dist/cli/program-mission.js +1 -1
- package/dist/cli/program-mission.js.map +1 -1
- package/dist/cli/program-workflow.d.ts.map +1 -1
- package/dist/cli/program-workflow.js +23 -2
- package/dist/cli/program-workflow.js.map +1 -1
- package/package.json +2 -2
- package/templates/.gitagent/config.json +3 -0
- package/templates/.gitagent/foreman/SUBSTRATE.version.json +1 -1
- package/templates/.gitagent/planner/KPI-REPORT.schema.yaml +4 -0
- package/templates/.gitagent/planner/PERFORMANCE.md +18 -0
- package/templates/.gitagent/planner/PERFORMANCE_RUBRIC.template.md +32 -0
- package/templates/.githooks/pre-push +5 -5
- package/templates/.github/workflows/gxt-validate.yml +7 -4
- package/templates/integrations/compatibility.json +52 -16
- package/templates/scripts/gxt-pin-mission.sh +15 -2
- package/templates/scripts/gxt-runtime-env.sh +12 -6
- package/templates/scripts/lib/trusted-automation.mjs +56 -9
- package/templates/scripts/verify-pr-missions.sh +3 -3
package/LICENSE
CHANGED
|
@@ -203,33 +203,16 @@
|
|
|
203
203
|
|
|
204
204
|
END OF TERMS AND CONDITIONS
|
|
205
205
|
|
|
206
|
+
Copyright 2026 Juergen Eger
|
|
206
207
|
|
|
207
|
-
|
|
208
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
209
|
+
you may not use this file except in compliance with the License.
|
|
210
|
+
You may obtain a copy of the License at
|
|
208
211
|
|
|
212
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
209
213
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
file or class name and description of purpose be included on the
|
|
216
|
-
same "printed page" as the copyright notice for easier
|
|
217
|
-
identification within third-party archives.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
Copyright [yyyy] [name of copyright owner]
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
224
|
-
you may not use this file except in compliance with the License.
|
|
225
|
-
You may obtain a copy of the License at
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
Unless required by applicable law or agreed to in writing, software
|
|
232
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
233
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
234
|
-
See the License for the specific language governing permissions and
|
|
235
|
-
limitations under the License.
|
|
214
|
+
Unless required by applicable law or agreed to in writing, software
|
|
215
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
216
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
217
|
+
See the License for the specific language governing permissions and
|
|
218
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -6,11 +6,56 @@
|
|
|
6
6
|
|
|
7
7
|
## The one-line pitch
|
|
8
8
|
|
|
9
|
-
**OpenGantry is a local-first,
|
|
9
|
+
**OpenGantry is the deterministic runtime and governance engine for AI agents.** It is a local-first CLI that scopes agent edits, runs your shell gates, and returns structured failure JSON so agents can retry without a human watching the terminal. It does not write your code or content for you. It replaces humans babysitting AI coding assistants — not your tests, not your CI, not your code review.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
> **Not [Gantry.io](https://gantry.io)?** OpenGantry is the open-source **`gantry` CLI** for local-first, Git-native agent enforcement in your repository, not a hosted observability dashboard. Product home: [opengantry.ai](https://opengantry.ai).
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
### Local control, unmonitored loops, tamper-evident proof
|
|
14
|
+
|
|
15
|
+
Three engineering problems show up today, calendar or no calendar:
|
|
16
|
+
|
|
17
|
+
| Problem | What goes wrong | OpenGantry answer |
|
|
18
|
+
|---------|-----------------|-------------------|
|
|
19
|
+
| **Local developer control** | Source and credentials leave the machine for a vendor console to "govern" agents | Execution stays on-machine; verify is offline; optional future hub is digests only |
|
|
20
|
+
| **Unmonitored agent loops** | Agents thrash on unstructured stderr, wander outside declared paths, or keep retrying without a structured verdict | Mission YAML + TMVC + `findings[]` so the loop is scoped and machine-readable |
|
|
21
|
+
| **Tamper-evident auditability** | "It passed locally" with no citeable trail | Planner stamps, `EXECUTOR_LOG.md` quotes, optional SSH/GPG attestation receipts |
|
|
22
|
+
|
|
23
|
+
**Hybrid model:** free local CLI (spoke) for developers; optional metadata plane (hub) later for team-wide audit aggregation. Source trees and gate stdout never leave via GXT export paths.
|
|
24
|
+
|
|
25
|
+
Deep dive: [`docs/SECURITY.md`](docs/SECURITY.md) · [`docs/FEATURES.md`](docs/FEATURES.md) · [opengantry.ai](https://opengantry.ai)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## In plain English
|
|
30
|
+
|
|
31
|
+
OpenGantry uses product terms that sound abstract. Here is what the CLI actually runs:
|
|
32
|
+
|
|
33
|
+
| Term you will see | What it actually is |
|
|
34
|
+
|-------------------|---------------------|
|
|
35
|
+
| **Contract** | Mission YAML under `.gitagent/missions/` — allowed paths, forbidden paths, and a required `gate_command` (shell) |
|
|
36
|
+
| **Legislate** | `gantry legislate` / Mission Architect writes that YAML; a Planner commit locks it in Git before work |
|
|
37
|
+
| **Governance** | Hooks + `gantry verify` that fail closed if scope or gates are violated — not a process committee |
|
|
38
|
+
| **Verdict** | Deterministic pass/fail from shell gates + trace checks; on fail, a `findings[]` JSON envelope |
|
|
39
|
+
|
|
40
|
+
**"Contract" is not design-by-contract (DbC).** It is not pre/post conditions in source code. It is the Git-locked work order that tells the agent where it may edit and which shell command must pass before merge.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Why not just TDD and CI?
|
|
45
|
+
|
|
46
|
+
You already have `npm test` and GitHub Actions. OpenGantry does not replace them — it makes them usable when an **AI agent** runs the loop.
|
|
47
|
+
|
|
48
|
+
| Who runs the loop | What happens on failure |
|
|
49
|
+
|-------------------|-------------------------|
|
|
50
|
+
| **Human developer** | Reads stderr, parses the stack trace, rewrites code |
|
|
51
|
+
| **AI agent + raw TDD/CI** | Chokes on unstructured stderr, hallucinates fixes, spins in retry loops — a senior still babysits |
|
|
52
|
+
| **AI agent + OpenGantry** | Same gates you already trust; `gantry verify --json` returns `findings[]` with file, line, and hint so the agent can self-correct |
|
|
53
|
+
|
|
54
|
+
| Already have | Still missing for autonomous agents | OpenGantry adds |
|
|
55
|
+
|--------------|-------------------------------------|-----------------|
|
|
56
|
+
| `npm test` / GH Actions | Structured failure for model retry | `findings[]` envelope |
|
|
57
|
+
| PR CI | Declared edit blast radius | TMVC + forbidden zones in mission YAML |
|
|
58
|
+
| Code review | Proof the agent stayed in scope | Git mission + `EXECUTOR_LOG.md` quotes |
|
|
14
59
|
|
|
15
60
|
---
|
|
16
61
|
|
|
@@ -21,9 +66,9 @@ Most AI agent tooling optimizes for *speed of generation*. OpenGantry optimizes
|
|
|
21
66
|
- **Scope before execution:** no silent edits to governance files, no wandering outside approved paths
|
|
22
67
|
- **Deterministic verification:** gates are shell commands with pass/fail outcomes, not LLM opinions
|
|
23
68
|
- **Forensic trace:** every mission ties to `[MSN-XXXX]` commits and verbatim quotes in `EXECUTOR_LOG.md`
|
|
24
|
-
- **Domain-agnostic
|
|
69
|
+
- **Domain-agnostic:** the same loop governs TypeScript imports *and* brand/compliance copy
|
|
25
70
|
|
|
26
|
-
The long-term bet: external executors (Cursor agents, Hermes, CI bots) do the work; **OpenGantry owns the
|
|
71
|
+
The long-term bet: external executors (Cursor agents, Hermes, CI bots) do the work; **OpenGantry owns the mission YAML and the verify output**. That separation is what makes agentic delivery auditable in regulated or security-sensitive environments.
|
|
27
72
|
|
|
28
73
|
---
|
|
29
74
|
|
|
@@ -47,7 +92,7 @@ Everything revolves around a **mission**:
|
|
|
47
92
|
|
|
48
93
|
```mermaid
|
|
49
94
|
flowchart LR
|
|
50
|
-
A[Planner
|
|
95
|
+
A[Planner commits mission YAML] --> B[Executor works in TMVC scope]
|
|
51
96
|
B --> C[Trace in EXECUTOR_LOG.md]
|
|
52
97
|
C --> D[gantry verify]
|
|
53
98
|
D -->|fail| E[findings JSON → agent retries]
|
|
@@ -56,7 +101,7 @@ flowchart LR
|
|
|
56
101
|
|
|
57
102
|
**Roles:**
|
|
58
103
|
|
|
59
|
-
- **Planner:** human (or Mission Architect in chat)
|
|
104
|
+
- **Planner:** human (or Mission Architect in chat) commits mission YAML via `gantry legislate` before execution
|
|
60
105
|
- **Executor:** agent or developer edits within TMVC roots; forbidden zones respected
|
|
61
106
|
- **Verifier:** `gantry verify` checks gate output and trace mapping
|
|
62
107
|
|
|
@@ -72,9 +117,9 @@ flowchart LR
|
|
|
72
117
|
|
|
73
118
|
---
|
|
74
119
|
|
|
75
|
-
##
|
|
120
|
+
## Three phases, any domain
|
|
76
121
|
|
|
77
|
-
|
|
122
|
+
OpenGantry is a **domain-neutral verify loop**, not just a TypeScript linter:
|
|
78
123
|
|
|
79
124
|
| Phase | Command | Output |
|
|
80
125
|
|-------|---------|--------|
|
|
@@ -91,7 +136,7 @@ v3.0.0 reframes the product as a **universal governance layer**, not just a Type
|
|
|
91
136
|
|
|
92
137
|
List them: `gantry domains`
|
|
93
138
|
|
|
94
|
-
**
|
|
139
|
+
**Binary enforcement:** pass/fail only — no LLM opinions at the gate. Content discovery uses exact-match boilerplate only; it does not infer "dominant terminology" from statistics that would flip on unrelated edits.
|
|
95
140
|
|
|
96
141
|
See [`docs/DOMAINS.md`](docs/DOMAINS.md) for adapter details and [`docs/AGENT-LOOP.md`](docs/AGENT-LOOP.md) for external executor integration.
|
|
97
142
|
|
|
@@ -119,7 +164,7 @@ Emits a proposal with evidence-anchored conventions and anomalies (`file:line` s
|
|
|
119
164
|
|
|
120
165
|
**Speed:** the discovery scanner uses streaming regex per file, not a whole-repo AST. It is budgeted to finish a **5,000-file monorepo in under five seconds** (pinned in CI). OpenGantry ingests repository context in seconds without loading the tree into a heavy compiler graph or spiking RAM. Enterprise teams do not have to wait minutes for a governance tool to "understand" the repo before the agent loop starts.
|
|
121
166
|
|
|
122
|
-
### 3. Blueprint:
|
|
167
|
+
### 3. Blueprint: lock rules and gate commands
|
|
123
168
|
|
|
124
169
|
```bash
|
|
125
170
|
gantry blueprint --domain content --yes
|
|
@@ -189,14 +234,14 @@ See [`examples/content-governance/`](examples/content-governance/). Ad copy with
|
|
|
189
234
|
|
|
190
235
|
- **Not an agent:** it does not chat, plan features, or generate PRs by itself
|
|
191
236
|
- **Not Gantry.io:** no hosted observability dashboard; everything runs in your repo
|
|
192
|
-
- **Not an LLM judge
|
|
237
|
+
- **Not an LLM judge for merge:** gates stay deterministic; optional LLM evidence is committed separately via `gantry scan`
|
|
193
238
|
|
|
194
239
|
---
|
|
195
240
|
|
|
196
241
|
## Mental model for adopters
|
|
197
242
|
|
|
198
243
|
```
|
|
199
|
-
OpenGantry =
|
|
244
|
+
OpenGantry = scoped work order + shell gates + structured verify output
|
|
200
245
|
Executor agent = worker (Cursor, Hermes, human dev)
|
|
201
246
|
```
|
|
202
247
|
|
|
@@ -206,15 +251,18 @@ You adopt OpenGantry when agent velocity is valuable but **unreviewed scope cree
|
|
|
206
251
|
|
|
207
252
|
## Documentation map {#documentation-map-start-here}
|
|
208
253
|
|
|
209
|
-
Full doc index: [`docs/index.md`](docs/index.md) —
|
|
254
|
+
Full doc index: [`docs/index.md`](docs/index.md) — organized by **how**, **what**, and **why**.
|
|
210
255
|
|
|
211
256
|
## Where to go next
|
|
212
257
|
|
|
213
258
|
| Goal | Doc |
|
|
214
259
|
|------|-----|
|
|
215
260
|
| All documentation | [`docs/index.md`](docs/index.md) |
|
|
216
|
-
|
|
|
217
|
-
|
|
|
261
|
+
| What it helps with | [`docs/USE-CASES.md`](docs/USE-CASES.md) |
|
|
262
|
+
| Why features exist | [`docs/FEATURES.md`](docs/FEATURES.md) |
|
|
263
|
+
| Adoption runbook | [`docs/ADOPTION.md`](docs/ADOPTION.md) |
|
|
264
|
+
| Release history | [`docs/CHANGELOG.md`](docs/CHANGELOG.md) |
|
|
265
|
+
| Domain adapters | [`docs/DOMAINS.md`](docs/DOMAINS.md) |
|
|
218
266
|
| External agent integration | [`docs/AGENT-LOOP.md`](docs/AGENT-LOOP.md) |
|
|
219
267
|
| Contributing / dogfooding this repo | [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) |
|
|
220
268
|
| Content walkthrough | [`examples/content-governance/`](examples/content-governance/) |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attest.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/attest.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAYtD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { logInfo } from "../lib/cli-io.js";
|
|
2
|
+
import { attestMission } from "../lib/attest-mission.js";
|
|
3
|
+
import { emitCliJson, runUserCommand } from "../lib/command-boundary.js";
|
|
4
|
+
import { emitPinnedMissionBanner, resolveMissionArg } from "../lib/mission-arg.js";
|
|
5
|
+
import { loadWorkspace } from "../lib/workspace.js";
|
|
6
|
+
export function runAttest(options) {
|
|
7
|
+
runUserCommand({ json: options.json }, () => {
|
|
8
|
+
const { root } = loadWorkspace();
|
|
9
|
+
const resolved = resolveMissionArg(root, options.mission);
|
|
10
|
+
emitPinnedMissionBanner(resolved, { json: options.json });
|
|
11
|
+
const result = attestMission({ root, resolved, out: options.out, sign: options.sign });
|
|
12
|
+
if (options.json) {
|
|
13
|
+
emitCliJson({ status: "ok", ...result });
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
logInfo(`gantry attest: wrote ${result.receipt_path}`);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=attest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attest.js","sourceRoot":"","sources":["../../../src/cli/commands/attest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AASpD,MAAM,UAAU,SAAS,CAAC,OAAsB;IAC9C,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1D,uBAAuB,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACvF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,wBAAwB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-imports.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check-imports.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check-imports.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/check-imports.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CA2BlE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { findBannedImportsInFolder } from "../lib/ast-discovery.js";
|
|
2
2
|
import { logError, setExitCode } from "../lib/cli-io.js";
|
|
3
|
+
import { emitCliJson, runUserCommand } from "../lib/command-boundary.js";
|
|
3
4
|
import { loadWorkspace } from "../lib/workspace.js";
|
|
4
5
|
export function runCheckImports(options) {
|
|
5
6
|
if (options.ban.length === 0) {
|
|
@@ -7,11 +8,11 @@ export function runCheckImports(options) {
|
|
|
7
8
|
setExitCode(2);
|
|
8
9
|
return;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
runUserCommand({ json: options.json }, () => {
|
|
11
12
|
const { root } = loadWorkspace();
|
|
12
13
|
const violations = findBannedImportsInFolder(root, options.dir, options.ban);
|
|
13
14
|
if (options.json) {
|
|
14
|
-
|
|
15
|
+
emitCliJson({ ok: violations.length === 0, violations });
|
|
15
16
|
if (violations.length > 0)
|
|
16
17
|
setExitCode(1);
|
|
17
18
|
return;
|
|
@@ -24,10 +25,6 @@ export function runCheckImports(options) {
|
|
|
24
25
|
process.stderr.write(`${v.file}: banned import "${v.specifier}"\n`);
|
|
25
26
|
}
|
|
26
27
|
setExitCode(1);
|
|
27
|
-
}
|
|
28
|
-
catch (e) {
|
|
29
|
-
logError(e instanceof Error ? e.message : String(e));
|
|
30
|
-
setExitCode(1);
|
|
31
|
-
}
|
|
28
|
+
});
|
|
32
29
|
}
|
|
33
30
|
//# sourceMappingURL=check-imports.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-imports.js","sourceRoot":"","sources":["../../../src/cli/commands/check-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,UAAU,eAAe,CAAC,OAA4B;IAC1D,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,QAAQ,CAAC,4DAA4D,CAAC,CAAC;QACvE,WAAW,CAAC,CAAC,CAAC,CAAC;QACf,OAAO;IACT,CAAC;IAED,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"check-imports.js","sourceRoot":"","sources":["../../../src/cli/commands/check-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,UAAU,eAAe,CAAC,OAA4B;IAC1D,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,QAAQ,CAAC,4DAA4D,CAAC,CAAC;QACvE,WAAW,CAAC,CAAC,CAAC,CAAC;QACf,OAAO;IACT,CAAC;IAED,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAE7E,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,WAAW,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YACzD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;gBAAE,WAAW,CAAC,CAAC,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC;QACtE,CAAC;QACD,WAAW,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-feed.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/context-feed.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context-feed.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/context-feed.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,kBAAuB,GAAG,IAAI,CAsCrE"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logInfo } from "../lib/cli-io.js";
|
|
2
|
+
import { emitCliJson, runUserCommand } from "../lib/command-boundary.js";
|
|
2
3
|
import { clearRemediationSnapshot, readRemediationSnapshot, } from "../lib/context-feed-store.js";
|
|
3
4
|
import { loadWorkspace } from "../lib/workspace.js";
|
|
4
5
|
export function runContextFeed(options = {}) {
|
|
5
|
-
|
|
6
|
+
runUserCommand({ json: options.json }, () => {
|
|
6
7
|
const { root } = loadWorkspace();
|
|
7
8
|
if (options.clear) {
|
|
8
9
|
clearRemediationSnapshot(root);
|
|
9
10
|
if (options.json) {
|
|
10
|
-
|
|
11
|
+
emitCliJson({ status: "cleared", path: ".gitagent/tmp/NEXT_REMEDIATION.json" });
|
|
11
12
|
}
|
|
12
13
|
else {
|
|
13
14
|
logInfo("context-feed: cleared");
|
|
@@ -17,7 +18,7 @@ export function runContextFeed(options = {}) {
|
|
|
17
18
|
const snapshot = readRemediationSnapshot(root);
|
|
18
19
|
if (!snapshot) {
|
|
19
20
|
if (options.json) {
|
|
20
|
-
|
|
21
|
+
emitCliJson({ status: "empty", snapshot: null });
|
|
21
22
|
}
|
|
22
23
|
else {
|
|
23
24
|
logInfo("context-feed: (no active remediation)");
|
|
@@ -25,7 +26,7 @@ export function runContextFeed(options = {}) {
|
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
28
|
if (options.json) {
|
|
28
|
-
|
|
29
|
+
emitCliJson({ status: "ok", snapshot });
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
logInfo(`context-feed: phase=${snapshot.phase} error=${snapshot.error_code}`);
|
|
@@ -39,10 +40,6 @@ export function runContextFeed(options = {}) {
|
|
|
39
40
|
for (const hint of snapshot.fix_hints)
|
|
40
41
|
logInfo(` - ${hint}`);
|
|
41
42
|
}
|
|
42
|
-
}
|
|
43
|
-
catch (e) {
|
|
44
|
-
logError(e instanceof Error ? e.message : String(e));
|
|
45
|
-
setExitCode(2);
|
|
46
|
-
}
|
|
43
|
+
});
|
|
47
44
|
}
|
|
48
45
|
//# sourceMappingURL=context-feed.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-feed.js","sourceRoot":"","sources":["../../../src/cli/commands/context-feed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"context-feed.js","sourceRoot":"","sources":["../../../src/cli/commands/context-feed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EACL,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOpD,MAAM,UAAU,cAAc,CAAC,UAA8B,EAAE;IAC7D,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QAEjC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,wBAAwB,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,qCAAqC,EAAE,CAAC,CAAC;YAClF,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,uBAAuB,CAAC,CAAC;YACnC,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,uCAAuC,CAAC,CAAC;YACnD,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,OAAO,CAAC,uBAAuB,QAAQ,CAAC,KAAK,UAAU,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,cAAc,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,iBAAiB;YAAE,OAAO,CAAC,cAAc,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACpF,IAAI,QAAQ,CAAC,MAAM;YAAE,OAAO,CAAC,aAAa,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,cAAc,CAAC,CAAC;YACxB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,SAAS;gBAAE,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -5,8 +5,10 @@ export interface DoctorReport {
|
|
|
5
5
|
next_step: string | null;
|
|
6
6
|
exit_code: number;
|
|
7
7
|
}
|
|
8
|
-
export
|
|
8
|
+
export interface DoctorOptions {
|
|
9
9
|
json?: boolean;
|
|
10
10
|
audience?: OutputAudience;
|
|
11
|
-
|
|
11
|
+
policy?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function runDoctor(options?: DoctorOptions): void;
|
|
12
14
|
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAA2C,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG5F,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA+BD,wBAAgB,SAAS,CAAC,OAAO,GAAE,aAAkB,GAAG,IAAI,CAe3D"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { logInfo, setExitCode, errorMessage } from "../lib/cli-io.js";
|
|
2
|
+
import { emitCliJson } from "../lib/command-boundary.js";
|
|
2
3
|
import { audienceSectionTitle, filterTaggedStepsForAudience, } from "../lib/audience-output.js";
|
|
3
4
|
import { doctorLinesHasFail, collectDoctorReport } from "../lib/doctor.js";
|
|
4
5
|
import { loadWorkspace } from "../lib/workspace.js";
|
|
5
6
|
function emitDoctor(lines, nextStep, hasFail, json, audience) {
|
|
6
7
|
const exitCode = hasFail ? 1 : 0;
|
|
7
8
|
if (json) {
|
|
8
|
-
|
|
9
|
+
emitCliJson({ lines, next_step: nextStep, exit_code: exitCode });
|
|
9
10
|
}
|
|
10
11
|
else {
|
|
11
12
|
for (const line of lines) {
|
|
@@ -28,7 +29,7 @@ function emitDoctor(lines, nextStep, hasFail, json, audience) {
|
|
|
28
29
|
export function runDoctor(options = {}) {
|
|
29
30
|
try {
|
|
30
31
|
const { root, manifest } = loadWorkspace();
|
|
31
|
-
const report = collectDoctorReport(root, manifest);
|
|
32
|
+
const report = collectDoctorReport(root, manifest, undefined, options.policy);
|
|
32
33
|
emitDoctor(report.lines, report.nextStep, doctorLinesHasFail(report.lines), options.json, options.audience);
|
|
33
34
|
}
|
|
34
35
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAE7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAmB,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAE7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAmB,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAcpD,SAAS,UAAU,CACjB,KAAmB,EACnB,QAAuB,EACvB,OAAgB,EAChB,IAAyB,EACzB,QAAyB;IAEzB,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,IAAI,EAAE,CAAC;QACT,WAAW,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,4BAA4B,CACxC,QAAQ,EACR,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAC3D,CAAC;QACF,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;YACvB,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,IAAI,OAAO;QAAE,WAAW,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,UAAyB,EAAE;IACnD,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,aAAa,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9E,UAAU,CACR,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,QAAQ,EACf,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,EAChC,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,QAAQ,CACjB,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC5B,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/metrics.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/metrics.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAWxD"}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
+
import { logInfo } from "../lib/cli-io.js";
|
|
2
|
+
import { emitCliJson, runUserCommand } from "../lib/command-boundary.js";
|
|
1
3
|
import { collectGitMetrics, formatGitMetricsHuman } from "../lib/git-metrics.js";
|
|
2
|
-
import { logError, logInfo, setExitCode, errorMessage } from "../lib/cli-io.js";
|
|
3
4
|
import { loadWorkspace } from "../lib/workspace.js";
|
|
4
5
|
export function runMetrics(options) {
|
|
5
|
-
|
|
6
|
+
runUserCommand({ json: options.json }, () => {
|
|
6
7
|
const { root } = loadWorkspace();
|
|
7
8
|
const ref = options.ref?.trim() || "HEAD";
|
|
8
9
|
const report = collectGitMetrics(root, ref);
|
|
9
10
|
if (options.json === true) {
|
|
10
|
-
|
|
11
|
+
emitCliJson(report);
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
13
14
|
logInfo(formatGitMetricsHuman(report));
|
|
14
|
-
}
|
|
15
|
-
catch (e) {
|
|
16
|
-
logError(errorMessage(e));
|
|
17
|
-
setExitCode(2);
|
|
18
|
-
}
|
|
15
|
+
});
|
|
19
16
|
}
|
|
20
17
|
//# sourceMappingURL=metrics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/cli/commands/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/cli/commands/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOpD,MAAM,UAAU,UAAU,CAAC,OAAuB;IAChD,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC;QAC1C,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC1B,WAAW,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QACD,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/pin.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAsBhD;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAa/B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { logInfo } from "../lib/cli-io.js";
|
|
2
|
+
import { runUserCommand } from "../lib/command-boundary.js";
|
|
3
|
+
import { GantryUserError } from "../lib/errors.js";
|
|
4
|
+
import { clearActiveMissionPin, pinActiveMission, readActiveMissionPin, } from "../lib/missions/parser.js";
|
|
5
|
+
import { loadWorkspace } from "../lib/workspace.js";
|
|
6
|
+
export function runPin(options) {
|
|
7
|
+
runUserCommand({ json: false }, () => {
|
|
8
|
+
const { root } = loadWorkspace();
|
|
9
|
+
const missionArg = options.mission?.trim();
|
|
10
|
+
if (!missionArg) {
|
|
11
|
+
const pinned = readActiveMissionPin(root);
|
|
12
|
+
if (!pinned) {
|
|
13
|
+
throw new GantryUserError("MISSION_REQUIRED", "gantry pin: no active mission pinned", "gantry pin .gitagent/missions/<file>.yaml", 1);
|
|
14
|
+
}
|
|
15
|
+
logInfo(pinned);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const rel = pinActiveMission(root, missionArg);
|
|
19
|
+
logInfo(`Pinned active mission: ${rel}`);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function runUnpin() {
|
|
23
|
+
runUserCommand({ json: false }, () => {
|
|
24
|
+
const { root } = loadWorkspace();
|
|
25
|
+
if (!clearActiveMissionPin(root)) {
|
|
26
|
+
throw new GantryUserError("MISSION_REQUIRED", "gantry unpin: no active mission pinned", undefined, 1);
|
|
27
|
+
}
|
|
28
|
+
logInfo("gantry unpin: cleared active mission pin");
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=pin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pin.js","sourceRoot":"","sources":["../../../src/cli/commands/pin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMpD,MAAM,UAAU,MAAM,CAAC,OAAmB;IACxC,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;QAE3C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,eAAe,CACvB,kBAAkB,EAClB,sCAAsC,EACtC,2CAA2C,EAC3C,CAAC,CACF,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC/C,OAAO,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACjC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,eAAe,CACvB,kBAAkB,EAClB,wCAAwC,EACxC,SAAS,EACT,CAAC,CACF,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,0CAA0C,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ReceiptListOptions {
|
|
2
|
+
msn?: string;
|
|
3
|
+
json?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface ReceiptShowOptions {
|
|
6
|
+
target?: string;
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function runReceiptList(options: ReceiptListOptions): void;
|
|
10
|
+
export declare function runReceiptShow(options: ReceiptShowOptions): void;
|
|
11
|
+
//# sourceMappingURL=receipt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/receipt.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAgBhE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAqBhE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { logInfo } from "../lib/cli-io.js";
|
|
2
|
+
import { emitCliJson, runUserCommand } from "../lib/command-boundary.js";
|
|
3
|
+
import { listReceipts, resolveReceiptPath, summarizeReceipt, } from "../lib/receipt-inspect.js";
|
|
4
|
+
import { loadWorkspace } from "../lib/workspace.js";
|
|
5
|
+
export function runReceiptList(options) {
|
|
6
|
+
runUserCommand({ json: options.json }, () => {
|
|
7
|
+
const { root } = loadWorkspace();
|
|
8
|
+
const entries = listReceipts(root, options.msn);
|
|
9
|
+
if (options.json) {
|
|
10
|
+
emitCliJson({ status: "ok", receipts: entries });
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (entries.length === 0) {
|
|
14
|
+
logInfo("gantry receipt list: (no receipts)");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
for (const e of entries) {
|
|
18
|
+
logInfo(`${e.path} ${e.msn_id} ${e.verify_status} ${e.receipt_sha256.slice(0, 12)}`);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function runReceiptShow(options) {
|
|
23
|
+
runUserCommand({ json: options.json }, () => {
|
|
24
|
+
const { root } = loadWorkspace();
|
|
25
|
+
const { relPath, receipt } = resolveReceiptPath(root, options.target);
|
|
26
|
+
const summary = summarizeReceipt(relPath, receipt);
|
|
27
|
+
if (options.json) {
|
|
28
|
+
emitCliJson({ status: "ok", receipt: summary, raw: receipt });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
logInfo(`gantry receipt show: ${summary.path}`);
|
|
32
|
+
logInfo(` msn_id: ${summary.msn_id}`);
|
|
33
|
+
logInfo(` verify_status: ${summary.verify_status}`);
|
|
34
|
+
logInfo(` receipt_sha256: ${summary.receipt_sha256}`);
|
|
35
|
+
logInfo(` mission_rel: ${summary.mission_rel}`);
|
|
36
|
+
logInfo(` git_head: ${summary.git_head}`);
|
|
37
|
+
logInfo(` issued_at: ${summary.issued_at}`);
|
|
38
|
+
if (summary.error_code)
|
|
39
|
+
logInfo(` error_code: ${summary.error_code}`);
|
|
40
|
+
if (summary.signature_verify_status) {
|
|
41
|
+
logInfo(` signature.verify_status: ${summary.signature_verify_status}`);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=receipt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipt.js","sourceRoot":"","sources":["../../../src/cli/commands/receipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAYpD,MAAM,UAAU,cAAc,CAAC,OAA2B;IACxD,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,oCAAoC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAA2B;IACxD,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE;QAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QACD,OAAO,CAAC,wBAAwB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,aAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,oBAAoB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,qBAAqB,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,kBAAkB,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,eAAe,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,gBAAgB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QAC7C,IAAI,OAAO,CAAC,UAAU;YAAE,OAAO,CAAC,iBAAiB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QACvE,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;YACpC,OAAO,CAAC,8BAA8B,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/runtime.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAMD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CA8BjE;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDzF"}
|