@shrkcrft/inspector 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/agent-brief.d.ts.map +1 -1
- package/dist/agent-brief.js +59 -10
- package/dist/agent-contract-gate.d.ts.map +1 -1
- package/dist/agent-contract-gate.js +25 -2
- package/dist/agent-instructions.d.ts.map +1 -1
- package/dist/agent-instructions.js +11 -0
- package/dist/agent-task-prep.d.ts.map +1 -1
- package/dist/agent-task-prep.js +1 -3
- package/dist/ai-readiness.d.ts +84 -9
- package/dist/ai-readiness.d.ts.map +1 -1
- package/dist/ai-readiness.js +181 -35
- package/dist/apply-dispatch-trace.d.ts +1 -2
- package/dist/apply-dispatch-trace.d.ts.map +1 -1
- package/dist/apply-dispatch-trace.js +0 -9
- package/dist/area-explore.d.ts.map +1 -1
- package/dist/area-explore.js +4 -6
- package/dist/area-map.d.ts +0 -5
- package/dist/area-map.d.ts.map +1 -1
- package/dist/area-map.js +0 -10
- package/dist/changed-preflight.d.ts +7 -0
- package/dist/changed-preflight.d.ts.map +1 -1
- package/dist/changed-preflight.js +56 -9
- package/dist/changes-summary.d.ts.map +1 -1
- package/dist/changes-summary.js +10 -1
- package/dist/check-guardrail-globs.d.ts +16 -0
- package/dist/check-guardrail-globs.d.ts.map +1 -0
- package/dist/check-guardrail-globs.js +38 -0
- package/dist/code-intelligence-doctor.d.ts +21 -0
- package/dist/code-intelligence-doctor.d.ts.map +1 -0
- package/dist/code-intelligence-doctor.js +985 -0
- package/dist/command-recommender.d.ts.map +1 -1
- package/dist/command-recommender.js +23 -0
- package/dist/compliance-profiles.js +1 -1
- package/dist/construct-adoption-diff.d.ts.map +1 -1
- package/dist/construct-adoption-diff.js +2 -1
- package/dist/construct-adoption.d.ts.map +1 -1
- package/dist/construct-adoption.js +10 -11
- package/dist/construct-inference.d.ts.map +1 -1
- package/dist/construct-inference.js +5 -2
- package/dist/construct-registry.d.ts.map +1 -1
- package/dist/construct-registry.js +2 -10
- package/dist/contract-file-rule.d.ts +8 -0
- package/dist/contract-file-rule.d.ts.map +1 -1
- package/dist/contract-file-rule.js +8 -3
- package/dist/contract-template-registry.d.ts.map +1 -1
- package/dist/contract-template-registry.js +2 -10
- package/dist/contradictions.d.ts +8 -1
- package/dist/contradictions.d.ts.map +1 -1
- package/dist/contradictions.js +37 -35
- package/dist/convention-registry.d.ts.map +1 -1
- package/dist/convention-registry.js +2 -10
- package/dist/coverage-report.d.ts.map +1 -1
- package/dist/coverage-report.js +14 -1
- package/dist/dashboard/dashboard-knowledge.d.ts +8 -0
- package/dist/dashboard/dashboard-knowledge.d.ts.map +1 -0
- package/dist/dashboard/dashboard-knowledge.js +259 -0
- package/dist/decision-records.d.ts.map +1 -1
- package/dist/decision-records.js +5 -10
- package/dist/delegate-catalog.d.ts +45 -0
- package/dist/delegate-catalog.d.ts.map +1 -0
- package/dist/delegate-catalog.js +50 -0
- package/dist/delegate-doctor.d.ts +15 -0
- package/dist/delegate-doctor.d.ts.map +1 -0
- package/dist/delegate-doctor.js +36 -0
- package/dist/delegate-pack-recipes.d.ts +29 -0
- package/dist/delegate-pack-recipes.d.ts.map +1 -0
- package/dist/delegate-pack-recipes.js +77 -0
- package/dist/demo-script.d.ts +0 -1
- package/dist/demo-script.d.ts.map +1 -1
- package/dist/demo-script.js +0 -43
- package/dist/docs-check.js +1 -1
- package/dist/drift-baseline.d.ts.map +1 -1
- package/dist/drift-baseline.js +5 -2
- package/dist/feedback-ingestion.d.ts.map +1 -1
- package/dist/feedback-ingestion.js +2 -16
- package/dist/git-helpers.d.ts +15 -0
- package/dist/git-helpers.d.ts.map +1 -1
- package/dist/git-helpers.js +51 -4
- package/dist/helper-registry.d.ts +27 -54
- package/dist/helper-registry.d.ts.map +1 -1
- package/dist/helper-registry.js +16 -517
- package/dist/impact-analysis.d.ts.map +1 -1
- package/dist/impact-analysis.js +14 -7
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/ingest-drafts.js +8 -4
- package/dist/migration-profile-registry.d.ts.map +1 -1
- package/dist/migration-profile-registry.js +2 -10
- package/dist/monorepo-onboarding.js +2 -2
- package/dist/onboarding-report.d.ts.map +1 -1
- package/dist/onboarding-report.js +5 -1
- package/dist/onboarding.d.ts +1 -1
- package/dist/onboarding.d.ts.map +1 -1
- package/dist/onboarding.js +9 -66
- package/dist/ownership.js +2 -10
- package/dist/pack-contributions-inventory.d.ts +0 -1
- package/dist/pack-contributions-inventory.d.ts.map +1 -1
- package/dist/pack-contributions-inventory.js +17 -29
- package/dist/pack-helper-registry.d.ts.map +1 -1
- package/dist/pack-helper-registry.js +2 -10
- package/dist/pack-release-check.d.ts.map +1 -1
- package/dist/pack-release-check.js +4 -11
- package/dist/pack-signature-status.d.ts.map +1 -1
- package/dist/pack-signature-status.js +18 -2
- package/dist/pack-test-runner.js +2 -10
- package/dist/plan-review.d.ts.map +1 -1
- package/dist/plan-review.js +5 -10
- package/dist/plan-simulation.d.ts +13 -0
- package/dist/plan-simulation.d.ts.map +1 -1
- package/dist/plan-simulation.js +4 -21
- package/dist/playbook-registry.d.ts.map +1 -1
- package/dist/playbook-registry.js +2 -10
- package/dist/policy-engine.d.ts.map +1 -1
- package/dist/policy-engine.js +3 -11
- package/dist/policy-test.js +3 -11
- package/dist/profile-registry.d.ts +0 -1
- package/dist/profile-registry.d.ts.map +1 -1
- package/dist/profile-registry.js +4 -32
- package/dist/propose-knowledge.d.ts +15 -0
- package/dist/propose-knowledge.d.ts.map +1 -1
- package/dist/propose-knowledge.js +37 -4
- package/dist/quality-baseline.d.ts.map +1 -1
- package/dist/quality-baseline.js +3 -1
- package/dist/ranker-explainability.d.ts.map +1 -1
- package/dist/ranker-explainability.js +3 -9
- package/dist/registration-hint-registry.d.ts.map +1 -1
- package/dist/registration-hint-registry.js +2 -10
- package/dist/registry-lifecycle.d.ts +6 -0
- package/dist/registry-lifecycle.d.ts.map +1 -1
- package/dist/registry-lifecycle.js +137 -10
- package/dist/release-readiness.js +3 -3
- package/dist/repo-memory.d.ts.map +1 -1
- package/dist/repo-memory.js +3 -1
- package/dist/reposet.js +1 -1
- package/dist/repository-intelligence.d.ts.map +1 -1
- package/dist/repository-intelligence.js +7 -2
- package/dist/repository-knowledge-model.d.ts +1 -1
- package/dist/repository-knowledge-model.d.ts.map +1 -1
- package/dist/repository-stats.d.ts.map +1 -1
- package/dist/repository-stats.js +3 -1
- package/dist/resolve-verification-commands.d.ts +26 -0
- package/dist/resolve-verification-commands.d.ts.map +1 -0
- package/dist/resolve-verification-commands.js +55 -0
- package/dist/review-packet.d.ts.map +1 -1
- package/dist/review-packet.js +14 -17
- package/dist/rule-drift.d.ts.map +1 -1
- package/dist/rule-drift.js +24 -9
- package/dist/rule-scaffold.d.ts.map +1 -1
- package/dist/rule-scaffold.js +12 -4
- package/dist/scaffold-patterns.js +2 -10
- package/dist/search-tuning-registry.d.ts.map +1 -1
- package/dist/search-tuning-registry.js +2 -10
- package/dist/self-config-doctor-v2.d.ts +1 -1
- package/dist/self-config-doctor-v2.d.ts.map +1 -1
- package/dist/self-config-doctor-v2.js +6 -10
- package/dist/self-config-doctor.d.ts.map +1 -1
- package/dist/self-config-doctor.js +7 -13
- package/dist/sharkcraft-inspector.d.ts +14 -0
- package/dist/sharkcraft-inspector.d.ts.map +1 -1
- package/dist/sharkcraft-inspector.js +103 -1
- package/dist/start-here.d.ts +2 -2
- package/dist/start-here.d.ts.map +1 -1
- package/dist/start-here.js +16 -1
- package/dist/synthesize-from-onboarding.d.ts +68 -0
- package/dist/synthesize-from-onboarding.d.ts.map +1 -0
- package/dist/synthesize-from-onboarding.js +508 -0
- package/dist/task-packet.d.ts +13 -0
- package/dist/task-packet.d.ts.map +1 -1
- package/dist/task-packet.js +59 -6
- package/dist/task-ranker.d.ts.map +1 -1
- package/dist/task-ranker.js +1 -31
- package/dist/task-routing-hint-registry.d.ts.map +1 -1
- package/dist/task-routing-hint-registry.js +2 -10
- package/dist/template-drift.d.ts +7 -0
- package/dist/template-drift.d.ts.map +1 -1
- package/dist/template-drift.js +14 -6
- package/dist/test-impact.d.ts.map +1 -1
- package/dist/test-impact.js +5 -2
- package/dist/test-runner.d.ts.map +1 -1
- package/dist/test-runner.js +12 -17
- package/dist/universal-search.d.ts +0 -1
- package/dist/universal-search.d.ts.map +1 -1
- package/dist/universal-search.js +0 -12
- package/dist/why-file.js +66 -22
- package/package.json +18 -18
- package/dist/plugin-lifecycle-profile-registry.d.ts +0 -52
- package/dist/plugin-lifecycle-profile-registry.d.ts.map +0 -1
- package/dist/plugin-lifecycle-profile-registry.js +0 -202
- package/dist/plugin-lifecycle.d.ts +0 -132
- package/dist/plugin-lifecycle.d.ts.map +0 -1
- package/dist/plugin-lifecycle.js +0 -477
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert an {@link IOnboardingPlan} into populated `sharkcraft/*.ts`
|
|
3
|
+
* file contents — the engine behind `shrk init --infer --write`.
|
|
4
|
+
*
|
|
5
|
+
* Design goals:
|
|
6
|
+
*
|
|
7
|
+
* - **Populated, not advisory.** The existing `writeOnboardingDrafts`
|
|
8
|
+
* emits files into `sharkcraft/onboarding/` and asks the user to
|
|
9
|
+
* adopt by hand. This module emits directly to `sharkcraft/`-root
|
|
10
|
+
* files so a `shrk init --infer --write` user gets a working
|
|
11
|
+
* project on day 1.
|
|
12
|
+
*
|
|
13
|
+
* - **Honest about confidence.** Inferred entries are tagged with
|
|
14
|
+
* their source signal and confidence; medium-confidence rows get a
|
|
15
|
+
* `// TODO: review` marker on the emitted line. The user can see
|
|
16
|
+
* exactly what was inferred vs hand-curated. Low-confidence rows
|
|
17
|
+
* are dropped from the populated file and reported in the
|
|
18
|
+
* companion `.inferred-report.md` so the user can find them.
|
|
19
|
+
*
|
|
20
|
+
* - **Self-contained output.** Generated files declare their own
|
|
21
|
+
* `defineKnowledgeEntry` / `definePathConvention` stubs — no
|
|
22
|
+
* `@shrkcrft/*` imports, matching the local-mirror pattern from
|
|
23
|
+
* `packages/presets/src/emit/synthesize-files.ts`.
|
|
24
|
+
*
|
|
25
|
+
* - **Deterministic.** Same input → same output, byte-for-byte.
|
|
26
|
+
* Sort lists by id where they're rendered together.
|
|
27
|
+
*
|
|
28
|
+
* - **Idempotent at the file level.** The caller decides write vs
|
|
29
|
+
* dry-run + force; this module only produces strings.
|
|
30
|
+
*/
|
|
31
|
+
// ─── Local-mirror preambles (match presets' synthesize-files.ts) ─────────────
|
|
32
|
+
const KNOWLEDGE_HELPERS = `// Local helpers — keep this file self-contained (no @shrkcrft/* imports).
|
|
33
|
+
// Generated by \`shrk init --infer\`. Edit freely.
|
|
34
|
+
|
|
35
|
+
const KnowledgePriority = {
|
|
36
|
+
Critical: 'critical',
|
|
37
|
+
High: 'high',
|
|
38
|
+
Medium: 'medium',
|
|
39
|
+
Low: 'low',
|
|
40
|
+
} as const;
|
|
41
|
+
|
|
42
|
+
const KnowledgeType = {
|
|
43
|
+
Rule: 'rule',
|
|
44
|
+
Path: 'path',
|
|
45
|
+
Template: 'template',
|
|
46
|
+
Architecture: 'architecture',
|
|
47
|
+
Technical: 'technical',
|
|
48
|
+
Convention: 'convention',
|
|
49
|
+
Workflow: 'workflow',
|
|
50
|
+
Warning: 'warning',
|
|
51
|
+
} as const;
|
|
52
|
+
|
|
53
|
+
function defineKnowledgeEntry<T>(entry: T): T {
|
|
54
|
+
return entry;
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
const PIPELINE_HELPERS = `// Local helpers — keep this file self-contained (no @shrkcrft/* imports).
|
|
58
|
+
// Generated by \`shrk init --infer\`. Edit freely.
|
|
59
|
+
|
|
60
|
+
function definePipeline<T>(pipeline: T): T {
|
|
61
|
+
return pipeline;
|
|
62
|
+
}
|
|
63
|
+
`;
|
|
64
|
+
// ─── Confidence triage ───────────────────────────────────────────────────────
|
|
65
|
+
const HIGH_CONFIDENCE_RULE_IDS = new Set([
|
|
66
|
+
'typescript.strict-mode',
|
|
67
|
+
'project.package-manager',
|
|
68
|
+
]);
|
|
69
|
+
/** Map an inferred-rule priority to a {high|medium|low} adoption tier. */
|
|
70
|
+
function ruleTier(rule) {
|
|
71
|
+
// Promote known-canonical rules.
|
|
72
|
+
if (HIGH_CONFIDENCE_RULE_IDS.has(rule.id))
|
|
73
|
+
return 'high';
|
|
74
|
+
const p = rule.priority.toLowerCase();
|
|
75
|
+
if (p === 'critical' || p === 'high')
|
|
76
|
+
return 'high';
|
|
77
|
+
if (p === 'medium')
|
|
78
|
+
return 'medium';
|
|
79
|
+
return 'low';
|
|
80
|
+
}
|
|
81
|
+
function pathTier(path) {
|
|
82
|
+
// Path conventions are inferred from disk presence — if we found the
|
|
83
|
+
// directory, the convention is real. The only "low" case is when the
|
|
84
|
+
// patterns list is empty (couldn't pin a concrete location).
|
|
85
|
+
if (path.patterns.length === 0)
|
|
86
|
+
return 'low';
|
|
87
|
+
return 'high';
|
|
88
|
+
}
|
|
89
|
+
function boundaryTier(rule) {
|
|
90
|
+
// Boundary rules require BOTH a from-pattern AND a forbidden list to
|
|
91
|
+
// be enforceable. Without forbidden imports, the rule is a label,
|
|
92
|
+
// not a gate.
|
|
93
|
+
if (rule.from.length === 0)
|
|
94
|
+
return 'low';
|
|
95
|
+
if (!rule.forbiddenImports || rule.forbiddenImports.length === 0)
|
|
96
|
+
return 'medium';
|
|
97
|
+
return 'high';
|
|
98
|
+
}
|
|
99
|
+
function pipelineTier(pipeline) {
|
|
100
|
+
// Pipelines with concrete steps that map to verification commands
|
|
101
|
+
// are higher-confidence than generic feature-dev outlines.
|
|
102
|
+
if (pipeline.steps.length === 0)
|
|
103
|
+
return 'low';
|
|
104
|
+
if (pipeline.steps.length <= 2)
|
|
105
|
+
return 'medium';
|
|
106
|
+
return 'high';
|
|
107
|
+
}
|
|
108
|
+
// ─── Renderers ──────────────────────────────────────────────────────────────
|
|
109
|
+
function renderPath(p, tier) {
|
|
110
|
+
const todo = tier === 'medium' ? '// TODO: review — confidence: medium\n ' : '';
|
|
111
|
+
const primaryPath = p.patterns[0]?.replace(/\/\*\*.*$/, '').replace(/\/\*$/, '') ?? '';
|
|
112
|
+
return ` ${todo}defineKnowledgeEntry({
|
|
113
|
+
id: ${JSON.stringify(p.id)},
|
|
114
|
+
title: ${JSON.stringify(p.title)},
|
|
115
|
+
type: KnowledgeType.Path,
|
|
116
|
+
priority: KnowledgePriority.High,
|
|
117
|
+
tags: ['paths', 'inferred'],
|
|
118
|
+
scope: ['inferred'],
|
|
119
|
+
appliesWhen: ['generate-code'],
|
|
120
|
+
content: ${JSON.stringify(p.content)},
|
|
121
|
+
metadata: {
|
|
122
|
+
path: ${JSON.stringify(primaryPath)},
|
|
123
|
+
patterns: ${JSON.stringify(p.patterns)},
|
|
124
|
+
inferredFrom: ${JSON.stringify(p.reason)},
|
|
125
|
+
},
|
|
126
|
+
})`;
|
|
127
|
+
}
|
|
128
|
+
function renderRule(r, tier) {
|
|
129
|
+
const todo = tier === 'medium' ? '// TODO: review — confidence: medium\n ' : '';
|
|
130
|
+
const priority = r.priority === 'critical' ? 'KnowledgePriority.Critical'
|
|
131
|
+
: r.priority === 'high' ? 'KnowledgePriority.High'
|
|
132
|
+
: r.priority === 'medium' ? 'KnowledgePriority.Medium'
|
|
133
|
+
: 'KnowledgePriority.Low';
|
|
134
|
+
return ` ${todo}defineKnowledgeEntry({
|
|
135
|
+
id: ${JSON.stringify(r.id)},
|
|
136
|
+
title: ${JSON.stringify(r.title)},
|
|
137
|
+
type: KnowledgeType.Rule,
|
|
138
|
+
priority: ${priority},
|
|
139
|
+
tags: ['inferred', ${JSON.stringify(r.source)}],
|
|
140
|
+
scope: ['inferred'],
|
|
141
|
+
appliesWhen: ['generate-code', 'review'],
|
|
142
|
+
content: ${JSON.stringify(r.content)},
|
|
143
|
+
metadata: {
|
|
144
|
+
inferredFrom: ${JSON.stringify(r.reason)},
|
|
145
|
+
source: ${JSON.stringify(r.source)},
|
|
146
|
+
},
|
|
147
|
+
})`;
|
|
148
|
+
}
|
|
149
|
+
function renderBoundary(b, tier) {
|
|
150
|
+
const todo = tier === 'medium' ? '// TODO: review — confidence: medium\n ' : '';
|
|
151
|
+
const forbidden = b.forbiddenImports && b.forbiddenImports.length > 0
|
|
152
|
+
? `\n forbiddenImports: ${JSON.stringify(b.forbiddenImports)},`
|
|
153
|
+
: '';
|
|
154
|
+
const allowed = b.allowedImports && b.allowedImports.length > 0
|
|
155
|
+
? `\n allowedImports: ${JSON.stringify(b.allowedImports)},`
|
|
156
|
+
: '';
|
|
157
|
+
return ` ${todo}{
|
|
158
|
+
id: ${JSON.stringify(b.id)},
|
|
159
|
+
title: ${JSON.stringify(b.title)},
|
|
160
|
+
severity: ${JSON.stringify(b.severity)},
|
|
161
|
+
from: ${JSON.stringify(b.from)},${forbidden}${allowed}
|
|
162
|
+
suggestedFix: ${JSON.stringify(b.suggestedFix)},
|
|
163
|
+
inferredFrom: ${JSON.stringify(b.reason)},
|
|
164
|
+
}`;
|
|
165
|
+
}
|
|
166
|
+
function renderPipeline(p, tier) {
|
|
167
|
+
const todo = tier === 'medium' ? '// TODO: review — confidence: medium\n ' : '';
|
|
168
|
+
const stepLines = p.steps
|
|
169
|
+
.map((s) => ` { id: ${JSON.stringify(s)}, type: 'command', description: ${JSON.stringify(s)} }`)
|
|
170
|
+
.join(',\n');
|
|
171
|
+
return ` ${todo}definePipeline({
|
|
172
|
+
id: ${JSON.stringify(p.id)},
|
|
173
|
+
title: ${JSON.stringify(p.title)},
|
|
174
|
+
description: ${JSON.stringify(p.description)},
|
|
175
|
+
tags: ['inferred'],
|
|
176
|
+
steps: [
|
|
177
|
+
${stepLines}
|
|
178
|
+
],
|
|
179
|
+
metadata: {
|
|
180
|
+
inferredFrom: ${JSON.stringify(p.reason)},
|
|
181
|
+
},
|
|
182
|
+
})`;
|
|
183
|
+
}
|
|
184
|
+
// ─── File builders ──────────────────────────────────────────────────────────
|
|
185
|
+
function buildConfigFile(opts) {
|
|
186
|
+
return (`// Generated by \`shrk init --infer\`. Edit freely; SharkCraft will not\n` +
|
|
187
|
+
`// regenerate this file. Re-run \`shrk init --infer --force\` to overwrite.\n\n` +
|
|
188
|
+
`const config = {\n` +
|
|
189
|
+
` projectName: ${JSON.stringify(opts.projectName)},\n` +
|
|
190
|
+
` description: ${JSON.stringify(opts.description)},\n` +
|
|
191
|
+
` pathFiles: ${JSON.stringify(opts.includePaths ? ['paths.ts'] : [])},\n` +
|
|
192
|
+
` ruleFiles: ${JSON.stringify(opts.includeRules ? ['rules.ts'] : [])},\n` +
|
|
193
|
+
` boundaryFiles: ${JSON.stringify(opts.includeBoundaries ? ['boundaries.ts'] : [])},\n` +
|
|
194
|
+
` pipelineFiles: ${JSON.stringify(opts.includePipelines ? ['pipelines.ts'] : [])},\n` +
|
|
195
|
+
` knowledgeFiles: ${JSON.stringify(['knowledge.ts'])},\n` +
|
|
196
|
+
` templateFiles: ${JSON.stringify([])},\n` +
|
|
197
|
+
` docsFiles: ${JSON.stringify([])},\n` +
|
|
198
|
+
` defaultMaxTokens: 3500,\n` +
|
|
199
|
+
`};\n\nexport default config;\n`);
|
|
200
|
+
}
|
|
201
|
+
function buildPathsFile(rendered) {
|
|
202
|
+
return (KNOWLEDGE_HELPERS +
|
|
203
|
+
'\nconst paths = [\n' +
|
|
204
|
+
rendered.join(',\n') +
|
|
205
|
+
(rendered.length > 0 ? ',\n' : '') +
|
|
206
|
+
'];\n\nexport default paths;\n');
|
|
207
|
+
}
|
|
208
|
+
function buildRulesFile(rendered) {
|
|
209
|
+
return (KNOWLEDGE_HELPERS +
|
|
210
|
+
'\nconst rules = [\n' +
|
|
211
|
+
rendered.join(',\n') +
|
|
212
|
+
(rendered.length > 0 ? ',\n' : '') +
|
|
213
|
+
'];\n\nexport default rules;\n');
|
|
214
|
+
}
|
|
215
|
+
function buildBoundariesFile(rendered) {
|
|
216
|
+
return ('// Generated by `shrk init --infer`. Plain default-export array — the\n' +
|
|
217
|
+
'// boundaries loader accepts any object with id/title/severity/from.\n\n' +
|
|
218
|
+
'export default [\n' +
|
|
219
|
+
rendered.join(',\n') +
|
|
220
|
+
(rendered.length > 0 ? ',\n' : '') +
|
|
221
|
+
'];\n');
|
|
222
|
+
}
|
|
223
|
+
function buildPipelinesFile(rendered) {
|
|
224
|
+
return (PIPELINE_HELPERS +
|
|
225
|
+
'\nconst pipelines = [\n' +
|
|
226
|
+
rendered.join(',\n') +
|
|
227
|
+
(rendered.length > 0 ? ',\n' : '') +
|
|
228
|
+
'];\n\nexport default pipelines;\n');
|
|
229
|
+
}
|
|
230
|
+
function buildKnowledgeSeed(projectName, description) {
|
|
231
|
+
// Minimal but useful knowledge seed — these aren't really inferable,
|
|
232
|
+
// but every repo benefits from the agent-briefing + safety baseline.
|
|
233
|
+
return (KNOWLEDGE_HELPERS +
|
|
234
|
+
'\n' +
|
|
235
|
+
`export const projectOverview = defineKnowledgeEntry({
|
|
236
|
+
id: 'project.overview',
|
|
237
|
+
title: ${JSON.stringify(projectName + ' — project overview')},
|
|
238
|
+
type: KnowledgeType.Architecture,
|
|
239
|
+
priority: KnowledgePriority.High,
|
|
240
|
+
tags: ['overview', 'inferred'],
|
|
241
|
+
scope: ['inferred'],
|
|
242
|
+
appliesWhen: ['onboard', 'plan-work'],
|
|
243
|
+
summary: ${JSON.stringify(description || 'High-level overview of this project.')},
|
|
244
|
+
content: ${JSON.stringify(description || 'High-level overview of this project. Generated by shrk init --infer; replace with project-specific context.')},
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
export const agentBriefing = defineKnowledgeEntry({
|
|
248
|
+
id: 'agent.briefing',
|
|
249
|
+
title: 'AI agent briefing',
|
|
250
|
+
type: KnowledgeType.Convention,
|
|
251
|
+
priority: KnowledgePriority.Critical,
|
|
252
|
+
tags: ['agent', 'safety'],
|
|
253
|
+
scope: ['agent'],
|
|
254
|
+
appliesWhen: ['agent-start', 'agent-plan'],
|
|
255
|
+
content: \`When working in this repo as an AI agent:
|
|
256
|
+
1. Read \\\`shrk brief\\\` for the focused project context (rules + paths + verification).
|
|
257
|
+
2. Use \\\`shrk task "<task>"\\\` to get a per-task packet (relevant rules + templates + commands).
|
|
258
|
+
3. Generate code via \\\`shrk gen <template> <name> --dry-run --save-plan plan.json\\\`, then apply with \\\`shrk apply plan.json --verify-signature --validate\\\`.
|
|
259
|
+
4. Never bypass \\\`shrk check boundaries\\\` — it gates architecture violations.\`,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
export const generationSafety = defineKnowledgeEntry({
|
|
263
|
+
id: 'safety.generation',
|
|
264
|
+
title: 'Generation safety',
|
|
265
|
+
type: KnowledgeType.Warning,
|
|
266
|
+
priority: KnowledgePriority.Critical,
|
|
267
|
+
tags: ['safety', 'generation'],
|
|
268
|
+
scope: ['generation'],
|
|
269
|
+
appliesWhen: ['generate-code', 'overwrite-file'],
|
|
270
|
+
content: \`shrk gen defaults to dry-run. A real write requires --write AND a clean plan (no conflicts). AI agents must call create_generation_plan via MCP first — never write files directly through MCP.\`,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
export default [projectOverview, agentBriefing, generationSafety];
|
|
274
|
+
`);
|
|
275
|
+
}
|
|
276
|
+
// ─── Confidence report renderers ─────────────────────────────────────────────
|
|
277
|
+
function buildReportMarkdown(report, projectName) {
|
|
278
|
+
const lines = [];
|
|
279
|
+
lines.push(`# Inferred from your codebase`);
|
|
280
|
+
lines.push('');
|
|
281
|
+
lines.push(`\`shrk init --infer\` scanned ${projectName} and produced the populated ` +
|
|
282
|
+
`\`sharkcraft/*.ts\` files alongside this report. Re-run with \`--force\` to regenerate.`);
|
|
283
|
+
lines.push('');
|
|
284
|
+
lines.push(`## ✅ Adopted directly (${report.adoptedHigh.length} entries — high confidence)`);
|
|
285
|
+
lines.push('');
|
|
286
|
+
if (report.adoptedHigh.length === 0) {
|
|
287
|
+
lines.push('_None._');
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
for (const line of report.adoptedHigh) {
|
|
291
|
+
lines.push(`- **[${line.kind}] \`${line.id}\`** — ${line.title} _(${line.reason})_`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
lines.push('');
|
|
295
|
+
lines.push(`## 🟡 Adopted with review marker (${report.adoptedMedium.length} entries — medium confidence)`);
|
|
296
|
+
lines.push('');
|
|
297
|
+
lines.push('These entries were included in the populated files with a `// TODO: review` ' +
|
|
298
|
+
'comment. Read them, confirm they match your team\'s actual practice, then remove the marker.');
|
|
299
|
+
lines.push('');
|
|
300
|
+
if (report.adoptedMedium.length === 0) {
|
|
301
|
+
lines.push('_None._');
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
for (const line of report.adoptedMedium) {
|
|
305
|
+
lines.push(`- **[${line.kind}] \`${line.id}\`** — ${line.title} _(${line.reason})_`);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
lines.push('');
|
|
309
|
+
lines.push(`## ⚠️ Not adopted (${report.dropped.length} entries — low confidence)`);
|
|
310
|
+
lines.push('');
|
|
311
|
+
lines.push('These entries had weak signals — either incomplete data or generic patterns that ' +
|
|
312
|
+
'might not reflect your real conventions. Review the draft versions under ' +
|
|
313
|
+
'`sharkcraft/onboarding/` (after running `shrk onboard --write-drafts`) and adopt any that apply.');
|
|
314
|
+
lines.push('');
|
|
315
|
+
if (report.dropped.length === 0) {
|
|
316
|
+
lines.push('_None — all signals were strong enough to adopt._');
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
for (const line of report.dropped) {
|
|
320
|
+
lines.push(`- **[${line.kind}] \`${line.id}\`** — ${line.title} _(${line.reason})_`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
lines.push('');
|
|
324
|
+
lines.push(`## ✍️ What shrk can't infer (author these by hand)`);
|
|
325
|
+
lines.push('');
|
|
326
|
+
lines.push('These categories rely on team knowledge that\'s not visible in code or config. ' +
|
|
327
|
+
'Add them to `sharkcraft/knowledge.ts` to make Claude aware:');
|
|
328
|
+
lines.push('');
|
|
329
|
+
for (const item of report.notInferable)
|
|
330
|
+
lines.push(`- ${item}`);
|
|
331
|
+
lines.push('');
|
|
332
|
+
lines.push('---');
|
|
333
|
+
lines.push('');
|
|
334
|
+
lines.push(`_Generated by \`shrk init --infer\`. This report is regenerated each ` +
|
|
335
|
+
`time you re-run with \`--force\`._`);
|
|
336
|
+
return lines.join('\n') + '\n';
|
|
337
|
+
}
|
|
338
|
+
const NOT_INFERABLE_DEFAULTS = [
|
|
339
|
+
'Project-specific architectural decisions ("we chose X over Y because…").',
|
|
340
|
+
'Deprecated paths / legacy code to avoid ("don\'t add new code to legacy/").',
|
|
341
|
+
'Non-obvious conventions ("our pagination uses cursor, not offset").',
|
|
342
|
+
'Cross-cutting concerns ("all writes go through the audit-log middleware").',
|
|
343
|
+
'Recently-changed patterns ("DTOs migrated to class-validator last month — old code uses Zod").',
|
|
344
|
+
'Team workflow conventions ("review with two approvals before merge to main").',
|
|
345
|
+
];
|
|
346
|
+
// ─── Public entry point ─────────────────────────────────────────────────────
|
|
347
|
+
/**
|
|
348
|
+
* Convert an {@link IOnboardingPlan} into a populated set of
|
|
349
|
+
* `sharkcraft/*.ts` files plus a companion confidence report.
|
|
350
|
+
*
|
|
351
|
+
* The caller is responsible for actually writing the files; this
|
|
352
|
+
* function is pure (input plan → output strings).
|
|
353
|
+
*/
|
|
354
|
+
export function synthesizeFromOnboarding(plan) {
|
|
355
|
+
const report = { adoptedHigh: [], adoptedMedium: [], dropped: [] };
|
|
356
|
+
// ── Triage paths ────────────────────────────────────────────────────
|
|
357
|
+
const renderedPaths = [];
|
|
358
|
+
for (const p of [...plan.inferredPathConventions].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
359
|
+
const tier = pathTier(p);
|
|
360
|
+
if (tier === 'low') {
|
|
361
|
+
report.dropped.push({ kind: 'path', id: p.id, title: p.title, reason: p.reason });
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
renderedPaths.push(renderPath(p, tier));
|
|
365
|
+
(tier === 'high' ? report.adoptedHigh : report.adoptedMedium).push({
|
|
366
|
+
kind: 'path',
|
|
367
|
+
id: p.id,
|
|
368
|
+
title: p.title,
|
|
369
|
+
reason: p.reason,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
// ── Triage rules ────────────────────────────────────────────────────
|
|
373
|
+
const renderedRules = [];
|
|
374
|
+
for (const r of [...plan.inferredRules].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
375
|
+
const tier = ruleTier(r);
|
|
376
|
+
if (tier === 'low') {
|
|
377
|
+
report.dropped.push({ kind: 'rule', id: r.id, title: r.title, reason: r.reason });
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
renderedRules.push(renderRule(r, tier));
|
|
381
|
+
(tier === 'high' ? report.adoptedHigh : report.adoptedMedium).push({
|
|
382
|
+
kind: 'rule',
|
|
383
|
+
id: r.id,
|
|
384
|
+
title: r.title,
|
|
385
|
+
reason: r.reason,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
// ── Triage boundaries ──────────────────────────────────────────────
|
|
389
|
+
const renderedBoundaries = [];
|
|
390
|
+
for (const b of [...plan.inferredBoundaryRules].sort((a, b2) => a.id.localeCompare(b2.id))) {
|
|
391
|
+
const tier = boundaryTier(b);
|
|
392
|
+
if (tier === 'low') {
|
|
393
|
+
report.dropped.push({ kind: 'boundary', id: b.id, title: b.title, reason: b.reason });
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
renderedBoundaries.push(renderBoundary(b, tier));
|
|
397
|
+
(tier === 'high' ? report.adoptedHigh : report.adoptedMedium).push({
|
|
398
|
+
kind: 'boundary',
|
|
399
|
+
id: b.id,
|
|
400
|
+
title: b.title,
|
|
401
|
+
reason: b.reason,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
// ── Triage pipelines ───────────────────────────────────────────────
|
|
405
|
+
const renderedPipelines = [];
|
|
406
|
+
for (const p of [...plan.inferredPipelines].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
407
|
+
const tier = pipelineTier(p);
|
|
408
|
+
if (tier === 'low') {
|
|
409
|
+
report.dropped.push({ kind: 'pipeline', id: p.id, title: p.title, reason: p.reason });
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
renderedPipelines.push(renderPipeline(p, tier));
|
|
413
|
+
(tier === 'high' ? report.adoptedHigh : report.adoptedMedium).push({
|
|
414
|
+
kind: 'pipeline',
|
|
415
|
+
id: p.id,
|
|
416
|
+
title: p.title,
|
|
417
|
+
reason: p.reason,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
// ── Templates are dropped wholesale into the report — emitting a
|
|
421
|
+
// runnable template from inference is too speculative to populate
|
|
422
|
+
// automatically. The user gets them as drafts via `shrk onboard
|
|
423
|
+
// --write-drafts`.
|
|
424
|
+
for (const t of plan.inferredTemplateCandidates) {
|
|
425
|
+
report.dropped.push({
|
|
426
|
+
kind: 'template',
|
|
427
|
+
id: t.id,
|
|
428
|
+
title: t.name,
|
|
429
|
+
reason: `${t.reason} (templates require manual review; see sharkcraft/onboarding/inferred-templates.draft.ts after \`shrk onboard --write-drafts\`)`,
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
// ── Verification commands surface in the report only (consumed via
|
|
433
|
+
// sharkcraft.config.ts verificationCommands[]; not emitted as
|
|
434
|
+
// `sharkcraft/*.ts` here to avoid duplicating config shape).
|
|
435
|
+
for (const v of plan.inferredVerificationCommands) {
|
|
436
|
+
report.adoptedHigh.push({
|
|
437
|
+
kind: 'verification',
|
|
438
|
+
id: v.id,
|
|
439
|
+
title: `${v.label}: \`${v.command}\``,
|
|
440
|
+
reason: v.reason,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
const projectName = plan.projectSummary.projectName ?? 'project';
|
|
444
|
+
const description = plan.projectSummary.description ?? '';
|
|
445
|
+
const files = [];
|
|
446
|
+
files.push({
|
|
447
|
+
path: 'sharkcraft.config.ts',
|
|
448
|
+
kind: 'config',
|
|
449
|
+
content: buildConfigFile({
|
|
450
|
+
projectName,
|
|
451
|
+
description,
|
|
452
|
+
includePaths: renderedPaths.length > 0,
|
|
453
|
+
includeRules: renderedRules.length > 0,
|
|
454
|
+
includeBoundaries: renderedBoundaries.length > 0,
|
|
455
|
+
includePipelines: renderedPipelines.length > 0,
|
|
456
|
+
}),
|
|
457
|
+
});
|
|
458
|
+
files.push({
|
|
459
|
+
path: 'knowledge.ts',
|
|
460
|
+
kind: 'knowledge',
|
|
461
|
+
content: buildKnowledgeSeed(projectName, description),
|
|
462
|
+
});
|
|
463
|
+
if (renderedPaths.length > 0) {
|
|
464
|
+
files.push({ path: 'paths.ts', kind: 'paths', content: buildPathsFile(renderedPaths) });
|
|
465
|
+
}
|
|
466
|
+
if (renderedRules.length > 0) {
|
|
467
|
+
files.push({ path: 'rules.ts', kind: 'rules', content: buildRulesFile(renderedRules) });
|
|
468
|
+
}
|
|
469
|
+
if (renderedBoundaries.length > 0) {
|
|
470
|
+
files.push({
|
|
471
|
+
path: 'boundaries.ts',
|
|
472
|
+
kind: 'boundaries',
|
|
473
|
+
content: buildBoundariesFile(renderedBoundaries),
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
if (renderedPipelines.length > 0) {
|
|
477
|
+
files.push({
|
|
478
|
+
path: 'pipelines.ts',
|
|
479
|
+
kind: 'pipelines',
|
|
480
|
+
content: buildPipelinesFile(renderedPipelines),
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
const fullReport = {
|
|
484
|
+
adoptedHigh: report.adoptedHigh,
|
|
485
|
+
adoptedMedium: report.adoptedMedium,
|
|
486
|
+
dropped: report.dropped,
|
|
487
|
+
notInferable: NOT_INFERABLE_DEFAULTS,
|
|
488
|
+
};
|
|
489
|
+
files.push({
|
|
490
|
+
path: '.inferred-report.md',
|
|
491
|
+
kind: 'report-md',
|
|
492
|
+
content: buildReportMarkdown(fullReport, projectName),
|
|
493
|
+
});
|
|
494
|
+
files.push({
|
|
495
|
+
path: '.inferred-report.json',
|
|
496
|
+
kind: 'report-json',
|
|
497
|
+
content: JSON.stringify({
|
|
498
|
+
schema: 'sharkcraft.inferred-report/v1',
|
|
499
|
+
generatedAt: new Date().toISOString().slice(0, 10),
|
|
500
|
+
projectName,
|
|
501
|
+
adoptedHigh: fullReport.adoptedHigh,
|
|
502
|
+
adoptedMedium: fullReport.adoptedMedium,
|
|
503
|
+
dropped: fullReport.dropped,
|
|
504
|
+
notInferable: fullReport.notInferable,
|
|
505
|
+
}, null, 2) + '\n',
|
|
506
|
+
});
|
|
507
|
+
return { files, report: fullReport };
|
|
508
|
+
}
|
package/dist/task-packet.d.ts
CHANGED
|
@@ -95,6 +95,19 @@ export interface IBuildTaskPacketOptions {
|
|
|
95
95
|
scope?: readonly string[];
|
|
96
96
|
/** When true, include per-kind ranking reasons in the packet. */
|
|
97
97
|
explainRanking?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* When true (default), apply tight caps to the packet — top-5 rules /
|
|
100
|
+
* templates / paths and per-field caps on actionHints aggregates.
|
|
101
|
+
*
|
|
102
|
+
* When false, returns the full ranking + aggregated hints (older behavior).
|
|
103
|
+
* Use this when an agent explicitly asks for an exhaustive packet via
|
|
104
|
+
* `shrk task --full`.
|
|
105
|
+
*
|
|
106
|
+
* Tightening exists because the original benchmark called out token
|
|
107
|
+
* overhead as half of why shrk was net-negative; the default packet should
|
|
108
|
+
* be lean unless the caller opts in.
|
|
109
|
+
*/
|
|
110
|
+
compact?: boolean;
|
|
98
111
|
}
|
|
99
112
|
/**
|
|
100
113
|
* Build a deterministic, AI-ready bundle for a single task. Pure orchestration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-packet.d.ts","sourceRoot":"","sources":["../src/task-packet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"task-packet.d.ts","sourceRoot":"","sources":["../src/task-packet.ts"],"names":[],"mappings":"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"}
|
package/dist/task-packet.js
CHANGED
|
@@ -2,6 +2,23 @@ import { buildContext } from '@shrkcrft/context';
|
|
|
2
2
|
import { aggregateActionHints, } from '@shrkcrft/knowledge';
|
|
3
3
|
import { rankAll } from "./task-ranker.js";
|
|
4
4
|
import { buildProjectOverview, renderOverviewText } from "./project-overview.js";
|
|
5
|
+
import { resolveVerificationCommands } from "./resolve-verification-commands.js";
|
|
6
|
+
/**
|
|
7
|
+
* Per-field caps applied to the packet when `compact: true`.
|
|
8
|
+
* Keeps the JSON small while still covering the highest-signal hits.
|
|
9
|
+
*/
|
|
10
|
+
const COMPACT_CAPS = {
|
|
11
|
+
rules: 5,
|
|
12
|
+
paths: 5,
|
|
13
|
+
templates: 3,
|
|
14
|
+
commands: 5,
|
|
15
|
+
mcpTools: 5,
|
|
16
|
+
forbiddenActions: 5,
|
|
17
|
+
verificationCommands: 5,
|
|
18
|
+
safetyNotes: 5,
|
|
19
|
+
relatedTemplates: 5,
|
|
20
|
+
relatedPathConventions: 5,
|
|
21
|
+
};
|
|
5
22
|
function findPipelinesByTags(pipelines, ...tags) {
|
|
6
23
|
return pipelines.filter((p) => p.tags?.some((t) => tags.includes(t.toLowerCase())));
|
|
7
24
|
}
|
|
@@ -46,6 +63,7 @@ function pickPipelines(pipelines, task) {
|
|
|
46
63
|
*/
|
|
47
64
|
export function buildTaskPacket(inspection, task, options = {}) {
|
|
48
65
|
const maxTokens = options.maxTokens ?? 3500;
|
|
66
|
+
const compact = options.compact !== false;
|
|
49
67
|
const overview = buildProjectOverview(inspection.workspace, inspection.config?.projectName);
|
|
50
68
|
const overviewText = renderOverviewText(overview);
|
|
51
69
|
const contextResult = buildContext(inspection.knowledgeEntries, {
|
|
@@ -55,17 +73,41 @@ export function buildTaskPacket(inspection, task, options = {}) {
|
|
|
55
73
|
projectOverview: overviewText,
|
|
56
74
|
});
|
|
57
75
|
// ── Deterministic ranker — replaces the old substring search ─────────
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const
|
|
76
|
+
// Compact mode requests top-5; full mode requests top-10 (the original).
|
|
77
|
+
const rankN = compact ? 8 : 10;
|
|
78
|
+
const ranking = rankAll(inspection, task, rankN);
|
|
79
|
+
const relevantRules = compact
|
|
80
|
+
? ranking.rules.slice(0, COMPACT_CAPS.rules).map((r) => r.item)
|
|
81
|
+
: ranking.rules.map((r) => r.item);
|
|
82
|
+
const relevantPaths = compact
|
|
83
|
+
? ranking.paths.slice(0, COMPACT_CAPS.paths).map((r) => r.item)
|
|
84
|
+
: ranking.paths.map((r) => r.item);
|
|
85
|
+
const relevantTemplates = compact
|
|
86
|
+
? ranking.templates.slice(0, COMPACT_CAPS.templates).map((r) => r.item)
|
|
87
|
+
: ranking.templates.map((r) => r.item);
|
|
62
88
|
// Aggregate hints from the *ranked* knowledge so unrelated entries don't
|
|
63
89
|
// leak into the action-hints surface.
|
|
64
90
|
const hintCorpus = [
|
|
65
91
|
...ranking.rules.slice(0, 8).map((r) => r.item),
|
|
66
92
|
...inspection.knowledgeEntries.filter((e) => e.priority === 'critical' || e.priority === 'high'),
|
|
67
93
|
];
|
|
68
|
-
const
|
|
94
|
+
const actionHintsRaw = aggregateActionHints(hintCorpus);
|
|
95
|
+
// Cap each per-field aggregate when compact. Aggregator already
|
|
96
|
+
// priority-sorts entries, so the top-N kept here is the highest-signal
|
|
97
|
+
// slice of each field. `requiresHumanReview` / `writePolicy` /
|
|
98
|
+
// `preferredFlow` / `contributingEntries` are unchanged.
|
|
99
|
+
const actionHints = compact
|
|
100
|
+
? {
|
|
101
|
+
...actionHintsRaw,
|
|
102
|
+
commands: actionHintsRaw.commands.slice(0, COMPACT_CAPS.commands),
|
|
103
|
+
mcpTools: actionHintsRaw.mcpTools.slice(0, COMPACT_CAPS.mcpTools),
|
|
104
|
+
forbiddenActions: actionHintsRaw.forbiddenActions.slice(0, COMPACT_CAPS.forbiddenActions),
|
|
105
|
+
verificationCommands: actionHintsRaw.verificationCommands.slice(0, COMPACT_CAPS.verificationCommands),
|
|
106
|
+
safetyNotes: actionHintsRaw.safetyNotes.slice(0, COMPACT_CAPS.safetyNotes),
|
|
107
|
+
relatedTemplates: actionHintsRaw.relatedTemplates.slice(0, COMPACT_CAPS.relatedTemplates),
|
|
108
|
+
relatedPathConventions: actionHintsRaw.relatedPathConventions.slice(0, COMPACT_CAPS.relatedPathConventions),
|
|
109
|
+
}
|
|
110
|
+
: actionHintsRaw;
|
|
69
111
|
// Pipelines: prefer ranker output, then verb fallback for context-only.
|
|
70
112
|
const rankedPipelines = ranking.pipelines.slice(0, 3).map((p) => ({
|
|
71
113
|
pipelineId: p.item.id,
|
|
@@ -89,6 +131,17 @@ export function buildTaskPacket(inspection, task, options = {}) {
|
|
|
89
131
|
confidence: (r.score >= 15 ? 'high' : r.score >= 9 ? 'medium' : 'low'),
|
|
90
132
|
reasons: r.reasons,
|
|
91
133
|
}));
|
|
134
|
+
// Verification commands: prefer the matched pipeline's declared gates, then
|
|
135
|
+
// the config's trusted gate set, then the knowledge action-hint defaults —
|
|
136
|
+
// so the packet tells the agent to run the gates the pack actually declares
|
|
137
|
+
// (e.g. `bun test` / `bun x tsc … --noEmit`) instead of a generic fallback.
|
|
138
|
+
const resolvedVerification = resolveVerificationCommands(inspection, {
|
|
139
|
+
pipelineIds: recommendedPipelines.map((p) => p.pipelineId),
|
|
140
|
+
knowledgeDefaults: actionHints.verificationCommands,
|
|
141
|
+
});
|
|
142
|
+
const verificationCommands = compact
|
|
143
|
+
? resolvedVerification.slice(0, COMPACT_CAPS.verificationCommands)
|
|
144
|
+
: resolvedVerification;
|
|
92
145
|
const tokenEstimate = contextResult.totalTokens +
|
|
93
146
|
Math.ceil((actionHints.commands.length + actionHints.mcpTools.length + actionHints.verificationCommands.length) *
|
|
94
147
|
4);
|
|
@@ -144,7 +197,7 @@ export function buildTaskPacket(inspection, task, options = {}) {
|
|
|
144
197
|
recommendedMcpTools: actionHints.mcpTools.map((t) => t.tool),
|
|
145
198
|
recommendedCliCommands: actionHints.commands.map((c) => typeof c === 'string' ? c : c.command),
|
|
146
199
|
forbiddenActions: actionHints.forbiddenActions,
|
|
147
|
-
verificationCommands
|
|
200
|
+
verificationCommands,
|
|
148
201
|
humanReviewPoints,
|
|
149
202
|
tokenEstimate,
|
|
150
203
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-ranker.d.ts","sourceRoot":"","sources":["../src/task-ranker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;;;;GAQG;AAEH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"task-ranker.d.ts","sourceRoot":"","sources":["../src/task-ranker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAElE;;;;;;;;GAQG;AAEH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAmOD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,IAAI,EAAE,MAAM,GACX,WAAW,CAAC,eAAe,CAAC,EAAE,CAqBhC;AAGD,wBAAgB,aAAa,CAC3B,SAAS,EAAE,SAAS,mBAAmB,EAAE,EACzC,IAAI,EAAE,MAAM,GACX,WAAW,CAAC,mBAAmB,CAAC,EAAE,CAiBpC;AAGD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,IAAI,EAAE,MAAM,GACX,WAAW,CAAC,eAAe,CAAC,EAAE,CAEhC;AAGD,wBAAgB,aAAa,CAC3B,SAAS,EAAE,SAAS,mBAAmB,EAAE,EACzC,IAAI,EAAE,MAAM,GACX,WAAW,CAAC,mBAAmB,CAAC,EAAE,CAkCpC;AAGD,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,WAAW,CAAC,OAAO,CAAC,EAAE,CAgCxB;AAGD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,WAAW,CAAC,eAAe,CAAC,EAAE,CAAC;IACtC,KAAK,EAAE,WAAW,CAAC,eAAe,CAAC,EAAE,CAAC;IACtC,SAAS,EAAE,WAAW,CAAC,mBAAmB,CAAC,EAAE,CAAC;IAC9C,SAAS,EAAE,WAAW,CAAC,mBAAmB,CAAC,EAAE,CAAC;IAC9C,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;CACjC;AAED,wBAAgB,OAAO,CACrB,UAAU,EAAE;IACV,gBAAgB,EAAE,SAAS,eAAe,EAAE,CAAC;IAC7C,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC1C,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC1C,cAAc,EAAE;QAAE,IAAI,EAAE,MAAM,SAAS,OAAO,EAAE,CAAA;KAAE,CAAC;IACnD,SAAS,EAAE;QAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAC3C,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,SAAS,eAAe,EAAE,CAAA;KAAE,CAAC;IACxD,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,SAAS,eAAe,EAAE,CAAA;KAAE,CAAC;CACzD,EACD,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,MAAW,GACjB,cAAc,CAiEhB;AAGD,wBAAgB,aAAa,CAAC,CAAC,EAC7B,KAAK,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,EAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,EAC7B,KAAK,GAAE,MAAU,GAChB,MAAM,CAKR;AAED,uFAAuF;AACvF,YAAY,EAAE,eAAe,EAAE,CAAC"}
|