@webpresso/agent-kit 0.21.4 → 0.23.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +93 -66
- package/bin/_run.js +143 -1
- package/bin/runtime-manifest.json +40 -0
- package/catalog/AGENTS.md.tpl +7 -6
- package/catalog/agent/commands/plan-refine.md +3 -3
- package/catalog/agent/commands/pll.md +2 -0
- package/catalog/agent/guides/parallel-execution.md +2 -0
- package/catalog/agent/rules/extraction-parity.md +27 -1
- package/catalog/agent/rules/public-package-safety.md +24 -1
- package/catalog/agent/skills/plan-refine/SKILL.md +5 -4
- package/catalog/agent/skills/pll/SKILL.md +1 -0
- package/catalog/base-kit/.github/workflows/ci.webpresso.yml.tmpl +33 -0
- package/catalog/base-kit/commitlint.config.ts.tmpl +1 -3
- package/catalog/base-kit/e2e/fixtures/smoke.html.tmpl +13 -0
- package/catalog/base-kit/e2e/smoke.spec.ts.tmpl +13 -0
- package/catalog/base-kit/oxlint.config.ts.tmpl +26 -0
- package/catalog/base-kit/playwright.config.ts.tmpl +10 -0
- package/catalog/base-kit/src/quality-sample.test.ts.tmpl +19 -0
- package/catalog/base-kit/src/quality-sample.ts.tmpl +11 -0
- package/catalog/base-kit/stryker.config.ts.tmpl +14 -0
- package/catalog/base-kit/tsconfig.json.tmpl +9 -0
- package/catalog/base-kit/vitest.config.ts.tmpl +10 -0
- package/catalog/docs/templates/adr.md +1 -1
- package/catalog/docs/templates/blueprint.md +2 -0
- package/catalog/docs/templates/blueprint.yaml +16 -15
- package/catalog/docs/templates/guide.md +1 -1
- package/catalog/docs/templates/postmortem.md +1 -1
- package/catalog/docs/templates/research.md +1 -1
- package/catalog/docs/templates/runbook.md +1 -1
- package/catalog/docs/templates/system.md +12 -3
- package/catalog/docs/templates/tech-debt.md +1 -0
- package/commands/blueprint.md +10 -12
- package/dist/esm/audit/blueprint-db-consistency.d.ts +1 -1
- package/dist/esm/audit/blueprint-db-consistency.js +6 -8
- package/dist/esm/audit/blueprint-lifecycle-sql.js +10 -3
- package/dist/esm/audit/cloudflare-deploy-contract.d.ts +3 -0
- package/dist/esm/audit/cloudflare-deploy-contract.js +64 -0
- package/dist/esm/audit/no-legacy-cli-bin.d.ts +3 -0
- package/dist/esm/audit/no-legacy-cli-bin.js +100 -0
- package/dist/esm/audit/package-surface.js +14 -1
- package/dist/esm/audit/repo-guardrails.js +40 -13
- package/dist/esm/audit/resolve-audit-script.d.ts +24 -0
- package/dist/esm/audit/resolve-audit-script.js +27 -0
- package/dist/esm/audit/roadmap-links.js +23 -10
- package/dist/esm/blueprint/core/schema.d.ts +8 -8
- package/dist/esm/blueprint/core/schema.js +2 -2
- package/dist/esm/blueprint/db/enums.d.ts +1 -1
- package/dist/esm/blueprint/db/ingester.js +18 -10
- package/dist/esm/blueprint/index.d.ts +0 -1
- package/dist/esm/blueprint/index.js +0 -2
- package/dist/esm/blueprint/lifecycle/audit.js +9 -2
- package/dist/esm/blueprint/lifecycle/local.js +15 -4
- package/dist/esm/blueprint/local.d.ts +0 -3
- package/dist/esm/blueprint/local.js +0 -2
- package/dist/esm/blueprint/service/BlueprintCreationService.js +16 -8
- package/dist/esm/blueprint/service/BlueprintService.js +37 -19
- package/dist/esm/blueprint/service/scanner.js +73 -9
- package/dist/esm/blueprint/tracked-document/schema.d.ts +2 -2
- package/dist/esm/blueprint/utils/document-paths.d.ts +23 -0
- package/dist/esm/blueprint/utils/document-paths.js +91 -0
- package/dist/esm/blueprint/utils/package-assets.d.ts +11 -0
- package/dist/esm/blueprint/utils/package-assets.js +33 -4
- package/dist/esm/build/package-manifest.js +7 -0
- package/dist/esm/build/release-policy.d.ts +27 -0
- package/dist/esm/build/release-policy.js +29 -0
- package/dist/esm/build/runtime-targets.d.ts +13 -0
- package/dist/esm/build/runtime-targets.js +48 -0
- package/dist/esm/build/sync-catalog-doc-templates.d.ts +23 -0
- package/dist/esm/build/sync-catalog-doc-templates.js +93 -0
- package/dist/esm/cli/auto-update/detect-pm.d.ts +15 -0
- package/dist/esm/cli/auto-update/detect-pm.js +24 -9
- package/dist/esm/cli/auto-update/skip.js +9 -1
- package/dist/esm/cli/bundle/agent-command-inventory.d.ts +120 -0
- package/dist/esm/cli/bundle/agent-command-inventory.js +100 -0
- package/dist/esm/cli/bundle/index.d.ts +17 -0
- package/dist/esm/cli/bundle/index.js +15 -0
- package/dist/esm/cli/cli.d.ts +1 -1
- package/dist/esm/cli/cli.js +49 -5
- package/dist/esm/cli/commands/audit-core.d.ts +1 -1
- package/dist/esm/cli/commands/audit.js +4 -7
- package/dist/esm/cli/commands/blueprint/router.js +16 -10
- package/dist/esm/cli/commands/blueprint/template-resolver.js +8 -4
- package/dist/esm/cli/commands/hook.d.ts +8 -0
- package/dist/esm/cli/commands/hook.js +47 -0
- package/dist/esm/cli/commands/init/host-visibility.js +4 -2
- package/dist/esm/cli/commands/init/index.js +80 -7
- package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +12 -0
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +142 -7
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/codex-ownership.js +9 -1
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +130 -20
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.d.ts +65 -0
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.js +64 -0
- package/dist/esm/cli/commands/package-manager.d.ts +15 -0
- package/dist/esm/cli/commands/package-manager.js +42 -0
- package/dist/esm/cli/commands/test.d.ts +1 -0
- package/dist/esm/cli/commands/test.js +2 -1
- package/dist/esm/cli/commands/typecheck.js +10 -19
- package/dist/esm/cli/package-scripts.d.ts +12 -0
- package/dist/esm/cli/package-scripts.js +59 -0
- package/dist/esm/cli/utils.js +3 -22
- package/dist/esm/cli/wp-extensions.d.ts +14 -0
- package/dist/esm/cli/wp-extensions.js +34 -0
- package/dist/esm/config/docs-lint/schemas/common.d.ts +1 -1
- package/dist/esm/config/docs-lint/schemas/implementation-plan.d.ts +2 -2
- package/dist/esm/config/docs-lint/schemas/parent-roadmap.d.ts +1 -1
- package/dist/esm/config/stryker/index.d.ts +85 -0
- package/dist/esm/config/stryker/index.js +31 -0
- package/dist/esm/e2e/command-builder.js +35 -7
- package/dist/esm/e2e/config.d.ts +56 -0
- package/dist/esm/e2e/config.js +114 -0
- package/dist/esm/e2e/execution.js +8 -0
- package/dist/esm/e2e/run-planner.js +2 -0
- package/dist/esm/e2e/types.d.ts +3 -0
- package/dist/esm/format/index.js +5 -1
- package/dist/esm/hooks/guard-switch/index.d.ts +1 -1
- package/dist/esm/hooks/guard-switch/index.js +22 -14
- package/dist/esm/hooks/post-tool/lint-after-edit.d.ts +1 -0
- package/dist/esm/hooks/post-tool/lint-after-edit.js +5 -2
- package/dist/esm/hooks/pretool-guard/validators/file-conventions.js +1 -1
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.d.ts +6 -0
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +27 -2
- package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +2 -1
- package/dist/esm/hooks/pretool-guard/validators/path-contract.js +59 -34
- package/dist/esm/hooks/pretool-guard/validators/plan-frontmatter.js +3 -3
- package/dist/esm/hooks/shared/routing-block.js +18 -4
- package/dist/esm/hooks/shared/validators/blueprint.js +3 -0
- package/dist/esm/hooks/stop/qa-changed-files.d.ts +1 -0
- package/dist/esm/hooks/stop/qa-changed-files.js +5 -2
- package/dist/esm/lint/index.js +3 -1
- package/dist/esm/mcp/auto-discover.d.ts +2 -0
- package/dist/esm/mcp/auto-discover.js +14 -6
- package/dist/esm/mcp/blueprint-server.js +379 -80
- package/dist/esm/mcp/cli.js +21 -0
- package/dist/esm/mcp/runners/test.js +15 -0
- package/dist/esm/mcp/server.d.ts +7 -0
- package/dist/esm/mcp/server.js +16 -27
- package/dist/esm/mcp/tools/_registry.d.ts +3 -0
- package/dist/esm/mcp/tools/_registry.js +21 -0
- package/dist/esm/mcp/tools/audit.d.ts +1 -0
- package/dist/esm/mcp/tools/audit.js +13 -8
- package/dist/esm/mcp/tools/typecheck.js +4 -2
- package/dist/esm/mutation/affected.d.ts +9 -0
- package/dist/esm/mutation/affected.js +36 -0
- package/dist/esm/package.json +8 -0
- package/dist/esm/runtime/package-version.d.ts +2 -0
- package/dist/esm/runtime/package-version.js +43 -0
- package/dist/esm/test/command-builder.d.ts +4 -0
- package/dist/esm/test/command-builder.js +28 -3
- package/dist/esm/test-helpers/hermetic-env.d.ts +25 -0
- package/dist/esm/test-helpers/hermetic-env.js +31 -0
- package/dist/esm/tool-runtime/index.d.ts +5 -0
- package/dist/esm/tool-runtime/index.js +24 -0
- package/dist/esm/tool-runtime/resolve-runner.d.ts +16 -0
- package/dist/esm/tool-runtime/resolve-runner.js +42 -0
- package/dist/esm/typecheck/index.js +4 -2
- package/dist/esm/wp-extension/index.d.ts +50 -0
- package/dist/esm/wp-extension/index.js +268 -0
- package/package.json +75 -46
- package/skills/plan-refine/SKILL.md +5 -4
- package/skills/pll/SKILL.md +1 -0
- package/dist/esm/blueprint/dag/cycle-detector.d.ts +0 -12
- package/dist/esm/blueprint/dag/cycle-detector.js +0 -46
- package/dist/esm/blueprint/dag/executor.d.ts +0 -140
- package/dist/esm/blueprint/dag/executor.js +0 -292
- package/dist/esm/blueprint/dag/index.d.ts +0 -20
- package/dist/esm/blueprint/dag/index.js +0 -17
- package/dist/esm/blueprint/dag/interfaces.d.ts +0 -56
- package/dist/esm/blueprint/dag/interfaces.js +0 -13
- package/dist/esm/blueprint/dag/local/independence.d.ts +0 -107
- package/dist/esm/blueprint/dag/local/independence.js +0 -231
- package/dist/esm/blueprint/dag/local/index.d.ts +0 -14
- package/dist/esm/blueprint/dag/local/index.js +0 -14
- package/dist/esm/blueprint/dag/local/package-graph.d.ts +0 -66
- package/dist/esm/blueprint/dag/local/package-graph.js +0 -148
- package/dist/esm/blueprint/dag/plan-parser.d.ts +0 -54
- package/dist/esm/blueprint/dag/plan-parser.js +0 -236
- package/dist/esm/blueprint/dag/task-graph-algorithms.d.ts +0 -13
- package/dist/esm/blueprint/dag/task-graph-algorithms.js +0 -236
- package/dist/esm/blueprint/dag/task-graph.d.ts +0 -171
- package/dist/esm/blueprint/dag/task-graph.js +0 -370
- package/dist/esm/blueprint/dag/types.d.ts +0 -17
- package/dist/esm/blueprint/dag/types.js +0 -2
- package/dist/esm/blueprint/graph/index.d.ts +0 -5
- package/dist/esm/blueprint/graph/index.js +0 -5
- package/dist/esm/blueprint/graph/mermaid-parser.d.ts +0 -3
- package/dist/esm/blueprint/graph/mermaid-parser.js +0 -93
- package/dist/esm/blueprint/graph/mermaid-serializer.d.ts +0 -3
- package/dist/esm/blueprint/graph/mermaid-serializer.js +0 -20
- package/dist/esm/blueprint/graph/schema.d.ts +0 -89
- package/dist/esm/blueprint/graph/schema.js +0 -104
- package/dist/esm/blueprint/graph/task-graph-adapter.d.ts +0 -6
- package/dist/esm/blueprint/graph/task-graph-adapter.js +0 -30
|
@@ -11,5 +11,6 @@ export declare function getNonCanonicalPlanningPathViolation(filePath: string, b
|
|
|
11
11
|
* accepted blueprints root layout (or the explicitly provided root).
|
|
12
12
|
*/
|
|
13
13
|
export declare function isCanonicalBlueprintOverviewPath(filePath: string, blueprintsRoot?: string): boolean;
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function isCanonicalBlueprintDocumentPath(filePath: string, blueprintsRoot?: string): boolean;
|
|
15
|
+
export declare function getBlueprintPathViolation(filePath: string, blueprintsRoot?: string, cwd?: string): string | null;
|
|
15
16
|
//# sourceMappingURL=path-contract.d.ts.map
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { BLUEPRINT_OVERVIEW_FILENAME, getBlueprintAlternateDocumentPath, isBlueprintSupportingMarkdownRelativePath, isBlueprintStatus, parseBlueprintDocumentRelativePath, } from '#utils/document-paths.js';
|
|
1
4
|
export const BLUEPRINTS_ROOT = 'webpresso/blueprints';
|
|
2
5
|
const DEFAULT_BLUEPRINTS_ROOT = 'blueprints';
|
|
3
6
|
export const TECH_DEBT_ROOT = 'webpresso/tech-debt';
|
|
4
7
|
const DEFAULT_TECH_DEBT_ROOT = 'tech-debt';
|
|
5
|
-
const BLUEPRINT_STATUSES = new Set([
|
|
6
|
-
'draft',
|
|
7
|
-
'planned',
|
|
8
|
-
'parked',
|
|
9
|
-
'in-progress',
|
|
10
|
-
'completed',
|
|
11
|
-
'archived',
|
|
12
|
-
]);
|
|
13
|
-
const KEBAB_CASE_SEGMENT = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
14
8
|
// Both canonical blueprint-root layouts accepted by default.
|
|
15
9
|
const CANONICAL_BLUEPRINTS_ROOTS = [BLUEPRINTS_ROOT, DEFAULT_BLUEPRINTS_ROOT];
|
|
16
10
|
const CANONICAL_TECH_DEBT_ROOTS = [TECH_DEBT_ROOT, DEFAULT_TECH_DEBT_ROOT];
|
|
@@ -20,6 +14,16 @@ function normalizePlanningPath(filePath) {
|
|
|
20
14
|
function matchesRoot(normalized, root) {
|
|
21
15
|
return normalized === root || normalized.startsWith(`${root}/`);
|
|
22
16
|
}
|
|
17
|
+
function stripBlueprintRoot(normalized, roots) {
|
|
18
|
+
for (const root of roots) {
|
|
19
|
+
if (normalized === root)
|
|
20
|
+
return { relativePath: '', root };
|
|
21
|
+
if (normalized.startsWith(`${root}/`)) {
|
|
22
|
+
return { relativePath: normalized.slice(root.length + 1), root };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
23
27
|
/**
|
|
24
28
|
* Returns true if the path is under any accepted blueprints root.
|
|
25
29
|
* Pass `blueprintsRoot` to restrict to a single configured root.
|
|
@@ -66,39 +70,60 @@ export function getNonCanonicalPlanningPathViolation(filePath, blueprintsRoot, t
|
|
|
66
70
|
* accepted blueprints root layout (or the explicitly provided root).
|
|
67
71
|
*/
|
|
68
72
|
export function isCanonicalBlueprintOverviewPath(filePath, blueprintsRoot) {
|
|
73
|
+
const parsed = getCanonicalBlueprintDocument(filePath, blueprintsRoot);
|
|
74
|
+
return parsed?.shape === 'folder';
|
|
75
|
+
}
|
|
76
|
+
export function isCanonicalBlueprintDocumentPath(filePath, blueprintsRoot) {
|
|
77
|
+
return getCanonicalBlueprintDocument(filePath, blueprintsRoot) !== null;
|
|
78
|
+
}
|
|
79
|
+
function getCanonicalBlueprintDocument(filePath, blueprintsRoot) {
|
|
69
80
|
const normalized = normalizePlanningPath(filePath);
|
|
70
81
|
const roots = blueprintsRoot ? [blueprintsRoot] : CANONICAL_BLUEPRINTS_ROOTS;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const parts = normalized.split('/');
|
|
74
|
-
const n = rootParts.length;
|
|
75
|
-
return (parts.length === n + 3 &&
|
|
76
|
-
parts.slice(0, n).join('/') === root &&
|
|
77
|
-
BLUEPRINT_STATUSES.has(parts[n] ?? '') &&
|
|
78
|
-
KEBAB_CASE_SEGMENT.test(parts[n + 1] ?? '') &&
|
|
79
|
-
parts[n + 2] === '_overview.md');
|
|
80
|
-
});
|
|
82
|
+
const stripped = stripBlueprintRoot(normalized, roots);
|
|
83
|
+
return stripped ? parseBlueprintDocumentRelativePath(stripped.relativePath) : null;
|
|
81
84
|
}
|
|
82
|
-
export function getBlueprintPathViolation(filePath, blueprintsRoot) {
|
|
85
|
+
export function getBlueprintPathViolation(filePath, blueprintsRoot, cwd = process.cwd()) {
|
|
83
86
|
const normalized = normalizePlanningPath(filePath);
|
|
84
87
|
if (!isBlueprintPath(normalized, blueprintsRoot))
|
|
85
88
|
return null;
|
|
86
|
-
if (normalized.endsWith('/_overview.md') &&
|
|
87
|
-
!isCanonicalBlueprintOverviewPath(normalized, blueprintsRoot)) {
|
|
88
|
-
const root = blueprintsRoot ?? BLUEPRINTS_ROOT;
|
|
89
|
-
return `Blueprint overview files must live at ${root}/<status>/<slug>/_overview.md. Got: ${normalized}`;
|
|
90
|
-
}
|
|
91
89
|
const roots = blueprintsRoot ? [blueprintsRoot] : CANONICAL_BLUEPRINTS_ROOTS;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
90
|
+
const stripped = stripBlueprintRoot(normalized, roots);
|
|
91
|
+
if (!stripped) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const parsed = parseBlueprintDocumentRelativePath(stripped.relativePath);
|
|
95
|
+
if (parsed) {
|
|
96
|
+
const blueprintRoot = path.isAbsolute(filePath)
|
|
97
|
+
? path.join(path.parse(filePath).root, stripped.root)
|
|
98
|
+
: path.join(cwd, stripped.root);
|
|
99
|
+
const currentPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, normalized);
|
|
100
|
+
const alternate = getBlueprintAlternateDocumentPath(blueprintRoot, currentPath);
|
|
101
|
+
if (alternate && existsSync(alternate)) {
|
|
102
|
+
return `Blueprint slug "${parsed.state}/${parsed.slug}" cannot exist in both flat and folder forms. Remove either ${path.relative(cwd, filePath).replace(/\\/g, '/')} or ${path.relative(cwd, alternate).replace(/\\/g, '/')}.`;
|
|
101
103
|
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const parts = stripped.relativePath.split('/').filter((segment) => segment.length > 0);
|
|
107
|
+
const [state, slug, doc] = parts;
|
|
108
|
+
const root = stripped.root;
|
|
109
|
+
if (parts.length === 2 &&
|
|
110
|
+
typeof doc === 'undefined' &&
|
|
111
|
+
typeof slug === 'string' &&
|
|
112
|
+
slug.endsWith('.md')) {
|
|
113
|
+
return `Blueprint markdown under ${root}/<status>/ must be either <slug>.md or <slug>/${BLUEPRINT_OVERVIEW_FILENAME}. Got: ${normalized}`;
|
|
114
|
+
}
|
|
115
|
+
if (parts.length === 3 && doc === BLUEPRINT_OVERVIEW_FILENAME) {
|
|
116
|
+
return `Blueprint overview files must live at ${root}/<status>/<slug>/${BLUEPRINT_OVERVIEW_FILENAME}. Got: ${normalized}`;
|
|
117
|
+
}
|
|
118
|
+
if (parts.length === 3 && isBlueprintSupportingMarkdownRelativePath(stripped.relativePath)) {
|
|
119
|
+
const canonicalOverviewPath = path.join(cwd, root, state ?? '', slug ?? '', BLUEPRINT_OVERVIEW_FILENAME);
|
|
120
|
+
if (!existsSync(canonicalOverviewPath)) {
|
|
121
|
+
return `Supporting blueprint markdown requires ${root}/${state}/${slug}/${BLUEPRINT_OVERVIEW_FILENAME}. Got: ${normalized}`;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
if (parts.length >= 3 && isBlueprintStatus(state)) {
|
|
126
|
+
return `Blueprint markdown must use one of ${root}/<status>/<slug>.md or ${root}/<status>/<slug>/${BLUEPRINT_OVERVIEW_FILENAME}. Supporting markdown is only allowed beside ${BLUEPRINT_OVERVIEW_FILENAME}. Got: ${normalized}`;
|
|
102
127
|
}
|
|
103
128
|
return null;
|
|
104
129
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import jsYaml from 'js-yaml';
|
|
2
2
|
import { getContent, getFilePath } from '#hooks/shared/types';
|
|
3
|
-
import { getNonCanonicalPlanningPathViolation, isBlueprintPath } from './path-contract.js';
|
|
3
|
+
import { getNonCanonicalPlanningPathViolation, isBlueprintPath, isCanonicalBlueprintDocumentPath, } from './path-contract.js';
|
|
4
4
|
import { createSkipResult } from './skip-result.js';
|
|
5
5
|
// Keep aligned with webpresso/blueprint planStatusSchema + plan type enum.
|
|
6
6
|
const VALID_TYPES = ['blueprint', 'parent-roadmap'];
|
|
@@ -10,8 +10,8 @@ function shouldValidatePath(filePath) {
|
|
|
10
10
|
const normalized = filePath.startsWith('/') ? filePath.slice(1) : filePath;
|
|
11
11
|
const nonCanonicalPlanningPath = getNonCanonicalPlanningPathViolation(normalized);
|
|
12
12
|
const currentPath = isBlueprintPath(normalized);
|
|
13
|
-
const
|
|
14
|
-
return !nonCanonicalPlanningPath && currentPath &&
|
|
13
|
+
const isCanonicalBlueprintDoc = isCanonicalBlueprintDocumentPath(normalized);
|
|
14
|
+
return !nonCanonicalPlanningPath && currentPath && isCanonicalBlueprintDoc;
|
|
15
15
|
}
|
|
16
16
|
export function extractFrontmatterBlock(content) {
|
|
17
17
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -8,6 +8,7 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
8
8
|
<description>
|
|
9
9
|
Use the wp_* MCP tools for all test, lint, typecheck, qa, audit, local CI act,
|
|
10
10
|
and Cloudflare Worker tail operations.
|
|
11
|
+
If a wp_* MCP tool is stale or unavailable, use the matching wp CLI command.
|
|
11
12
|
If context-mode plugin routing is present, let it own ctx_* data-processing nudges.
|
|
12
13
|
These tools return structured, summary-first results and keep output concise.
|
|
13
14
|
</description>
|
|
@@ -55,7 +56,7 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
55
56
|
<tool name="wp_test">
|
|
56
57
|
<category>dev-workflow</category>
|
|
57
58
|
<trigger>running tests, verifying test suite, check if tests pass</trigger>
|
|
58
|
-
<forbidden>just test, pnpm test, vitest</forbidden>
|
|
59
|
+
<forbidden>just test, pnpm test, vitest, npx vitest, npm exec -- vitest, yarn vitest, bunx vitest, node ./node_modules/vitest/vitest.mjs</forbidden>
|
|
59
60
|
</tool>
|
|
60
61
|
<tool name="wp_e2e">
|
|
61
62
|
<category>dev-workflow</category>
|
|
@@ -65,12 +66,12 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
65
66
|
<tool name="wp_lint">
|
|
66
67
|
<category>dev-workflow</category>
|
|
67
68
|
<trigger>linting, code style checks, lint errors</trigger>
|
|
68
|
-
<forbidden>just lint, oxlint</forbidden>
|
|
69
|
+
<forbidden>just lint, oxlint, node ./node_modules/oxlint/bin/oxlint</forbidden>
|
|
69
70
|
</tool>
|
|
70
71
|
<tool name="wp_typecheck">
|
|
71
72
|
<category>dev-workflow</category>
|
|
72
73
|
<trigger>type checking, TypeScript errors, type errors</trigger>
|
|
73
|
-
<forbidden>tsc</forbidden>
|
|
74
|
+
<forbidden>tsc, node ./node_modules/typescript/bin/tsc</forbidden>
|
|
74
75
|
</tool>
|
|
75
76
|
<tool name="wp_qa">
|
|
76
77
|
<category>dev-workflow</category>
|
|
@@ -102,6 +103,11 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
102
103
|
<rule>Context-mode owns ctx_* routing when that plugin is installed.</rule>
|
|
103
104
|
</ownership_boundary>
|
|
104
105
|
|
|
106
|
+
<hook_diagnostics>
|
|
107
|
+
<rule>Prefer wp hook <name> over direct wp-<hook-bin> calls when a wp hook command exists.</rule>
|
|
108
|
+
<rule>Direct wp-* hook bins remain generated-hook runtime internals, not recommended agent diagnostics.</rule>
|
|
109
|
+
</hook_diagnostics>
|
|
110
|
+
|
|
105
111
|
<package_guidance>
|
|
106
112
|
<rule>Consumers add @webpresso/agent-kit and import config helpers through @webpresso/agent-kit/* subpath exports such as @webpresso/agent-kit/oxlint, @webpresso/agent-kit/vitest/node, @webpresso/agent-kit/test-preset, @webpresso/agent-kit/e2e-preset, @webpresso/agent-kit/tsconfig/base.json, @webpresso/agent-kit/docs-lint, @webpresso/agent-kit/stryker, @webpresso/agent-kit/launch, and @webpresso/agent-kit/workers-test.</rule>
|
|
107
113
|
<rule>Do not recommend adding retired split agent config packages for consumer projects; keep wp_* MCP tool names and wp-* hook bin names unchanged.</rule>
|
|
@@ -114,9 +120,16 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
114
120
|
<command>just qa</command>
|
|
115
121
|
<command>just lint-md</command>
|
|
116
122
|
<command>vitest</command>
|
|
123
|
+
<command>npx vitest</command>
|
|
124
|
+
<command>npm exec -- vitest</command>
|
|
125
|
+
<command>yarn vitest</command>
|
|
126
|
+
<command>bunx vitest</command>
|
|
127
|
+
<command>node ./node_modules/vitest/vitest.mjs</command>
|
|
117
128
|
<command>oxlint</command>
|
|
129
|
+
<command>node ./node_modules/oxlint/bin/oxlint</command>
|
|
118
130
|
<command>markdownlint-cli2</command>
|
|
119
131
|
<command>tsc</command>
|
|
132
|
+
<command>node ./node_modules/typescript/bin/tsc</command>
|
|
120
133
|
<command>act</command>
|
|
121
134
|
<command>vp exec act</command>
|
|
122
135
|
<command>pnpm exec act</command>
|
|
@@ -133,7 +146,8 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
133
146
|
</output_format>
|
|
134
147
|
|
|
135
148
|
<fallback>
|
|
136
|
-
When MCP tools are unavailable, use
|
|
149
|
+
When MCP tools are unavailable or stale, use the matching wp CLI command and keep output brief.
|
|
150
|
+
Do not fall through to raw tool bins under node_modules when a wp wrapper exists.
|
|
137
151
|
.omx is runtime/state only; it is not a direct hook surface.
|
|
138
152
|
</fallback>
|
|
139
153
|
</wp_routing>`;
|
|
@@ -26,6 +26,9 @@ export function shouldSkipFile(filePath) {
|
|
|
26
26
|
if (!filePath)
|
|
27
27
|
return false;
|
|
28
28
|
const normalized = filePath.startsWith('/') ? filePath.slice(1) : filePath;
|
|
29
|
+
if (normalized.startsWith('blueprints/') || normalized.startsWith('webpresso/blueprints/')) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
29
32
|
return SKIP_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
30
33
|
}
|
|
31
34
|
export function getSkipReason(filePath) {
|
|
@@ -85,12 +85,15 @@ export function runQaChecks(qaFiles, projectDir) {
|
|
|
85
85
|
export function formatStopHookOutput(result) {
|
|
86
86
|
return JSON.stringify(result);
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
|
|
88
|
+
export async function main() {
|
|
90
89
|
runHook(
|
|
91
90
|
// `Stop` is latency-sensitive and user-visible. Until webpresso grows a
|
|
92
91
|
// deferred execution plane, broad typecheck/test sweeps stay off the hot
|
|
93
92
|
// path instead of shelling synchronously at turn end.
|
|
94
93
|
(_input) => null, formatStopHookOutput);
|
|
95
94
|
}
|
|
95
|
+
if (process.argv[1] &&
|
|
96
|
+
realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
|
|
97
|
+
void main();
|
|
98
|
+
}
|
|
96
99
|
//# sourceMappingURL=qa-changed-files.js.map
|
package/dist/esm/lint/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { isRunFailure, runCommand } from '#mcp/tools/_shared/run-command';
|
|
10
10
|
import { resolveProjectRoot } from '#mcp/tools/_shared/project-root';
|
|
11
|
+
import { getManagedRunner } from '#tool-runtime';
|
|
11
12
|
const DEFAULT_LINT_TIMEOUT_MS = 5 * 60 * 1_000;
|
|
12
13
|
/**
|
|
13
14
|
* Parse oxlint's `--format=json` output (ESLint-compatible array shape) into
|
|
@@ -92,7 +93,8 @@ export async function runLint(options = {}) {
|
|
|
92
93
|
else {
|
|
93
94
|
lintArgs.push('.');
|
|
94
95
|
}
|
|
95
|
-
const
|
|
96
|
+
const resolution = getManagedRunner('vp', { outputPolicy: 'structured' });
|
|
97
|
+
const vpOutcome = await runCommand(resolution.command, [...resolution.args, ...lintArgs], runOptions);
|
|
96
98
|
if (isRunFailure(vpOutcome)) {
|
|
97
99
|
return {
|
|
98
100
|
passed: false,
|
|
@@ -61,5 +61,7 @@ export interface ToolDescriptor {
|
|
|
61
61
|
export interface ToolRegistrar {
|
|
62
62
|
registerTool(name: string, description: string, jsonSchema: Record<string, unknown>, outputSchema: Record<string, unknown> | undefined, handler: ToolHandler, annotations?: ToolAnnotations): void;
|
|
63
63
|
}
|
|
64
|
+
export declare function registerToolDescriptor(server: ToolRegistrar, descriptor: ToolDescriptor): ToolDescriptor;
|
|
65
|
+
export declare function registerToolDescriptors(server: ToolRegistrar, descriptors: readonly ToolDescriptor[]): ToolDescriptor[];
|
|
64
66
|
export declare function discoverTools(server: ToolRegistrar, toolsDir: string): Promise<ToolDescriptor[]>;
|
|
65
67
|
//# sourceMappingURL=auto-discover.d.ts.map
|
|
@@ -15,9 +15,20 @@ import { extname, join } from 'node:path';
|
|
|
15
15
|
import { pathToFileURL } from 'node:url';
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
18
|
+
export function registerToolDescriptor(server, descriptor) {
|
|
19
|
+
const jsonSchema = toJsonSchema(descriptor.inputSchema);
|
|
20
|
+
const outputSchema = descriptor.outputSchema ? toJsonSchema(descriptor.outputSchema) : undefined;
|
|
21
|
+
server.registerTool(descriptor.name, descriptor.description, jsonSchema, outputSchema, descriptor.handler, descriptor.annotations);
|
|
22
|
+
return descriptor;
|
|
23
|
+
}
|
|
24
|
+
export function registerToolDescriptors(server, descriptors) {
|
|
25
|
+
return descriptors.map((descriptor) => registerToolDescriptor(server, descriptor));
|
|
26
|
+
}
|
|
18
27
|
const SKIP_SUFFIXES = ['.test.ts', '.test.js', '.integration.test.ts', '.integration.test.js'];
|
|
19
28
|
const SUPPORTED_EXTENSIONS = new Set(['.ts', '.js', '.mjs', '.cjs']);
|
|
20
29
|
function shouldSkip(file) {
|
|
30
|
+
if (file.startsWith('_'))
|
|
31
|
+
return true;
|
|
21
32
|
if (file.endsWith('.d.ts') || file.endsWith('.d.ts.map'))
|
|
22
33
|
return true;
|
|
23
34
|
if (file.endsWith('.js.map') || file.endsWith('.ts.map'))
|
|
@@ -82,7 +93,7 @@ function toJsonSchema(schema) {
|
|
|
82
93
|
}
|
|
83
94
|
export async function discoverTools(server, toolsDir) {
|
|
84
95
|
const entries = await readdir(toolsDir, { withFileTypes: true });
|
|
85
|
-
const
|
|
96
|
+
const loaded = [];
|
|
86
97
|
for (const entry of entries) {
|
|
87
98
|
if (!entry.isFile())
|
|
88
99
|
continue;
|
|
@@ -98,11 +109,8 @@ export async function discoverTools(server, toolsDir) {
|
|
|
98
109
|
if (typeof descriptor.name !== 'string' || typeof descriptor.handler !== 'function') {
|
|
99
110
|
throw new Error(`Tool file ${fullPath} default export is malformed (missing name or handler)`);
|
|
100
111
|
}
|
|
101
|
-
|
|
102
|
-
const outputSchema = descriptor.outputSchema ? toJsonSchema(descriptor.outputSchema) : undefined;
|
|
103
|
-
server.registerTool(descriptor.name, descriptor.description, jsonSchema, outputSchema, descriptor.handler, descriptor.annotations);
|
|
104
|
-
registered.push(descriptor);
|
|
112
|
+
loaded.push(descriptor);
|
|
105
113
|
}
|
|
106
|
-
return
|
|
114
|
+
return registerToolDescriptors(server, loaded);
|
|
107
115
|
}
|
|
108
116
|
//# sourceMappingURL=auto-discover.js.map
|