@shrkcrft/cli 0.1.0-alpha.2 → 0.1.0-alpha.20
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/dist/audit/knowledge-audit-llm.d.ts +19 -0
- package/dist/audit/knowledge-audit-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-audit-llm.js +164 -0
- package/dist/audit/knowledge-audit.d.ts +61 -0
- package/dist/audit/knowledge-audit.d.ts.map +1 -0
- package/dist/audit/knowledge-audit.js +203 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts +11 -0
- package/dist/audit/knowledge-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan-llm.js +141 -0
- package/dist/audit/knowledge-fix-plan.d.ts +41 -0
- package/dist/audit/knowledge-fix-plan.d.ts.map +1 -0
- package/dist/audit/knowledge-fix-plan.js +125 -0
- package/dist/audit/pipeline-audit-llm.d.ts +11 -0
- package/dist/audit/pipeline-audit-llm.d.ts.map +1 -0
- package/dist/audit/pipeline-audit-llm.js +134 -0
- package/dist/audit/pipeline-audit.d.ts +69 -0
- package/dist/audit/pipeline-audit.d.ts.map +1 -0
- package/dist/audit/pipeline-audit.js +166 -0
- package/dist/audit/templates-audit-llm.d.ts +19 -0
- package/dist/audit/templates-audit-llm.d.ts.map +1 -0
- package/dist/audit/templates-audit-llm.js +207 -0
- package/dist/audit/templates-audit.d.ts +63 -0
- package/dist/audit/templates-audit.d.ts.map +1 -0
- package/dist/audit/templates-audit.js +171 -0
- package/dist/audit/templates-fix-plan-llm.d.ts +19 -0
- package/dist/audit/templates-fix-plan-llm.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan-llm.js +162 -0
- package/dist/audit/templates-fix-plan.d.ts +37 -0
- package/dist/audit/templates-fix-plan.d.ts.map +1 -0
- package/dist/audit/templates-fix-plan.js +174 -0
- package/dist/command-registry.d.ts +28 -0
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +91 -1
- package/dist/commands/ai-status.command.d.ts +19 -0
- package/dist/commands/ai-status.command.d.ts.map +1 -0
- package/dist/commands/ai-status.command.js +94 -0
- package/dist/commands/api-diff.command.d.ts +11 -0
- package/dist/commands/api-diff.command.d.ts.map +1 -0
- package/dist/commands/api-diff.command.js +144 -0
- package/dist/commands/apply.command.d.ts.map +1 -1
- package/dist/commands/apply.command.js +10 -2
- package/dist/commands/arch.command.d.ts +9 -0
- package/dist/commands/arch.command.d.ts.map +1 -0
- package/dist/commands/arch.command.js +186 -0
- package/dist/commands/ask.command.d.ts.map +1 -1
- package/dist/commands/ask.command.js +10 -9
- package/dist/commands/cache-align.command.d.ts +12 -0
- package/dist/commands/cache-align.command.d.ts.map +1 -0
- package/dist/commands/cache-align.command.js +78 -0
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +19 -2
- package/dist/commands/code-intel.command.d.ts +18 -0
- package/dist/commands/code-intel.command.d.ts.map +1 -0
- package/dist/commands/code-intel.command.js +146 -0
- package/dist/commands/codemod.command.d.ts.map +1 -1
- package/dist/commands/codemod.command.js +27 -6
- package/dist/commands/command-catalog.d.ts +15 -3
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +387 -34
- package/dist/commands/commands.command.d.ts.map +1 -1
- package/dist/commands/commands.command.js +4 -4
- package/dist/commands/completion.command.d.ts +10 -0
- package/dist/commands/completion.command.d.ts.map +1 -0
- package/dist/commands/completion.command.js +121 -0
- package/dist/commands/compress.command.d.ts +8 -0
- package/dist/commands/compress.command.d.ts.map +1 -0
- package/dist/commands/compress.command.js +147 -0
- package/dist/commands/constructs.command.d.ts.map +1 -1
- package/dist/commands/constructs.command.js +89 -23
- package/dist/commands/context.command.d.ts.map +1 -1
- package/dist/commands/context.command.js +121 -1
- package/dist/commands/contract-gate.command.d.ts.map +1 -1
- package/dist/commands/contract-gate.command.js +5 -1
- package/dist/commands/delegate.command.d.ts +65 -0
- package/dist/commands/delegate.command.d.ts.map +1 -0
- package/dist/commands/delegate.command.js +657 -0
- package/dist/commands/deps-audit.command.d.ts +23 -0
- package/dist/commands/deps-audit.command.d.ts.map +1 -0
- package/dist/commands/deps-audit.command.js +270 -0
- package/dist/commands/dev.command.d.ts.map +1 -1
- package/dist/commands/dev.command.js +5 -1
- package/dist/commands/diff-check.command.d.ts +30 -0
- package/dist/commands/diff-check.command.d.ts.map +1 -0
- package/dist/commands/diff-check.command.js +210 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +162 -10
- package/dist/commands/export.command.d.ts.map +1 -1
- package/dist/commands/export.command.js +76 -3
- package/dist/commands/framework.command.d.ts +12 -0
- package/dist/commands/framework.command.d.ts.map +1 -0
- package/dist/commands/framework.command.js +180 -0
- package/dist/commands/gate.command.d.ts +15 -0
- package/dist/commands/gate.command.d.ts.map +1 -0
- package/dist/commands/gate.command.js +300 -0
- package/dist/commands/gen.command.d.ts.map +1 -1
- package/dist/commands/gen.command.js +13 -1
- package/dist/commands/graph-code-subverbs.d.ts +33 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -0
- package/dist/commands/graph-code-subverbs.js +1366 -0
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +31 -2
- package/dist/commands/help.command.d.ts +4 -3
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +86 -18
- package/dist/commands/helper.command.js +1 -1
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +171 -1
- package/dist/commands/import.command.d.ts.map +1 -1
- package/dist/commands/import.command.js +121 -5
- package/dist/commands/ingest.command.d.ts.map +1 -1
- package/dist/commands/ingest.command.js +5 -1
- package/dist/commands/init.command.d.ts.map +1 -1
- package/dist/commands/init.command.js +174 -7
- package/dist/commands/knowledge-author.command.d.ts.map +1 -1
- package/dist/commands/knowledge-author.command.js +9 -0
- package/dist/commands/knowledge-propose.command.d.ts.map +1 -1
- package/dist/commands/knowledge-propose.command.js +4 -2
- package/dist/commands/knowledge.command.d.ts.map +1 -1
- package/dist/commands/knowledge.command.js +26 -3
- package/dist/commands/migrate.command.d.ts +13 -0
- package/dist/commands/migrate.command.d.ts.map +1 -0
- package/dist/commands/migrate.command.js +152 -0
- package/dist/commands/move-plan.command.d.ts +23 -0
- package/dist/commands/move-plan.command.d.ts.map +1 -0
- package/dist/commands/move-plan.command.js +360 -0
- package/dist/commands/packs-new.d.ts +1 -1
- package/dist/commands/packs-new.d.ts.map +1 -1
- package/dist/commands/packs-new.js +5 -36
- package/dist/commands/packs.command.d.ts.map +1 -1
- package/dist/commands/packs.command.js +2 -10
- package/dist/commands/plan-context.command.d.ts +11 -0
- package/dist/commands/plan-context.command.d.ts.map +1 -0
- package/dist/commands/plan-context.command.js +85 -0
- package/dist/commands/preflight.command.d.ts.map +1 -1
- package/dist/commands/preflight.command.js +15 -0
- package/dist/commands/profiles.command.js +4 -4
- package/dist/commands/recommend.command.d.ts +6 -0
- package/dist/commands/recommend.command.d.ts.map +1 -1
- package/dist/commands/recommend.command.js +119 -5
- package/dist/commands/release.command.js +13 -13
- package/dist/commands/rule-graph-subverbs.d.ts +3 -0
- package/dist/commands/rule-graph-subverbs.d.ts.map +1 -0
- package/dist/commands/rule-graph-subverbs.js +132 -0
- package/dist/commands/rules.command.d.ts.map +1 -1
- package/dist/commands/rules.command.js +20 -3
- package/dist/commands/scaffold-validate.command.d.ts +22 -0
- package/dist/commands/scaffold-validate.command.d.ts.map +1 -0
- package/dist/commands/scaffold-validate.command.js +215 -0
- package/dist/commands/search-structural.command.d.ts +18 -0
- package/dist/commands/search-structural.command.d.ts.map +1 -0
- package/dist/commands/search-structural.command.js +376 -0
- package/dist/commands/search.command.js +1 -1
- package/dist/commands/smart-context.command.d.ts +67 -0
- package/dist/commands/smart-context.command.d.ts.map +1 -0
- package/dist/commands/smart-context.command.js +4728 -0
- package/dist/commands/spike.command.d.ts +22 -0
- package/dist/commands/spike.command.d.ts.map +1 -0
- package/dist/commands/spike.command.js +235 -0
- package/dist/commands/surface.command.d.ts +1 -0
- package/dist/commands/surface.command.d.ts.map +1 -1
- package/dist/commands/surface.command.js +10 -3
- package/dist/commands/task-context.command.d.ts.map +1 -1
- package/dist/commands/task-context.command.js +5 -17
- package/dist/commands/task.command.d.ts.map +1 -1
- package/dist/commands/task.command.js +8 -2
- package/dist/commands/template-quality.command.d.ts.map +1 -1
- package/dist/commands/template-quality.command.js +39 -3
- package/dist/commands/templates.command.d.ts.map +1 -1
- package/dist/commands/templates.command.js +37 -2
- package/dist/commands/tests.command.d.ts.map +1 -1
- package/dist/commands/tests.command.js +13 -2
- package/dist/commands/watch.command.d.ts +26 -0
- package/dist/commands/watch.command.d.ts.map +1 -0
- package/dist/commands/watch.command.js +456 -0
- package/dist/dashboard/code-intelligence-data.d.ts +33 -0
- package/dist/dashboard/code-intelligence-data.d.ts.map +1 -0
- package/dist/dashboard/code-intelligence-data.js +329 -0
- package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
- package/dist/dashboard/dashboard-api-server.js +256 -2
- package/dist/dashboard/knowledge-ask.d.ts +4 -0
- package/dist/dashboard/knowledge-ask.d.ts.map +1 -0
- package/dist/dashboard/knowledge-ask.js +112 -0
- package/dist/env/load-dotenv.d.ts +15 -0
- package/dist/env/load-dotenv.d.ts.map +1 -0
- package/dist/env/load-dotenv.js +70 -0
- package/dist/export/claude-commands-export.d.ts +60 -0
- package/dist/export/claude-commands-export.d.ts.map +1 -0
- package/dist/export/claude-commands-export.js +276 -0
- package/dist/export/export-formats.d.ts +1 -1
- package/dist/export/export-formats.d.ts.map +1 -1
- package/dist/export/export-formats.js +139 -12
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/init/init-templates.d.ts.map +1 -1
- package/dist/init/init-templates.js +133 -113
- package/dist/init/paths-advisory.d.ts +20 -0
- package/dist/init/paths-advisory.d.ts.map +1 -0
- package/dist/init/paths-advisory.js +88 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +331 -17
- package/dist/output/ccr-store-config.d.ts +18 -0
- package/dist/output/ccr-store-config.d.ts.map +1 -0
- package/dist/output/ccr-store-config.js +41 -0
- package/dist/output/format-output.d.ts.map +1 -1
- package/dist/output/format-output.js +6 -1
- package/dist/output/output-compression.d.ts +15 -0
- package/dist/output/output-compression.d.ts.map +1 -0
- package/dist/output/output-compression.js +60 -0
- package/dist/output/resolve-compress-type.d.ts +22 -0
- package/dist/output/resolve-compress-type.d.ts.map +1 -0
- package/dist/output/resolve-compress-type.js +21 -0
- package/dist/output/watch-loop.d.ts +9 -1
- package/dist/output/watch-loop.d.ts.map +1 -1
- package/dist/output/watch-loop.js +13 -3
- package/dist/schemas/json-schemas.d.ts +384 -36
- package/dist/schemas/json-schemas.d.ts.map +1 -1
- package/dist/schemas/json-schemas.js +247 -36
- package/dist/surface/profiles.d.ts.map +1 -1
- package/dist/surface/profiles.js +54 -9
- package/dist/surface/surface-config-writer.d.ts.map +1 -1
- package/dist/surface/surface-config-writer.js +23 -11
- package/dist/validation/run-validation-loop.d.ts.map +1 -1
- package/dist/validation/run-validation-loop.js +5 -1
- package/package.json +35 -21
- package/dist/commands/plugin.command.d.ts +0 -11
- package/dist/commands/plugin.command.d.ts.map +0 -1
- package/dist/commands/plugin.command.js +0 -394
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { QualityGateReportStore, renderGateReportMarkdown, runQualityGates, } from '@shrkcrft/quality-gates';
|
|
2
|
+
import { chmodSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import * as nodePath from 'node:path';
|
|
4
|
+
import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
|
|
5
|
+
import { asJson, header, kv } from "../output/format-output.js";
|
|
6
|
+
/**
|
|
7
|
+
* `shrk gate` — run all code-intelligence quality gates and emit one
|
|
8
|
+
* pass/fail report. Designed as the single command CI should call
|
|
9
|
+
* before merge.
|
|
10
|
+
*
|
|
11
|
+
* Exit codes:
|
|
12
|
+
* - 0 if overall status is `pass` (no failures, no warnings)
|
|
13
|
+
* - 0 if overall is `warn` (default — opt-in to fail via --strict)
|
|
14
|
+
* - 1 if overall is `fail`
|
|
15
|
+
*
|
|
16
|
+
* Pass `--strict` to treat `warn` as failure.
|
|
17
|
+
*/
|
|
18
|
+
export const gateCommand = {
|
|
19
|
+
name: 'gate',
|
|
20
|
+
description: 'Aggregator: runs the code-intelligence quality gates (graph freshness, architecture, impact-since-ref) and reports a single pass/fail.',
|
|
21
|
+
usage: 'shrk gate [--since <gitref>] [--fail-on critical,high] [--arch-all] [--disable arch,impact,api-diff] [--api-baseline <path>] [--no-fail-on-breaking] [--strict] [--no-persist] [--json] [--markdown] [--output <path>]\n (the arch gate is baseline-relative by default once a baseline is frozen — fails only on NEW errors; --arch-all fails on total)\n shrk gate scaffold-ci [--provider github|generic] [--force] [--json]\n shrk gate scaffold-hook [--provider husky|raw] [--force] [--json]',
|
|
22
|
+
async run(args) {
|
|
23
|
+
if (args.positional[0] === 'scaffold-ci') {
|
|
24
|
+
const sliced = { ...args, positional: args.positional.slice(1) };
|
|
25
|
+
return runGateScaffoldCi(sliced);
|
|
26
|
+
}
|
|
27
|
+
if (args.positional[0] === 'scaffold-hook') {
|
|
28
|
+
const sliced = { ...args, positional: args.positional.slice(1) };
|
|
29
|
+
return runGateScaffoldHook(sliced);
|
|
30
|
+
}
|
|
31
|
+
const cwd = resolveCwd(args);
|
|
32
|
+
const wantJson = flagBool(args, 'json');
|
|
33
|
+
const wantMarkdown = flagBool(args, 'markdown');
|
|
34
|
+
const outputPath = flagString(args, 'output');
|
|
35
|
+
const strict = flagBool(args, 'strict');
|
|
36
|
+
const sinceRef = flagString(args, 'since');
|
|
37
|
+
const failOnRaw = flagString(args, 'fail-on');
|
|
38
|
+
const disableRaw = flagString(args, 'disable');
|
|
39
|
+
const apiBaseline = flagString(args, 'api-baseline');
|
|
40
|
+
const noFailOnBreaking = flagBool(args, 'no-fail-on-breaking');
|
|
41
|
+
const failOn = failOnRaw
|
|
42
|
+
? failOnRaw.split(',').map((s) => s.trim()).filter(Boolean)
|
|
43
|
+
: undefined;
|
|
44
|
+
const disable = disableRaw ? disableRaw.split(',').map((s) => s.trim()).filter(Boolean) : undefined;
|
|
45
|
+
// --arch-all: fail on TOTAL architecture errors (ignore the frozen baseline).
|
|
46
|
+
// By default the arch gate is baseline-relative — it fails only on NEW errors.
|
|
47
|
+
const archAll = flagBool(args, 'arch-all');
|
|
48
|
+
const report = runQualityGates({
|
|
49
|
+
projectRoot: cwd,
|
|
50
|
+
...(archAll ? { arch: { baselineRelative: false } } : {}),
|
|
51
|
+
impact: {
|
|
52
|
+
...(sinceRef ? { sinceRef } : {}),
|
|
53
|
+
...(failOn ? { failOn } : {}),
|
|
54
|
+
},
|
|
55
|
+
...(apiBaseline
|
|
56
|
+
? {
|
|
57
|
+
apiDiff: {
|
|
58
|
+
baselinePath: apiBaseline,
|
|
59
|
+
failOnBreaking: !noFailOnBreaking,
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
: {}),
|
|
63
|
+
...(disable ? { disable } : {}),
|
|
64
|
+
});
|
|
65
|
+
// Persist the report so dashboards and follow-up tooling can read
|
|
66
|
+
// it without re-running every gate. Opt out with `--no-persist`.
|
|
67
|
+
if (!flagBool(args, 'no-persist')) {
|
|
68
|
+
try {
|
|
69
|
+
new QualityGateReportStore(cwd).write(report);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Persistence is best-effort; never fail the gate on a
|
|
73
|
+
// disk-write error.
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (wantMarkdown) {
|
|
77
|
+
const md = renderGateReportMarkdown(report);
|
|
78
|
+
if (outputPath) {
|
|
79
|
+
const abs = nodePath.isAbsolute(outputPath)
|
|
80
|
+
? outputPath
|
|
81
|
+
: nodePath.resolve(cwd, outputPath);
|
|
82
|
+
writeFileSync(abs, md, 'utf8');
|
|
83
|
+
process.stdout.write(`Markdown report written → ${abs}\n`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
process.stdout.write(md);
|
|
87
|
+
}
|
|
88
|
+
return exitCode(report.overall, strict);
|
|
89
|
+
}
|
|
90
|
+
if (wantJson) {
|
|
91
|
+
process.stdout.write(asJson(report) + '\n');
|
|
92
|
+
return exitCode(report.overall, strict);
|
|
93
|
+
}
|
|
94
|
+
process.stdout.write(header(`Quality gates: ${report.overall.toUpperCase()}`));
|
|
95
|
+
process.stdout.write(kv('total duration', `${report.totalDurationMs}ms`) + '\n');
|
|
96
|
+
process.stdout.write(kv('summary', `pass=${report.counts.pass} warn=${report.counts.warn} fail=${report.counts.fail} skipped=${report.counts.skipped}`) + '\n');
|
|
97
|
+
process.stdout.write('\nGates:\n');
|
|
98
|
+
for (const g of report.gates) {
|
|
99
|
+
const status = g.status.padEnd(8);
|
|
100
|
+
process.stdout.write(` [${status}] ${g.label} (${g.durationMs}ms)\n`);
|
|
101
|
+
process.stdout.write(` ${g.message}\n`);
|
|
102
|
+
if (g.nextCommands && g.nextCommands.length > 0) {
|
|
103
|
+
for (const c of g.nextCommands)
|
|
104
|
+
process.stdout.write(` → ${c}\n`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return exitCode(report.overall, strict);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
function exitCode(overall, strict) {
|
|
111
|
+
if (overall === 'fail')
|
|
112
|
+
return 1;
|
|
113
|
+
if (overall === 'warn' && strict)
|
|
114
|
+
return 1;
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
const GITHUB_WORKFLOW = `name: shrk gate
|
|
118
|
+
|
|
119
|
+
on:
|
|
120
|
+
pull_request:
|
|
121
|
+
push:
|
|
122
|
+
branches: [main]
|
|
123
|
+
|
|
124
|
+
jobs:
|
|
125
|
+
gate:
|
|
126
|
+
runs-on: ubuntu-latest
|
|
127
|
+
timeout-minutes: 10
|
|
128
|
+
steps:
|
|
129
|
+
- uses: actions/checkout@v4
|
|
130
|
+
with:
|
|
131
|
+
fetch-depth: 0 # full history so 'shrk impact --since main' works
|
|
132
|
+
|
|
133
|
+
- name: Setup bun
|
|
134
|
+
uses: oven-sh/setup-bun@v2
|
|
135
|
+
|
|
136
|
+
- name: Install dependencies
|
|
137
|
+
run: bun install --frozen-lockfile
|
|
138
|
+
|
|
139
|
+
- name: Index code-intelligence graph
|
|
140
|
+
run: bunx shrk graph index
|
|
141
|
+
|
|
142
|
+
- name: Run shrk gate
|
|
143
|
+
run: bunx shrk gate --since origin/main --strict --markdown --output gate-report.md
|
|
144
|
+
|
|
145
|
+
- name: Upload gate report
|
|
146
|
+
if: always()
|
|
147
|
+
uses: actions/upload-artifact@v4
|
|
148
|
+
with:
|
|
149
|
+
name: shrk-gate-report
|
|
150
|
+
path: |
|
|
151
|
+
gate-report.md
|
|
152
|
+
.sharkcraft/quality-gates/last.json
|
|
153
|
+
|
|
154
|
+
- name: Comment on PR
|
|
155
|
+
if: github.event_name == 'pull_request' && always()
|
|
156
|
+
uses: marocchino/sticky-pull-request-comment@v2
|
|
157
|
+
with:
|
|
158
|
+
header: shrk-gate
|
|
159
|
+
path: gate-report.md
|
|
160
|
+
`;
|
|
161
|
+
const HUSKY_PRE_COMMIT = `#!/usr/bin/env sh
|
|
162
|
+
# shrk gate pre-commit hook (husky-compatible).
|
|
163
|
+
#
|
|
164
|
+
# Re-indexes the code graph from staged files only, then runs the
|
|
165
|
+
# default gate set against the change. Add or remove --disable flags
|
|
166
|
+
# to narrow the gate set if a particular check is too slow at this
|
|
167
|
+
# point in the loop.
|
|
168
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
169
|
+
|
|
170
|
+
set -e
|
|
171
|
+
|
|
172
|
+
bunx shrk graph index --changed
|
|
173
|
+
bunx shrk gate --strict
|
|
174
|
+
`;
|
|
175
|
+
const RAW_PRE_COMMIT = `#!/usr/bin/env sh
|
|
176
|
+
# shrk gate pre-commit hook (raw .git/hooks variant).
|
|
177
|
+
#
|
|
178
|
+
# Symlink or copy this file into .git/hooks/pre-commit:
|
|
179
|
+
# ln -s ../../scripts/pre-commit .git/hooks/pre-commit
|
|
180
|
+
# (or just \`cp scripts/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit\`).
|
|
181
|
+
set -e
|
|
182
|
+
|
|
183
|
+
bunx shrk graph index --changed
|
|
184
|
+
bunx shrk gate --strict
|
|
185
|
+
`;
|
|
186
|
+
const GENERIC_SCRIPT = `#!/usr/bin/env bash
|
|
187
|
+
# Generic CI runner for shrk gate. Copy / adapt for your provider.
|
|
188
|
+
#
|
|
189
|
+
# Usage:
|
|
190
|
+
# ./scripts/shrk-gate.sh
|
|
191
|
+
#
|
|
192
|
+
# Exit codes:
|
|
193
|
+
# 0 — gate pass or warn (non-strict)
|
|
194
|
+
# 1 — gate fail (or warn under --strict)
|
|
195
|
+
set -euo pipefail
|
|
196
|
+
|
|
197
|
+
# Ensure the code-intelligence graph is fresh.
|
|
198
|
+
bunx shrk graph index
|
|
199
|
+
|
|
200
|
+
# Run the aggregator. --strict turns warn into fail; drop it if you
|
|
201
|
+
# prefer to surface warnings without blocking merge.
|
|
202
|
+
bunx shrk gate \\
|
|
203
|
+
--since "\${BASE_REF:-origin/main}" \\
|
|
204
|
+
--strict \\
|
|
205
|
+
--markdown \\
|
|
206
|
+
--output gate-report.md
|
|
207
|
+
`;
|
|
208
|
+
async function runGateScaffoldHook(args) {
|
|
209
|
+
const cwd = resolveCwd(args);
|
|
210
|
+
const wantJson = flagBool(args, 'json');
|
|
211
|
+
const provider = flagString(args, 'provider') ?? 'husky';
|
|
212
|
+
const force = flagBool(args, 'force');
|
|
213
|
+
let target;
|
|
214
|
+
let body;
|
|
215
|
+
switch (provider) {
|
|
216
|
+
case 'husky':
|
|
217
|
+
target = nodePath.join(cwd, '.husky', 'pre-commit');
|
|
218
|
+
body = HUSKY_PRE_COMMIT;
|
|
219
|
+
break;
|
|
220
|
+
case 'raw':
|
|
221
|
+
target = nodePath.join(cwd, 'scripts', 'pre-commit');
|
|
222
|
+
body = RAW_PRE_COMMIT;
|
|
223
|
+
break;
|
|
224
|
+
default:
|
|
225
|
+
process.stderr.write(`Unknown --provider "${provider}". Use husky | raw.\n`);
|
|
226
|
+
return 2;
|
|
227
|
+
}
|
|
228
|
+
if (existsSync(target) && !force) {
|
|
229
|
+
const msg = `${target} already exists. Use --force to overwrite.\n`;
|
|
230
|
+
if (wantJson) {
|
|
231
|
+
process.stdout.write(asJson({ ok: false, error: 'exists', path: target }) + '\n');
|
|
232
|
+
return 1;
|
|
233
|
+
}
|
|
234
|
+
process.stderr.write(msg);
|
|
235
|
+
return 1;
|
|
236
|
+
}
|
|
237
|
+
mkdirSync(nodePath.dirname(target), { recursive: true });
|
|
238
|
+
writeFileSync(target, body, 'utf8');
|
|
239
|
+
try {
|
|
240
|
+
chmodSync(target, 0o755);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// ignore — Windows / strict FS.
|
|
244
|
+
}
|
|
245
|
+
if (wantJson) {
|
|
246
|
+
process.stdout.write(asJson({ ok: true, provider, wrote: target, bytes: body.length }) + '\n');
|
|
247
|
+
return 0;
|
|
248
|
+
}
|
|
249
|
+
process.stdout.write(`Scaffolded ${provider} pre-commit hook → ${target}\n`);
|
|
250
|
+
if (provider === 'raw') {
|
|
251
|
+
process.stdout.write(`Activate it with:\n ln -s ../../scripts/pre-commit .git/hooks/pre-commit\n`);
|
|
252
|
+
}
|
|
253
|
+
return 0;
|
|
254
|
+
}
|
|
255
|
+
async function runGateScaffoldCi(args) {
|
|
256
|
+
const cwd = resolveCwd(args);
|
|
257
|
+
const wantJson = flagBool(args, 'json');
|
|
258
|
+
const provider = flagString(args, 'provider') ?? 'github';
|
|
259
|
+
const force = flagBool(args, 'force');
|
|
260
|
+
let target;
|
|
261
|
+
let body;
|
|
262
|
+
switch (provider) {
|
|
263
|
+
case 'github':
|
|
264
|
+
target = nodePath.join(cwd, '.github', 'workflows', 'shrk-gate.yml');
|
|
265
|
+
body = GITHUB_WORKFLOW;
|
|
266
|
+
break;
|
|
267
|
+
case 'generic':
|
|
268
|
+
target = nodePath.join(cwd, 'scripts', 'shrk-gate.sh');
|
|
269
|
+
body = GENERIC_SCRIPT;
|
|
270
|
+
break;
|
|
271
|
+
default:
|
|
272
|
+
process.stderr.write(`Unknown --provider "${provider}". Use github | generic.\n`);
|
|
273
|
+
return 2;
|
|
274
|
+
}
|
|
275
|
+
if (existsSync(target) && !force) {
|
|
276
|
+
const msg = `${target} already exists. Use --force to overwrite.\n`;
|
|
277
|
+
if (wantJson) {
|
|
278
|
+
process.stdout.write(asJson({ ok: false, error: 'exists', path: target }) + '\n');
|
|
279
|
+
return 1;
|
|
280
|
+
}
|
|
281
|
+
process.stderr.write(msg);
|
|
282
|
+
return 1;
|
|
283
|
+
}
|
|
284
|
+
mkdirSync(nodePath.dirname(target), { recursive: true });
|
|
285
|
+
writeFileSync(target, body, 'utf8');
|
|
286
|
+
if (provider === 'generic') {
|
|
287
|
+
try {
|
|
288
|
+
chmodSync(target, 0o755);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
// ignore — Windows or stricter FS.
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (wantJson) {
|
|
295
|
+
process.stdout.write(asJson({ ok: true, provider, wrote: target, bytes: body.length }) + '\n');
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
298
|
+
process.stdout.write(`Scaffolded ${provider} CI runner → ${target}\n`);
|
|
299
|
+
return 0;
|
|
300
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gen.command.d.ts","sourceRoot":"","sources":["../../src/commands/gen.command.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkBhC,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"gen.command.d.ts","sourceRoot":"","sources":["../../src/commands/gen.command.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkBhC,eAAO,MAAM,UAAU,EAAE,eA+JxB,CAAC"}
|
|
@@ -19,7 +19,7 @@ const CHANGE_LABEL = {
|
|
|
19
19
|
export const genCommand = {
|
|
20
20
|
name: 'gen',
|
|
21
21
|
description: 'Generate code from a template. Defaults to dry-run.',
|
|
22
|
-
usage: 'shrk gen <templateId> [<name>] [--var key=value ...] [--dry-run] [--write] [--force] [--save-plan <file>] [--json]',
|
|
22
|
+
usage: 'shrk gen <templateId> [<name>] [--var key=value ...] [--dry-run] [--write] [--force] [--save-plan <file>] [--show-content] [--json]',
|
|
23
23
|
async run(args) {
|
|
24
24
|
const templateId = args.positional[0];
|
|
25
25
|
const name = args.positional[1];
|
|
@@ -114,6 +114,18 @@ export const genCommand = {
|
|
|
114
114
|
for (const change of plan.changes) {
|
|
115
115
|
process.stdout.write(`${CHANGE_LABEL[change.type]} ${change.relativePath} (${change.sizeBytes} bytes) — ${change.reason}\n`);
|
|
116
116
|
}
|
|
117
|
+
// --show-content: print the already-computed virtual file content so an
|
|
118
|
+
// agent can review what a template would generate WITHOUT writing to disk
|
|
119
|
+
// (the saved plan stays content-free). The bytes are identical in dry-run
|
|
120
|
+
// and --write; this is purely additive.
|
|
121
|
+
if (flagBool(args, 'show-content')) {
|
|
122
|
+
process.stdout.write('\nVirtual content (not written to disk):\n');
|
|
123
|
+
for (const change of plan.changes) {
|
|
124
|
+
const body = change.contents ?? '';
|
|
125
|
+
process.stdout.write(`\n----- ${change.relativePath} (${change.sizeBytes} bytes) -----\n`);
|
|
126
|
+
process.stdout.write(body.endsWith('\n') ? body : body + '\n');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
117
129
|
if (plan.postGenerationNotes.length) {
|
|
118
130
|
process.stdout.write('\nPost-generation notes:\n');
|
|
119
131
|
for (const note of plan.postGenerationNotes)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ParsedArgs } from '../command-registry.js';
|
|
2
|
+
export declare function runGraphIndex(args: ParsedArgs): Promise<number>;
|
|
3
|
+
export declare function runGraphCycles(args: ParsedArgs): Promise<number>;
|
|
4
|
+
export declare function runGraphUnresolved(args: ParsedArgs): Promise<number>;
|
|
5
|
+
export declare function runGraphDeps(args: ParsedArgs): Promise<number>;
|
|
6
|
+
export declare function runGraphStatus(args: ParsedArgs): Promise<number>;
|
|
7
|
+
export declare function runGraphSearch(args: ParsedArgs): Promise<number>;
|
|
8
|
+
export declare function runGraphContext(args: ParsedArgs): Promise<number>;
|
|
9
|
+
export declare function runGraphImpact(args: ParsedArgs): Promise<number>;
|
|
10
|
+
/**
|
|
11
|
+
* `shrk graph hubs` — the most-depended-on code: symbols ranked by how many
|
|
12
|
+
* DISTINCT files reference them, files by how many import them. The
|
|
13
|
+
* "load-bearing code" an agent should change most carefully and a human should
|
|
14
|
+
* understand first — the natural companion to `graph impact` (impact = blast
|
|
15
|
+
* radius of ONE node; hubs = the nodes with the biggest blast radius).
|
|
16
|
+
*/
|
|
17
|
+
export declare function runGraphHubs(args: ParsedArgs): Promise<number>;
|
|
18
|
+
export declare function runGraphCallers(args: ParsedArgs): Promise<number>;
|
|
19
|
+
/**
|
|
20
|
+
* `shrk graph path <from> <to>` — does code A actually reach code B?
|
|
21
|
+
*
|
|
22
|
+
* The question the original feedback fell back to grep for ("is billing
|
|
23
|
+
* actually WIRED to checkout?"). `callers` = direct callers, `impact` =
|
|
24
|
+
* reverse closure, `graph why` = the KNOWLEDGE graph — none answers the
|
|
25
|
+
* forward CODE path between two symbols/files. This BFS does, over the
|
|
26
|
+
* import/call/reference/declare/re-export/extends/implements edges, and
|
|
27
|
+
* prints each hop with its edge kind (and call-site line) so the answer
|
|
28
|
+
* shows HOW they are wired, not just that they are. When A→B has no path it
|
|
29
|
+
* also checks B→A so "the dependency runs the other way" is reported instead
|
|
30
|
+
* of a bare "no".
|
|
31
|
+
*/
|
|
32
|
+
export declare function runGraphPath(args: ParsedArgs): Promise<number>;
|
|
33
|
+
//# sourceMappingURL=graph-code-subverbs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-code-subverbs.d.ts","sourceRoot":"","sources":["../../src/commands/graph-code-subverbs.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAiI3F,wBAAsB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrE;AA4FD,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DtE;AAiBD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAwF1E;AAID,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA8EpE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAmFtE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiDtE;AAID,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgMvE;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA8HtE;AAID;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CpE;AAID,wBAAsB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA+EvE;AAyBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAgHpE"}
|