@vyuhlabs/dxkit 2.11.1 → 2.13.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/CHANGELOG.md +67 -0
- package/README.md +192 -279
- package/dist/baseline/check.d.ts +7 -0
- package/dist/baseline/check.d.ts.map +1 -1
- package/dist/baseline/check.js +3 -1
- package/dist/baseline/check.js.map +1 -1
- package/dist/baseline/entry-to-located.d.ts +36 -11
- package/dist/baseline/entry-to-located.d.ts.map +1 -1
- package/dist/baseline/entry-to-located.js +69 -13
- package/dist/baseline/entry-to-located.js.map +1 -1
- package/dist/baseline/finding-identity.d.ts +32 -0
- package/dist/baseline/finding-identity.d.ts.map +1 -1
- package/dist/baseline/finding-identity.js +17 -2
- package/dist/baseline/finding-identity.js.map +1 -1
- package/dist/baseline/producers/index.d.ts.map +1 -1
- package/dist/baseline/producers/index.js +5 -1
- package/dist/baseline/producers/index.js.map +1 -1
- package/dist/baseline/producers/quality.d.ts +15 -2
- package/dist/baseline/producers/quality.d.ts.map +1 -1
- package/dist/baseline/producers/quality.js +20 -2
- package/dist/baseline/producers/quality.js.map +1 -1
- package/dist/baseline/producers/stale-allow.d.ts +13 -2
- package/dist/baseline/producers/stale-allow.d.ts.map +1 -1
- package/dist/baseline/producers/stale-allow.js +9 -2
- package/dist/baseline/producers/stale-allow.js.map +1 -1
- package/dist/baseline/types.d.ts +12 -0
- package/dist/baseline/types.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +81 -1
- package/dist/cli.js.map +1 -1
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +5 -0
- package/dist/generator.js.map +1 -1
- package/dist/loop/demo.d.ts +11 -0
- package/dist/loop/demo.d.ts.map +1 -0
- package/dist/loop/demo.js +156 -0
- package/dist/loop/demo.js.map +1 -0
- package/dist/loop/doctor.d.ts +37 -0
- package/dist/loop/doctor.d.ts.map +1 -0
- package/dist/loop/doctor.js +294 -0
- package/dist/loop/doctor.js.map +1 -0
- package/dist/loop/ledger-cli.d.ts +7 -0
- package/dist/loop/ledger-cli.d.ts.map +1 -0
- package/dist/loop/ledger-cli.js +95 -0
- package/dist/loop/ledger-cli.js.map +1 -0
- package/dist/loop/ledger.d.ts +95 -0
- package/dist/loop/ledger.d.ts.map +1 -0
- package/dist/loop/ledger.js +201 -0
- package/dist/loop/ledger.js.map +1 -0
- package/dist/loop/policy.d.ts +35 -0
- package/dist/loop/policy.d.ts.map +1 -0
- package/dist/loop/policy.js +151 -0
- package/dist/loop/policy.js.map +1 -0
- package/dist/loop/scaffold.d.ts +26 -0
- package/dist/loop/scaffold.d.ts.map +1 -0
- package/dist/loop/scaffold.js +221 -0
- package/dist/loop/scaffold.js.map +1 -0
- package/dist/loop/stop-gate.d.ts +71 -0
- package/dist/loop/stop-gate.d.ts.map +1 -0
- package/dist/loop/stop-gate.js +295 -0
- package/dist/loop/stop-gate.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +9 -0
- package/dist/update.js.map +1 -1
- package/package.json +1 -1
- package/templates/.claude/skills/dxkit-config/SKILL.md +17 -0
- package/templates/.claude/skills/dxkit-init/SKILL.md +1 -0
- package/templates/.claude/skills/dxkit-learn/SKILL.md +17 -0
- package/templates/.claude/skills/dxkit-loop/SKILL.md +114 -0
- package/templates/.claude/skills/dxkit-onboard/SKILL.md +2 -0
- package/templates/.claude/skills/dxkit-update/SKILL.md +3 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.STOP_HOOK_COMMAND = void 0;
|
|
37
|
+
exports.isClaudeLoopInstalled = isClaudeLoopInstalled;
|
|
38
|
+
exports.installClaudeLoop = installClaudeLoop;
|
|
39
|
+
/**
|
|
40
|
+
* `init --claude-loop` scaffolding — wires the loop pack into a repo
|
|
41
|
+
* ADDITIVELY. None of these writers clobber a user's file:
|
|
42
|
+
*
|
|
43
|
+
* - `.claude/settings.json`: deep-merge our Stop hook into `hooks.Stop[]`,
|
|
44
|
+
* preserving every existing hook / permission / key. Idempotent.
|
|
45
|
+
* - `CLAUDE.md`: upsert a sentinel-delimited managed block, never
|
|
46
|
+
* touching prose outside the markers. Idempotent.
|
|
47
|
+
* - `.dxkit/policy.json`: set `loop.preset`, preserving all other policy.
|
|
48
|
+
*
|
|
49
|
+
* Each writer reads the existing file, mutates the minimum, and writes
|
|
50
|
+
* back; a malformed existing file is left untouched and surfaced as a
|
|
51
|
+
* note rather than overwritten. This mirrors the additive `.gitignore`
|
|
52
|
+
* installer (`ship-installers.ts:installIgnoreFiles`), extended to JSON +
|
|
53
|
+
* a Markdown managed block.
|
|
54
|
+
*/
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const policy_1 = require("./policy");
|
|
58
|
+
/** The command Claude Code runs on Stop. Kept in one place so the
|
|
59
|
+
* installer, doctor, and any future tooling agree on the exact string. */
|
|
60
|
+
exports.STOP_HOOK_COMMAND = 'npx vyuh-dxkit hook stop-gate';
|
|
61
|
+
/** Sentinel markers bounding the dxkit-managed region of CLAUDE.md. Only
|
|
62
|
+
* the text between them is ever rewritten. */
|
|
63
|
+
const CLAUDE_BLOCK_START = '<!-- dxkit:loop:start -->';
|
|
64
|
+
const CLAUDE_BLOCK_END = '<!-- dxkit:loop:end -->';
|
|
65
|
+
/** Preset-agnostic loop norm. Points at `.dxkit/policy.json` as the
|
|
66
|
+
* source of truth for the active posture, so this prose stays correct
|
|
67
|
+
* when the preset is switched without re-running init. */
|
|
68
|
+
const CLAUDE_LOOP_NORM = `## Autonomous loop safety (dxkit)
|
|
69
|
+
|
|
70
|
+
This repo runs coding loops behind the dxkit Stop-gate: when a loop tries
|
|
71
|
+
to stop, \`vyuh-dxkit hook stop-gate\` re-runs the guardrail and blocks
|
|
72
|
+
completion if the branch introduced net-new findings, handing them back
|
|
73
|
+
for repair. Loop norms:
|
|
74
|
+
|
|
75
|
+
- Fix the net-new finding the gate reports. Do NOT refresh the baseline to
|
|
76
|
+
clear a block, and do NOT fix unrelated pre-existing debt — the gate
|
|
77
|
+
only asks for what this branch introduced.
|
|
78
|
+
- The blocking posture is \`loop.preset\` in \`.dxkit/policy.json\`:
|
|
79
|
+
\`security-only\` (default) blocks net-new secrets + crit/high security +
|
|
80
|
+
reachable dependency vulns; \`full-debt\` also blocks test-gap + quality.
|
|
81
|
+
- \`vyuh-dxkit loop doctor\` verifies the loop is wired safely;
|
|
82
|
+
\`vyuh-dxkit loop ledger summarize\` reports what the gate did.`;
|
|
83
|
+
/** True when `.claude/settings.json` already registers the Stop-gate. Used
|
|
84
|
+
* by `update`'s install-flag detection so an upgrade refreshes the loop
|
|
85
|
+
* surface only on repos that opted into it. */
|
|
86
|
+
function isClaudeLoopInstalled(cwd) {
|
|
87
|
+
try {
|
|
88
|
+
const raw = fs.readFileSync(path.join(cwd, '.claude', 'settings.json'), 'utf8');
|
|
89
|
+
const parsed = JSON.parse(raw);
|
|
90
|
+
return (parsed.hooks?.Stop ?? []).some((e) => (e.hooks ?? []).some((h) => typeof h.command === 'string' && /hook\s+stop-gate/.test(h.command)));
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Merge the Stop hook into `.claude/settings.json`. Preserves all existing
|
|
98
|
+
* settings; idempotent (no-op when our hook is already registered). A
|
|
99
|
+
* malformed existing file is left intact and reported via `sidecars`.
|
|
100
|
+
*/
|
|
101
|
+
function mergeStopHook(cwd, result) {
|
|
102
|
+
const rel = path.join('.claude', 'settings.json');
|
|
103
|
+
const abs = path.join(cwd, rel);
|
|
104
|
+
let settings = {};
|
|
105
|
+
let existed = false;
|
|
106
|
+
if (fs.existsSync(abs)) {
|
|
107
|
+
existed = true;
|
|
108
|
+
try {
|
|
109
|
+
settings = JSON.parse(fs.readFileSync(abs, 'utf8'));
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Don't clobber a file we can't parse — drop a reference sidecar.
|
|
113
|
+
const sidecar = rel + '.dxkit';
|
|
114
|
+
fs.writeFileSync(path.join(cwd, sidecar), JSON.stringify({ hooks: { Stop: [stopEntry()] } }, null, 2) + '\n', 'utf8');
|
|
115
|
+
result.sidecars.push(sidecar);
|
|
116
|
+
result.notes.push(`${rel} is not valid JSON — left untouched. Merge the Stop hook from ${sidecar} by hand.`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
settings.hooks ??= {};
|
|
121
|
+
settings.hooks.Stop ??= [];
|
|
122
|
+
const already = settings.hooks.Stop.some((e) => (e.hooks ?? []).some((h) => typeof h.command === 'string' && /hook\s+stop-gate/.test(h.command)));
|
|
123
|
+
if (already) {
|
|
124
|
+
result.skipped.push(rel);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
settings.hooks.Stop.push(stopEntry());
|
|
128
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
129
|
+
fs.writeFileSync(abs, JSON.stringify(settings, null, 2) + '\n', 'utf8');
|
|
130
|
+
result.installed.push(rel);
|
|
131
|
+
if (existed) {
|
|
132
|
+
result.notes.push(`Merged the Stop-gate hook into your existing ${rel} (other hooks preserved).`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function stopEntry() {
|
|
136
|
+
// Stop hooks take no matcher (unlike PreToolUse).
|
|
137
|
+
return { hooks: [{ type: 'command', command: exports.STOP_HOOK_COMMAND }] };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Upsert the dxkit loop managed block in CLAUDE.md. Replaces the block
|
|
141
|
+
* between the sentinels if present (idempotent), appends it otherwise, and
|
|
142
|
+
* never touches content outside the markers.
|
|
143
|
+
*/
|
|
144
|
+
function upsertClaudeBlock(cwd, result) {
|
|
145
|
+
const rel = 'CLAUDE.md';
|
|
146
|
+
const abs = path.join(cwd, rel);
|
|
147
|
+
const block = `${CLAUDE_BLOCK_START}\n${CLAUDE_LOOP_NORM}\n${CLAUDE_BLOCK_END}`;
|
|
148
|
+
let existing = '';
|
|
149
|
+
let existed = false;
|
|
150
|
+
if (fs.existsSync(abs)) {
|
|
151
|
+
existed = true;
|
|
152
|
+
existing = fs.readFileSync(abs, 'utf8');
|
|
153
|
+
}
|
|
154
|
+
const startIdx = existing.indexOf(CLAUDE_BLOCK_START);
|
|
155
|
+
const endIdx = existing.indexOf(CLAUDE_BLOCK_END);
|
|
156
|
+
let next;
|
|
157
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
158
|
+
const before = existing.slice(0, startIdx);
|
|
159
|
+
const after = existing.slice(endIdx + CLAUDE_BLOCK_END.length);
|
|
160
|
+
next = before + block + after;
|
|
161
|
+
if (next === existing) {
|
|
162
|
+
result.skipped.push(rel);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (existed) {
|
|
167
|
+
next = existing.replace(/\s*$/, '') + '\n\n' + block + '\n';
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
next = `# CLAUDE.md\n\n${block}\n`;
|
|
171
|
+
}
|
|
172
|
+
fs.writeFileSync(abs, next, 'utf8');
|
|
173
|
+
result.installed.push(rel);
|
|
174
|
+
if (existed && startIdx === -1) {
|
|
175
|
+
result.notes.push(`Appended a dxkit loop block to your existing ${rel} (your content preserved).`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Ensure `loop.preset` in `.dxkit/policy.json`, preserving all other
|
|
180
|
+
* policy fields. `explicit` (init `--loop-preset`) overrides; otherwise an
|
|
181
|
+
* existing preset is preserved and `security-only` is seeded only when
|
|
182
|
+
* none exists. Idempotent; a malformed existing policy is reported, not
|
|
183
|
+
* overwritten.
|
|
184
|
+
*/
|
|
185
|
+
function ensureLoopPreset(cwd, explicit, result) {
|
|
186
|
+
const rel = path.join('.dxkit', 'policy.json');
|
|
187
|
+
const abs = path.join(cwd, rel);
|
|
188
|
+
let policy = {};
|
|
189
|
+
if (fs.existsSync(abs)) {
|
|
190
|
+
try {
|
|
191
|
+
policy = JSON.parse(fs.readFileSync(abs, 'utf8'));
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
result.notes.push(`${rel} is not valid JSON — left untouched. Set loop.preset by hand.`);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const existing = policy.loop?.preset;
|
|
199
|
+
// Override on explicit; else keep existing; else seed the default.
|
|
200
|
+
const target = explicit ?? existing ?? policy_1.DEFAULT_LOOP_PRESET;
|
|
201
|
+
if (existing === target) {
|
|
202
|
+
result.skipped.push(rel);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
policy.loop = { ...policy.loop, preset: target };
|
|
206
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
207
|
+
fs.writeFileSync(abs, JSON.stringify(policy, null, 2) + '\n', 'utf8');
|
|
208
|
+
result.installed.push(rel);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Scaffold the loop pack into `cwd`. Additive + idempotent: safe to run on
|
|
212
|
+
* a fresh repo or re-run on one that already has settings/CLAUDE.md/policy.
|
|
213
|
+
*/
|
|
214
|
+
function installClaudeLoop(cwd, opts = {}) {
|
|
215
|
+
const result = { installed: [], skipped: [], sidecars: [], notes: [] };
|
|
216
|
+
mergeStopHook(cwd, result);
|
|
217
|
+
upsertClaudeBlock(cwd, result);
|
|
218
|
+
ensureLoopPreset(cwd, opts.preset, result);
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/loop/scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vyuh-dxkit hook stop-gate` — the Claude Code **Stop hook** body.
|
|
3
|
+
*
|
|
4
|
+
* Purpose: stop an autonomous loop from declaring "done" while the
|
|
5
|
+
* deterministic guardrail still reports net-new findings. When the gate
|
|
6
|
+
* blocks, it feeds the exact net-new findings back to the model so the
|
|
7
|
+
* loop can repair them and try to stop again.
|
|
8
|
+
*
|
|
9
|
+
* Claude Code Stop-hook contract used here:
|
|
10
|
+
* - The hook receives a JSON payload on stdin (session_id, cwd,
|
|
11
|
+
* stop_hook_active, optional agent fields).
|
|
12
|
+
* - To BLOCK the stop AND have the model read an actionable message,
|
|
13
|
+
* the hook prints `{"decision":"block","reason":"..."}` on stdout and
|
|
14
|
+
* exits 0. (Exit code 2 also blocks, but its stderr reaches only the
|
|
15
|
+
* operator, not the model — wrong for a repair loop, so it's reserved
|
|
16
|
+
* here for operator-facing config failures.)
|
|
17
|
+
* - `stop_hook_active` is true when the model is already continuing
|
|
18
|
+
* because a prior Stop-gate blocked this turn. Claude Code caps
|
|
19
|
+
* consecutive blocks, so an un-fixable failure can't loop forever;
|
|
20
|
+
* we still keep blocking on net-new findings (the safety guarantee)
|
|
21
|
+
* and rely on that cap as the backstop.
|
|
22
|
+
*
|
|
23
|
+
* Posture:
|
|
24
|
+
* - Net-new findings → block every time (the model CAN fix these).
|
|
25
|
+
* - Guardrail could not run (no baseline, dxkit error) → an operator/
|
|
26
|
+
* preflight problem the model can't fix. Fail closed by surfacing it
|
|
27
|
+
* once (exit 2, operator-visible) then allow on the next attempt to
|
|
28
|
+
* avoid thrashing to the block cap. `DXKIT_LOOP_FAIL_OPEN=1` allows
|
|
29
|
+
* immediately with a loud warning instead. Never a silent skip.
|
|
30
|
+
*/
|
|
31
|
+
import type { GuardrailJsonPayload } from '../baseline/check-renderers';
|
|
32
|
+
import { type LedgerEvent } from './ledger';
|
|
33
|
+
/** Subset of the Claude Code Stop-hook stdin payload we consume. */
|
|
34
|
+
interface StopHookPayload {
|
|
35
|
+
readonly session_id?: string;
|
|
36
|
+
readonly cwd?: string;
|
|
37
|
+
readonly stop_hook_active?: boolean;
|
|
38
|
+
readonly agent_id?: string;
|
|
39
|
+
readonly agent_type?: string;
|
|
40
|
+
}
|
|
41
|
+
/** What the gate decided, before any process I/O. */
|
|
42
|
+
export interface StopGateDecision {
|
|
43
|
+
/** 'allow' → exit 0 silent; 'block-model' → exit 0 + decision JSON;
|
|
44
|
+
* 'block-operator' → exit 2 + stderr. */
|
|
45
|
+
readonly outcome: 'allow' | 'block-model' | 'block-operator';
|
|
46
|
+
/** Message fed to the model (block-model) or operator (block-operator). */
|
|
47
|
+
readonly message: string;
|
|
48
|
+
/** Ledger event recorded for this decision. */
|
|
49
|
+
readonly event: LedgerEvent;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build the repair-friendly message the model reads when blocked. Lists
|
|
53
|
+
* each net-new finding with the location it must fix, and is explicit
|
|
54
|
+
* about the two anti-patterns (refresh baseline / fix grandfathered debt)
|
|
55
|
+
* so the loop stays scoped to what IT introduced.
|
|
56
|
+
*/
|
|
57
|
+
export declare function buildRepairMessage(json: GuardrailJsonPayload): string;
|
|
58
|
+
/**
|
|
59
|
+
* Run the gate. Pure of stdout/exit — returns a decision the CLI wrapper
|
|
60
|
+
* turns into process output + exit code. `runCheck` is injected so tests
|
|
61
|
+
* can drive the gate without a real repo + baseline.
|
|
62
|
+
*/
|
|
63
|
+
export declare function computeStopGate(cwd: string, payload: StopHookPayload, runCheck: (repoDir: string) => Promise<GuardrailJsonPayload>): Promise<StopGateDecision>;
|
|
64
|
+
/**
|
|
65
|
+
* CLI entry for `vyuh-dxkit hook stop-gate`. Reads the hook payload from
|
|
66
|
+
* stdin, runs the guardrail in-process, writes the ledger + last-guardrail
|
|
67
|
+
* snapshot, then emits the Stop-hook decision and exits.
|
|
68
|
+
*/
|
|
69
|
+
export declare function runStopGate(cwd: string): Promise<void>;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=stop-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-gate.d.ts","sourceRoot":"","sources":["../../src/loop/stop-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,UAAU,CAAC;AAKlB,oEAAoE;AACpE,UAAU,eAAe;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B;8CAC0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,gBAAgB,CAAC;IAC7D,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAuBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CA2BrE;AAqBD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAC3D,OAAO,CAAC,gBAAgB,CAAC,CAiI3B;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD5D"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.buildRepairMessage = buildRepairMessage;
|
|
37
|
+
exports.computeStopGate = computeStopGate;
|
|
38
|
+
exports.runStopGate = runStopGate;
|
|
39
|
+
const ledger_1 = require("./ledger");
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
/** Read and parse the stdin hook payload; {} on any problem. */
|
|
44
|
+
function readStdinPayload() {
|
|
45
|
+
let raw = '';
|
|
46
|
+
try {
|
|
47
|
+
raw = fs.readFileSync(0, 'utf8');
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
if (!raw.trim())
|
|
53
|
+
return {};
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(raw);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Blocking pairs (classifier blocks AND not waived by an allowlist). */
|
|
62
|
+
function blockingPairs(json) {
|
|
63
|
+
return json.pairs.filter((p) => p.blocks && p.suppressedByAllowlist === undefined);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build the repair-friendly message the model reads when blocked. Lists
|
|
67
|
+
* each net-new finding with the location it must fix, and is explicit
|
|
68
|
+
* about the two anti-patterns (refresh baseline / fix grandfathered debt)
|
|
69
|
+
* so the loop stays scoped to what IT introduced.
|
|
70
|
+
*/
|
|
71
|
+
function buildRepairMessage(json) {
|
|
72
|
+
const blocking = blockingPairs(json);
|
|
73
|
+
const n = blocking.length;
|
|
74
|
+
const lines = [];
|
|
75
|
+
lines.push(`dxkit blocked completion because this branch introduces ${n} net-new ` +
|
|
76
|
+
`finding${n === 1 ? '' : 's'}.`);
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push('Do not refresh the baseline.');
|
|
79
|
+
lines.push('Do not fix unrelated grandfathered debt.');
|
|
80
|
+
lines.push('Fix only the net-new findings below, then try to stop again.');
|
|
81
|
+
lines.push('');
|
|
82
|
+
blocking.forEach((p, i) => {
|
|
83
|
+
const loc = p.file ? `${p.file}${p.line !== undefined ? `:${p.line}` : ''}` : '(no location)';
|
|
84
|
+
const sev = p.severity ? ` [${p.severity}]` : '';
|
|
85
|
+
lines.push(`${i + 1}. ${p.kind}${sev}`);
|
|
86
|
+
lines.push(` location: ${loc}`);
|
|
87
|
+
const detail = p.reasons.find((r) => r.detail)?.detail;
|
|
88
|
+
if (detail)
|
|
89
|
+
lines.push(` reason: ${detail}`);
|
|
90
|
+
});
|
|
91
|
+
lines.push('');
|
|
92
|
+
lines.push(`Full machine-readable detail: ${path.join(ledger_1.LEDGER_DIR, 'last-guardrail.json')} ` +
|
|
93
|
+
`(read it and fix only these net-new findings).`);
|
|
94
|
+
return lines.join('\n');
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Optional configured test command (DXKIT_LOOP_TEST_COMMAND). Runs only
|
|
98
|
+
* after the guardrail passes. Returns the status plus a short failure
|
|
99
|
+
* tail to surface in the block message. `not_configured` when unset.
|
|
100
|
+
*/
|
|
101
|
+
function runConfiguredTests(repoDir) {
|
|
102
|
+
const cmd = process.env.DXKIT_LOOP_TEST_COMMAND;
|
|
103
|
+
if (!cmd || !cmd.trim())
|
|
104
|
+
return { status: 'not_configured', tail: '' };
|
|
105
|
+
try {
|
|
106
|
+
(0, child_process_1.execSync)(cmd, { cwd: repoDir, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
107
|
+
return { status: 'pass', tail: '' };
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
const e = err;
|
|
111
|
+
const out = `${e.stdout ?? ''}${e.stderr ?? ''}`.trim();
|
|
112
|
+
const tail = out.split('\n').slice(-15).join('\n');
|
|
113
|
+
return { status: 'fail', tail };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Run the gate. Pure of stdout/exit — returns a decision the CLI wrapper
|
|
118
|
+
* turns into process output + exit code. `runCheck` is injected so tests
|
|
119
|
+
* can drive the gate without a real repo + baseline.
|
|
120
|
+
*/
|
|
121
|
+
async function computeStopGate(cwd, payload, runCheck) {
|
|
122
|
+
const start = Date.now();
|
|
123
|
+
const repoDir = payload.cwd || cwd;
|
|
124
|
+
const stopActive = !!payload.stop_hook_active;
|
|
125
|
+
const failOpen = process.env.DXKIT_LOOP_FAIL_OPEN === '1';
|
|
126
|
+
const session = payload.session_id || '';
|
|
127
|
+
const agentFields = {
|
|
128
|
+
...(payload.agent_id ? { agent_id: payload.agent_id } : {}),
|
|
129
|
+
...(payload.agent_type ? { agent_type: payload.agent_type } : {}),
|
|
130
|
+
};
|
|
131
|
+
let json;
|
|
132
|
+
try {
|
|
133
|
+
json = await runCheck(repoDir);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
// Guardrail could not run — a preflight/config problem (no baseline,
|
|
137
|
+
// dxkit error) the model cannot repair.
|
|
138
|
+
const msg = err.message || String(err);
|
|
139
|
+
const allow = failOpen || stopActive;
|
|
140
|
+
const event = (0, ledger_1.buildLedgerEvent)(repoDir, {
|
|
141
|
+
session_id: session,
|
|
142
|
+
...agentFields,
|
|
143
|
+
cwd: repoDir,
|
|
144
|
+
guardrail_status: 'error',
|
|
145
|
+
net_new_findings: 0,
|
|
146
|
+
baseline_findings: 0,
|
|
147
|
+
files_changed: 0,
|
|
148
|
+
allowed: allow,
|
|
149
|
+
stop_hook_active: stopActive,
|
|
150
|
+
tests_status: 'skipped',
|
|
151
|
+
lint_status: 'not_configured',
|
|
152
|
+
typecheck_status: 'not_configured',
|
|
153
|
+
duration_ms: Date.now() - start,
|
|
154
|
+
});
|
|
155
|
+
if (allow) {
|
|
156
|
+
return {
|
|
157
|
+
outcome: 'allow',
|
|
158
|
+
event,
|
|
159
|
+
message: `dxkit Stop-gate could not run the guardrail (${msg}). Allowing stop. ` +
|
|
160
|
+
`Fix the loop preflight (run \`vyuh-dxkit baseline create\` / ` +
|
|
161
|
+
`\`vyuh-dxkit loop doctor\`) before trusting unattended runs.`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
outcome: 'block-operator',
|
|
166
|
+
event,
|
|
167
|
+
message: `dxkit Stop-gate could not run the guardrail: ${msg}\n` +
|
|
168
|
+
`This is a loop preflight problem, not something the agent can fix. ` +
|
|
169
|
+
`Run \`vyuh-dxkit loop doctor\` / \`vyuh-dxkit baseline create\`, or set ` +
|
|
170
|
+
`DXKIT_LOOP_FAIL_OPEN=1 to allow stops when the gate can't run.`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
const blocking = blockingPairs(json);
|
|
174
|
+
const guardrailBlocks = blocking.length > 0;
|
|
175
|
+
// Guardrail decides first. If it blocks, don't bother running tests —
|
|
176
|
+
// the model must fix the findings regardless.
|
|
177
|
+
if (guardrailBlocks) {
|
|
178
|
+
const event = (0, ledger_1.buildLedgerEvent)(repoDir, {
|
|
179
|
+
session_id: session,
|
|
180
|
+
...agentFields,
|
|
181
|
+
cwd: repoDir,
|
|
182
|
+
branch: json.current.branch,
|
|
183
|
+
commit: json.current.commitSha,
|
|
184
|
+
guardrail_status: 'fail',
|
|
185
|
+
net_new_findings: blocking.length,
|
|
186
|
+
baseline_findings: json.baseline.findingsCount,
|
|
187
|
+
files_changed: 0,
|
|
188
|
+
allowed: false,
|
|
189
|
+
stop_hook_active: stopActive,
|
|
190
|
+
tests_status: 'skipped',
|
|
191
|
+
lint_status: 'not_configured',
|
|
192
|
+
typecheck_status: 'not_configured',
|
|
193
|
+
duration_ms: Date.now() - start,
|
|
194
|
+
});
|
|
195
|
+
return { outcome: 'block-model', event, message: buildRepairMessage(json) };
|
|
196
|
+
}
|
|
197
|
+
// Guardrail passed — run the optional configured test command.
|
|
198
|
+
const tests = runConfiguredTests(repoDir);
|
|
199
|
+
if (tests.status === 'fail') {
|
|
200
|
+
const event = (0, ledger_1.buildLedgerEvent)(repoDir, {
|
|
201
|
+
session_id: session,
|
|
202
|
+
...agentFields,
|
|
203
|
+
cwd: repoDir,
|
|
204
|
+
branch: json.current.branch,
|
|
205
|
+
commit: json.current.commitSha,
|
|
206
|
+
guardrail_status: 'pass',
|
|
207
|
+
net_new_findings: 0,
|
|
208
|
+
baseline_findings: json.baseline.findingsCount,
|
|
209
|
+
files_changed: 0,
|
|
210
|
+
allowed: false,
|
|
211
|
+
stop_hook_active: stopActive,
|
|
212
|
+
tests_status: 'fail',
|
|
213
|
+
lint_status: 'not_configured',
|
|
214
|
+
typecheck_status: 'not_configured',
|
|
215
|
+
duration_ms: Date.now() - start,
|
|
216
|
+
});
|
|
217
|
+
return {
|
|
218
|
+
outcome: 'block-model',
|
|
219
|
+
event,
|
|
220
|
+
message: `dxkit allowed the guardrail but the configured test command failed.\n` +
|
|
221
|
+
`Fix the failure below, then try to stop again.\n\n${tests.tail}`,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
// Clean stop.
|
|
225
|
+
const event = (0, ledger_1.buildLedgerEvent)(repoDir, {
|
|
226
|
+
session_id: session,
|
|
227
|
+
...agentFields,
|
|
228
|
+
cwd: repoDir,
|
|
229
|
+
branch: json.current.branch,
|
|
230
|
+
commit: json.current.commitSha,
|
|
231
|
+
guardrail_status: 'pass',
|
|
232
|
+
net_new_findings: 0,
|
|
233
|
+
baseline_findings: json.baseline.findingsCount,
|
|
234
|
+
files_changed: 0,
|
|
235
|
+
allowed: true,
|
|
236
|
+
stop_hook_active: stopActive,
|
|
237
|
+
tests_status: tests.status,
|
|
238
|
+
lint_status: 'not_configured',
|
|
239
|
+
typecheck_status: 'not_configured',
|
|
240
|
+
duration_ms: Date.now() - start,
|
|
241
|
+
});
|
|
242
|
+
return { outcome: 'allow', event, message: '' };
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* CLI entry for `vyuh-dxkit hook stop-gate`. Reads the hook payload from
|
|
246
|
+
* stdin, runs the guardrail in-process, writes the ledger + last-guardrail
|
|
247
|
+
* snapshot, then emits the Stop-hook decision and exits.
|
|
248
|
+
*/
|
|
249
|
+
async function runStopGate(cwd) {
|
|
250
|
+
const payload = readStdinPayload();
|
|
251
|
+
const repoDir = payload.cwd || cwd;
|
|
252
|
+
// Resolve the loop-scoped posture ONCE (preset → policy). This is the
|
|
253
|
+
// only place the loop preset is read; the CI guardrail never sees it.
|
|
254
|
+
const { resolveLoopPolicy } = await Promise.resolve().then(() => __importStar(require('./policy')));
|
|
255
|
+
const { policy, preset } = resolveLoopPolicy(repoDir);
|
|
256
|
+
const runCheck = async (dir) => {
|
|
257
|
+
const { runGuardrailCheck } = await Promise.resolve().then(() => __importStar(require('../baseline/check')));
|
|
258
|
+
const { renderJson } = await Promise.resolve().then(() => __importStar(require('../baseline/check-renderers')));
|
|
259
|
+
const result = await runGuardrailCheck({ cwd: dir, policy });
|
|
260
|
+
const json = renderJson(result);
|
|
261
|
+
// Persist the full machine-readable verdict so the model (and a human)
|
|
262
|
+
// can read the exact net-new findings the block message points to.
|
|
263
|
+
try {
|
|
264
|
+
const dir2 = path.join(dir, ledger_1.LEDGER_DIR);
|
|
265
|
+
fs.mkdirSync(dir2, { recursive: true });
|
|
266
|
+
fs.writeFileSync(path.join(dir2, 'last-guardrail.json'), JSON.stringify(json, null, 2) + '\n', 'utf8');
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
/* best-effort snapshot */
|
|
270
|
+
}
|
|
271
|
+
return json;
|
|
272
|
+
};
|
|
273
|
+
const decision = await computeStopGate(cwd, payload, runCheck);
|
|
274
|
+
// Stamp the active preset onto the ledger line so the audit trail shows
|
|
275
|
+
// which posture was in force when the gate allowed/blocked.
|
|
276
|
+
(0, ledger_1.appendLedgerEvent)(repoDir, { ...decision.event, preset });
|
|
277
|
+
if (decision.outcome === 'block-model') {
|
|
278
|
+
// Exit 0 + decision JSON on stdout → blocks the stop and feeds the
|
|
279
|
+
// reason to the model so it repairs.
|
|
280
|
+
process.stdout.write(JSON.stringify({ decision: 'block', reason: decision.message }) + '\n');
|
|
281
|
+
process.exit(0);
|
|
282
|
+
}
|
|
283
|
+
if (decision.outcome === 'block-operator') {
|
|
284
|
+
// Exit 2 → blocks the stop; stderr reaches the operator (the model
|
|
285
|
+
// can't fix a preflight problem).
|
|
286
|
+
process.stderr.write(decision.message + '\n');
|
|
287
|
+
process.exit(2);
|
|
288
|
+
}
|
|
289
|
+
// allow: exit 0 lets the stop proceed. Surface any warning (config
|
|
290
|
+
// fail-open) on stderr so it isn't a silent skip.
|
|
291
|
+
if (decision.message)
|
|
292
|
+
process.stderr.write(decision.message + '\n');
|
|
293
|
+
process.exit(0);
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=stop-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-gate.js","sourceRoot":"","sources":["../../src/loop/stop-gate.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -117,6 +117,10 @@ export interface ManifestInstallFlags {
|
|
|
117
117
|
withCiGuardrails: boolean;
|
|
118
118
|
withBaselineRefresh: boolean;
|
|
119
119
|
withPrReview: boolean;
|
|
120
|
+
/** Loop pack — Stop-gate hook in .claude/settings.json + CLAUDE.md loop
|
|
121
|
+
* norm + .dxkit/policy.json loop.preset. Optional: absent on manifests
|
|
122
|
+
* written before the loop pack existed (treated as not-installed). */
|
|
123
|
+
withClaudeLoop?: boolean;
|
|
120
124
|
}
|
|
121
125
|
export interface Manifest {
|
|
122
126
|
version: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAClB,YAAY,GACZ,QAAQ,GACR,IAAI,GACJ,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,CAAC;AAEX,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;IAC7C;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,eAAe,CAAC;CAC3C;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;;OAWG;IACH,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvC,cAAc,EAAE;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,eAAe,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAClB,YAAY,GACZ,QAAQ,GACR,IAAI,GACJ,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,CAAC;AAEX,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;IAC7C;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,eAAe,CAAC;CAC3C;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;;OAWG;IACH,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvC,cAAc,EAAE;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,eAAe,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB;;2EAEuE;IACvE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IACzC;;;OAGG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC"}
|
package/dist/update.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAkBzD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAEhD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAa5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,GACV;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,UAAU,GAAG,mBAAmB,CAAA;CAAE,CAKnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAW3E;AAsBD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwJ1F"}
|