@webpresso/agent-kit 0.21.3 → 0.21.5
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 +105 -41
- package/catalog/AGENTS.md.tpl +3 -1
- package/catalog/agent/rules/changeset-release.md +13 -16
- package/catalog/agent/skills/plan-refine/SKILL.md +5 -4
- 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 +1 -0
- package/catalog/docs/templates/blueprint.yaml +6 -3
- 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 +37 -4
- package/dist/esm/audit/resolve-audit-script.d.ts +24 -0
- package/dist/esm/audit/resolve-audit-script.js +27 -0
- package/dist/esm/blueprint/db/enums.d.ts +1 -1
- package/dist/esm/blueprint/index.d.ts +0 -1
- package/dist/esm/blueprint/index.js +0 -2
- package/dist/esm/blueprint/local.d.ts +0 -3
- package/dist/esm/blueprint/local.js +0 -2
- package/dist/esm/blueprint/service/BlueprintCreationService.js +5 -2
- 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/sync-catalog-doc-templates.d.ts +23 -0
- package/dist/esm/build/sync-catalog-doc-templates.js +93 -0
- package/dist/esm/cli/commands/audit.js +2 -7
- package/dist/esm/cli/commands/blueprint/router.js +5 -2
- package/dist/esm/cli/commands/blueprint/template-resolver.js +8 -4
- package/dist/esm/cli/commands/init/host-visibility.js +4 -2
- package/dist/esm/cli/commands/init/index.js +46 -7
- package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +12 -0
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +141 -6
- package/dist/esm/cli/commands/typecheck.js +10 -4
- package/dist/esm/e2e/command-builder.js +26 -7
- package/dist/esm/e2e/execution.js +4 -0
- package/dist/esm/e2e/run-planner.js +1 -0
- package/dist/esm/e2e/types.d.ts +1 -0
- package/dist/esm/format/index.js +7 -1
- package/dist/esm/lint/index.js +3 -1
- package/dist/esm/mcp/blueprint-server.js +361 -66
- package/dist/esm/mcp/tools/audit.js +2 -8
- package/dist/esm/mcp/tools/e2e.d.ts +1 -1
- package/dist/esm/package.json +3 -0
- package/dist/esm/secret-gate/runner.js +4 -0
- package/dist/esm/test/command-builder.d.ts +1 -0
- package/dist/esm/test/command-builder.js +8 -2
- 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 +23 -0
- package/dist/esm/tool-runtime/resolve-runner.d.ts +13 -0
- package/dist/esm/tool-runtime/resolve-runner.js +40 -0
- package/package.json +12 -18
- package/skills/plan-refine/SKILL.md +5 -4
- 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
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the absolute path of a Bun audit script (`audit-tph.ts`,
|
|
5
|
+
* `audit-tph-e2e.ts`) living in the sibling `audit/` directory two levels up
|
|
6
|
+
* from the caller.
|
|
7
|
+
*
|
|
8
|
+
* `../../audit/` is correct relative to the caller in BOTH layouts:
|
|
9
|
+
* - dev: `src/{cli,mcp}/.../audit.ts` → `src/audit/`
|
|
10
|
+
* - published: `dist/esm/{cli,mcp}/.../audit.js` → `dist/esm/audit/`
|
|
11
|
+
*
|
|
12
|
+
* The npm tarball ships only `dist/` (never `src/`), so the dev `.ts` source is
|
|
13
|
+
* absent there — fall back to the compiled `.js` sibling the build emits. The
|
|
14
|
+
* previous CLI resolver instead hand-rolled a `<bundle>/src/audit/<name>.ts`
|
|
15
|
+
* path that does not exist in dist, which made `bun` fail with
|
|
16
|
+
* "Module not found"; the MCP twin reached for the unshipped `src/audit/` via
|
|
17
|
+
* `resolvePackageAsset` and failed the same way.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveAuditScriptPath(name, { moduleUrl, exists = existsSync }) {
|
|
20
|
+
const sourceUrl = new URL(`../../audit/${name}`, moduleUrl);
|
|
21
|
+
if (exists(sourceUrl)) {
|
|
22
|
+
return fileURLToPath(sourceUrl);
|
|
23
|
+
}
|
|
24
|
+
const compiledUrl = new URL(`../../audit/${name.replace(/\.ts$/, '.js')}`, moduleUrl);
|
|
25
|
+
return fileURLToPath(compiledUrl);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=resolve-audit-script.js.map
|
|
@@ -65,8 +65,8 @@ export declare const reviewCadenceSchema: z.ZodEnum<{
|
|
|
65
65
|
quarterly: "quarterly";
|
|
66
66
|
}>;
|
|
67
67
|
export declare const visibilitySchema: z.ZodEnum<{
|
|
68
|
-
private: "private";
|
|
69
68
|
public: "public";
|
|
69
|
+
private: "private";
|
|
70
70
|
}>;
|
|
71
71
|
export declare const taskFileOpSchema: z.ZodEnum<{
|
|
72
72
|
create: "create";
|
|
@@ -16,7 +16,6 @@ export { validatePlanTemplate } from './core/validation/template.js';
|
|
|
16
16
|
export { type BlueprintDiff, type DiffChange, type DiffFieldChange, formatDiffForDisplay, generateBlueprintDiff, } from './history/diff.js';
|
|
17
17
|
export { checkAllCheckboxes, checkFirstCheckbox, extractCodeBlocks, extractTaskSection, updateBlockedReason, updateTaskStatus, } from './markdown/helpers.js';
|
|
18
18
|
export { applyBlueprintLifecycle, type BlueprintLifecycleIntent, type BlueprintLifecycleResult, type LifecycleTaskStatus, } from './lifecycle/engine.js';
|
|
19
|
-
export { type GraphEdge, type GraphEdgeType, type GraphLayout, type GraphNode, type GraphNodeType, type NormalizedGraph, parseMermaidToGraph, serializeGraphToMermaid, taskGraphToNormalizedGraph, } from './graph/index.js';
|
|
20
19
|
export type { BlueprintQueryFilters, BlueprintQueryResult, BlueprintQuerySummary, BlueprintRecord, BlueprintSortField, BlueprintSortOptions, Complexity, SortDirection, TaskStatus, } from './query/types.js';
|
|
21
20
|
export { isBlueprintStatus, isComplexity, isTaskStatus } from './query/types.js';
|
|
22
21
|
export { BlueprintNotFoundError } from './utils/errors.js';
|
|
@@ -17,8 +17,6 @@ export { formatDiffForDisplay, generateBlueprintDiff, } from './history/diff.js'
|
|
|
17
17
|
// Markdown helpers (pure functions)
|
|
18
18
|
export { checkAllCheckboxes, checkFirstCheckbox, extractCodeBlocks, extractTaskSection, updateBlockedReason, updateTaskStatus, } from './markdown/helpers.js';
|
|
19
19
|
export { applyBlueprintLifecycle, } from './lifecycle/engine.js';
|
|
20
|
-
// Graph model + Mermaid integration
|
|
21
|
-
export { parseMermaidToGraph, serializeGraphToMermaid, taskGraphToNormalizedGraph, } from './graph/index.js';
|
|
22
20
|
export { isBlueprintStatus, isComplexity, isTaskStatus } from './query/types.js';
|
|
23
21
|
export { BlueprintNotFoundError } from './utils/errors.js';
|
|
24
22
|
// Evidence Contract (F10) — pin per-kind evidence rules at zod parse time.
|
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* These exports use Node.js APIs (fs, simple-git) and are NOT compatible with Cloudflare Workers.
|
|
5
5
|
* For Workers-safe functions, use the main 'webpresso/blueprint' entry point.
|
|
6
6
|
*/
|
|
7
|
-
export type { FalseDependency, ParallelizeResult, TaskFiles, TaskPairAnalysis, } from './dag/local/independence.js';
|
|
8
|
-
export { createMockPackageGraph, IndependenceDetector } from './dag/local/independence.js';
|
|
9
|
-
export { createMockFileSystem, PackageGraph, realFileSystem } from './dag/local/package-graph.js';
|
|
10
7
|
export { type AcceptanceCriteria, type Blueprint, buildRoadmapModel, buildBlueprintProgressBridgeState, type BlueprintStatus, type BlueprintTaskStatus, checkAcceptanceCriteria, checkAllCheckboxes, checkChangelog, checkFirstCheckbox, complexitySchema, type CriteriaResult, extractTaskSection, formatDiffForDisplay, generateBlueprintDiff, isBlueprintStatus, isComplexity, isTaskStatus, lifecycleBlueprintStatusSchema, normalizeOmxTeamTaskSnapshot, type OmxTeamTaskSnapshot, type Phase, parseBlueprint, type PlanComplexity, type PlanFrontmatter, planStatusSchema, projectBlueprintLifecycleFromRuntime, resolveBlueprintProgressBridgePath, type RoadmapModel, type RoadmapNode, type RoadmapRollup, type RoadmapLike, serializeBlueprint, type Task, taskStatusSchema, type TaskStatusValue, updateBlockedReason, updateTaskStatus, type ValidationResult, validateEmbeddedPhases, validatePlanLinks, validatePlanState, validatePlanTemplate, } from './index.js';
|
|
11
8
|
export { BlueprintCreationService, type BlueprintCreationServiceOptions, type BlueprintDraft, type CreateBlueprintInput, type CreatedBlueprint, } from './service/BlueprintCreationService.js';
|
|
12
9
|
export { type BlueprintQueryOptions, BlueprintService, type BlueprintSummary, } from './service/BlueprintService.js';
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
* These exports use Node.js APIs (fs, simple-git) and are NOT compatible with Cloudflare Workers.
|
|
5
5
|
* For Workers-safe functions, use the main 'webpresso/blueprint' entry point.
|
|
6
6
|
*/
|
|
7
|
-
export { createMockPackageGraph, IndependenceDetector } from './dag/local/independence.js';
|
|
8
|
-
export { createMockFileSystem, PackageGraph, realFileSystem } from './dag/local/package-graph.js';
|
|
9
7
|
// Workers-safe exports for convenience (explicit re-export to avoid wildcard)
|
|
10
8
|
export { buildRoadmapModel, buildBlueprintProgressBridgeState, checkAcceptanceCriteria, checkAllCheckboxes, checkChangelog, checkFirstCheckbox, complexitySchema, extractTaskSection, formatDiffForDisplay, generateBlueprintDiff, isBlueprintStatus, isComplexity, isTaskStatus, lifecycleBlueprintStatusSchema, normalizeOmxTeamTaskSnapshot, parseBlueprint, planStatusSchema, projectBlueprintLifecycleFromRuntime, resolveBlueprintProgressBridgePath, serializeBlueprint, taskStatusSchema, updateBlockedReason, updateTaskStatus, validateEmbeddedPhases, validatePlanLinks, validatePlanState, validatePlanTemplate, } from './index.js';
|
|
11
9
|
// Services (require filesystem/git)
|
|
@@ -4,7 +4,7 @@ import path from 'node:path';
|
|
|
4
4
|
import { parseBlueprint } from '#core/parser';
|
|
5
5
|
import { scanBlueprintDirectory } from '#service/scanner';
|
|
6
6
|
import { resolveBlueprintRoot } from '#utils/blueprint-root';
|
|
7
|
-
import {
|
|
7
|
+
import { resolvePackageAssetPreferred } from '#utils/package-assets';
|
|
8
8
|
const RESERVED_BLUEPRINT_SLUGS = new Set([
|
|
9
9
|
'draft',
|
|
10
10
|
'planned',
|
|
@@ -13,7 +13,10 @@ const RESERVED_BLUEPRINT_SLUGS = new Set([
|
|
|
13
13
|
'completed',
|
|
14
14
|
'archived',
|
|
15
15
|
]);
|
|
16
|
-
const DEFAULT_TEMPLATE_PATH =
|
|
16
|
+
const DEFAULT_TEMPLATE_PATH = resolvePackageAssetPreferred([
|
|
17
|
+
'docs/templates/blueprint.md',
|
|
18
|
+
'catalog/docs/templates/blueprint.md',
|
|
19
|
+
]);
|
|
17
20
|
function formatDate(date) {
|
|
18
21
|
return date.toISOString().split('T')[0] ?? date.toISOString();
|
|
19
22
|
}
|
|
@@ -3,4 +3,15 @@
|
|
|
3
3
|
* package root) is found. Works whether running from src/ or dist/esm/.
|
|
4
4
|
*/
|
|
5
5
|
export declare function resolvePackageAsset(relativeFromRoot: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the first existing candidate, in priority order. Use when an asset
|
|
8
|
+
* lives at one path in the source checkout but a different path in the
|
|
9
|
+
* published tarball — e.g. templates authored under repo-root `docs/templates/`
|
|
10
|
+
* but shipped under `catalog/docs/templates/` because the npm `files` list
|
|
11
|
+
* includes `catalog/` and not `docs/`. Prefers the dev/source location and
|
|
12
|
+
* falls back to the shipped one, mirroring `bin/_run.js`'s source→built path
|
|
13
|
+
* translation. Falls back to cwd-relative on the first candidate when none
|
|
14
|
+
* exist, matching `resolvePackageAsset`'s last-resort behavior.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolvePackageAssetPreferred(candidates: readonly string[]): string;
|
|
6
17
|
//# sourceMappingURL=package-assets.d.ts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
/**
|
|
4
|
-
* Walk up from this file's location
|
|
5
|
-
*
|
|
4
|
+
* Walk up from this file's location looking for `relativeFromRoot`. Returns the
|
|
5
|
+
* first existing match, or `null` if none is found within the ancestor budget.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
function findPackageAsset(relativeFromRoot) {
|
|
8
8
|
let dir = path.dirname(new URL(import.meta.url).pathname);
|
|
9
9
|
for (let i = 0; i < 8; i++) {
|
|
10
10
|
const candidate = path.join(dir, relativeFromRoot);
|
|
@@ -15,6 +15,35 @@ export function resolvePackageAsset(relativeFromRoot) {
|
|
|
15
15
|
break;
|
|
16
16
|
dir = parent;
|
|
17
17
|
}
|
|
18
|
-
return
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Walk up from this file's location until the given path (relative to the
|
|
22
|
+
* package root) is found. Works whether running from src/ or dist/esm/.
|
|
23
|
+
*/
|
|
24
|
+
export function resolvePackageAsset(relativeFromRoot) {
|
|
25
|
+
return findPackageAsset(relativeFromRoot) ?? path.join(process.cwd(), relativeFromRoot);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the first existing candidate, in priority order. Use when an asset
|
|
29
|
+
* lives at one path in the source checkout but a different path in the
|
|
30
|
+
* published tarball — e.g. templates authored under repo-root `docs/templates/`
|
|
31
|
+
* but shipped under `catalog/docs/templates/` because the npm `files` list
|
|
32
|
+
* includes `catalog/` and not `docs/`. Prefers the dev/source location and
|
|
33
|
+
* falls back to the shipped one, mirroring `bin/_run.js`'s source→built path
|
|
34
|
+
* translation. Falls back to cwd-relative on the first candidate when none
|
|
35
|
+
* exist, matching `resolvePackageAsset`'s last-resort behavior.
|
|
36
|
+
*/
|
|
37
|
+
export function resolvePackageAssetPreferred(candidates) {
|
|
38
|
+
for (const relativeFromRoot of candidates) {
|
|
39
|
+
const found = findPackageAsset(relativeFromRoot);
|
|
40
|
+
if (found)
|
|
41
|
+
return found;
|
|
42
|
+
}
|
|
43
|
+
const primary = candidates[0];
|
|
44
|
+
if (primary === undefined) {
|
|
45
|
+
throw new Error('resolvePackageAssetPreferred requires at least one candidate path');
|
|
46
|
+
}
|
|
47
|
+
return path.join(process.cwd(), primary);
|
|
19
48
|
}
|
|
20
49
|
//# sourceMappingURL=package-assets.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* sync-catalog-doc-templates.ts
|
|
4
|
+
*
|
|
5
|
+
* `docs/templates/` (repo root) is the editable source of truth for the
|
|
6
|
+
* blueprint / doc templates. `catalog/docs/templates/` is the published +
|
|
7
|
+
* scaffolded mirror: the npm `files` list ships `catalog/` but NOT repo-root
|
|
8
|
+
* `docs/` (which holds internal docs that must stay private), and `wp init`
|
|
9
|
+
* scaffolds templates into a consumer from `catalog/docs/templates/`.
|
|
10
|
+
*
|
|
11
|
+
* The two MUST stay byte-identical. Nothing synced them before, so they
|
|
12
|
+
* drifted — this script regenerates the mirror from the source and is wired
|
|
13
|
+
* into the build. The colocated drift test fails CI if they ever diverge.
|
|
14
|
+
*
|
|
15
|
+
* Default: regenerate the mirror from the source.
|
|
16
|
+
* `--check`: exit non-zero and list drift without writing (CI / pre-publish).
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Names that are out of sync between source and mirror: content mismatch,
|
|
20
|
+
* missing from the mirror, or orphaned in the mirror.
|
|
21
|
+
*/
|
|
22
|
+
export declare function diffDocTemplateMirror(): string[];
|
|
23
|
+
//# sourceMappingURL=sync-catalog-doc-templates.d.ts.map
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* sync-catalog-doc-templates.ts
|
|
4
|
+
*
|
|
5
|
+
* `docs/templates/` (repo root) is the editable source of truth for the
|
|
6
|
+
* blueprint / doc templates. `catalog/docs/templates/` is the published +
|
|
7
|
+
* scaffolded mirror: the npm `files` list ships `catalog/` but NOT repo-root
|
|
8
|
+
* `docs/` (which holds internal docs that must stay private), and `wp init`
|
|
9
|
+
* scaffolds templates into a consumer from `catalog/docs/templates/`.
|
|
10
|
+
*
|
|
11
|
+
* The two MUST stay byte-identical. Nothing synced them before, so they
|
|
12
|
+
* drifted — this script regenerates the mirror from the source and is wired
|
|
13
|
+
* into the build. The colocated drift test fails CI if they ever diverge.
|
|
14
|
+
*
|
|
15
|
+
* Default: regenerate the mirror from the source.
|
|
16
|
+
* `--check`: exit non-zero and list drift without writing (CI / pre-publish).
|
|
17
|
+
*/
|
|
18
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync } from 'node:fs';
|
|
19
|
+
import { dirname, join } from 'node:path';
|
|
20
|
+
import { argv, exit } from 'node:process';
|
|
21
|
+
import { fileURLToPath } from 'node:url';
|
|
22
|
+
const PACKAGE_ROOT = dirname(dirname(import.meta.dirname));
|
|
23
|
+
const SOURCE_DIR = join(PACKAGE_ROOT, 'docs', 'templates');
|
|
24
|
+
const MIRROR_DIR = join(PACKAGE_ROOT, 'catalog', 'docs', 'templates');
|
|
25
|
+
function listFiles(dir) {
|
|
26
|
+
if (!existsSync(dir))
|
|
27
|
+
return [];
|
|
28
|
+
return readdirSync(dir, { withFileTypes: true })
|
|
29
|
+
.filter((entry) => entry.isFile())
|
|
30
|
+
.map((entry) => entry.name)
|
|
31
|
+
.sort();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Names that are out of sync between source and mirror: content mismatch,
|
|
35
|
+
* missing from the mirror, or orphaned in the mirror.
|
|
36
|
+
*/
|
|
37
|
+
export function diffDocTemplateMirror() {
|
|
38
|
+
const sourceFiles = listFiles(SOURCE_DIR);
|
|
39
|
+
const mirrorFiles = listFiles(MIRROR_DIR);
|
|
40
|
+
const names = [...new Set([...sourceFiles, ...mirrorFiles])].sort();
|
|
41
|
+
const drift = [];
|
|
42
|
+
for (const name of names) {
|
|
43
|
+
const inSource = sourceFiles.includes(name);
|
|
44
|
+
const inMirror = mirrorFiles.includes(name);
|
|
45
|
+
if (!inSource || !inMirror) {
|
|
46
|
+
drift.push(name);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (readFileSync(join(SOURCE_DIR, name), 'utf8') !== readFileSync(join(MIRROR_DIR, name), 'utf8')) {
|
|
50
|
+
drift.push(name);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return drift;
|
|
54
|
+
}
|
|
55
|
+
/** Regenerate the mirror from the source: copy every file, drop orphans. */
|
|
56
|
+
function syncDocTemplateMirror() {
|
|
57
|
+
mkdirSync(MIRROR_DIR, { recursive: true });
|
|
58
|
+
const sourceFiles = listFiles(SOURCE_DIR);
|
|
59
|
+
for (const name of listFiles(MIRROR_DIR)) {
|
|
60
|
+
if (!sourceFiles.includes(name))
|
|
61
|
+
rmSync(join(MIRROR_DIR, name));
|
|
62
|
+
}
|
|
63
|
+
for (const name of sourceFiles) {
|
|
64
|
+
cpSync(join(SOURCE_DIR, name), join(MIRROR_DIR, name));
|
|
65
|
+
}
|
|
66
|
+
return sourceFiles.length;
|
|
67
|
+
}
|
|
68
|
+
function main() {
|
|
69
|
+
if (!existsSync(SOURCE_DIR)) {
|
|
70
|
+
console.error(`doc templates source not found: ${SOURCE_DIR}`);
|
|
71
|
+
exit(1);
|
|
72
|
+
}
|
|
73
|
+
if (argv.includes('--check')) {
|
|
74
|
+
const drift = diffDocTemplateMirror();
|
|
75
|
+
if (drift.length > 0) {
|
|
76
|
+
console.error([
|
|
77
|
+
'catalog/docs/templates/ is out of sync with docs/templates/:',
|
|
78
|
+
...drift.map((name) => ` - ${name}`),
|
|
79
|
+
'Run `bun src/build/sync-catalog-doc-templates.ts` and commit the result.',
|
|
80
|
+
].join('\n'));
|
|
81
|
+
exit(1);
|
|
82
|
+
}
|
|
83
|
+
console.log('catalog/docs/templates/ is in sync with docs/templates/');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const count = syncDocTemplateMirror();
|
|
87
|
+
console.log(`Synced ${count} template(s) → catalog/docs/templates/`);
|
|
88
|
+
}
|
|
89
|
+
// Run as a script, but stay side-effect-free when imported (e.g. by the test).
|
|
90
|
+
if (fileURLToPath(import.meta.url) === argv[1]) {
|
|
91
|
+
main();
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=sync-catalog-doc-templates.js.map
|
|
@@ -9,6 +9,7 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import { runAuditDispatch } from './audit-core.js';
|
|
11
11
|
import { runStryker } from '#audit/run-stryker';
|
|
12
|
+
import { resolveAuditScriptPath } from '#audit/resolve-audit-script';
|
|
12
13
|
const REPO_AUDIT_REGISTRY = {
|
|
13
14
|
'catalog-drift': async (root) => (await import('#audit/repo-guardrails')).auditCatalogDrift(root),
|
|
14
15
|
'package-surface': async (root) => (await import('#audit/package-surface')).auditPackageSurface(root),
|
|
@@ -119,13 +120,7 @@ const AUDIT_KINDS = [
|
|
|
119
120
|
];
|
|
120
121
|
const AUDIT_KIND_LIST = AUDIT_KINDS.join(', ');
|
|
121
122
|
function resolveAuditScript(name) {
|
|
122
|
-
|
|
123
|
-
if (existsSync(fromSource)) {
|
|
124
|
-
return fromSource.pathname;
|
|
125
|
-
}
|
|
126
|
-
const bundleDir = path.dirname(new URL(import.meta.url).pathname);
|
|
127
|
-
const packageRoot = path.resolve(bundleDir, '..');
|
|
128
|
-
return path.join(packageRoot, 'src', 'audit', name);
|
|
123
|
+
return resolveAuditScriptPath(name, { moduleUrl: import.meta.url });
|
|
129
124
|
}
|
|
130
125
|
async function runAuditScript(script, extraArgs) {
|
|
131
126
|
const runtime = process.env.BUN_INSTALL ? 'bun' : 'bun';
|
|
@@ -6,7 +6,7 @@ import { blueprintToSpecKit } from '#export/spec-kit/index';
|
|
|
6
6
|
import { getProjectRoot } from '#cli/utils';
|
|
7
7
|
import { resolveBlueprintRoot } from '#utils/blueprint-root';
|
|
8
8
|
import { applyBlueprintLifecycleToFile, BlueprintCreationService, BlueprintService, complexitySchema, relativeBlueprintSlug, parseBlueprint, planStatusSchema, runBlueprintAudit, resolveBlueprintFile, serializeBlueprint, validateAllTasksDone, } from '#local';
|
|
9
|
-
import {
|
|
9
|
+
import { resolvePackageAssetPreferred } from '#utils/package-assets';
|
|
10
10
|
import { describeBlueprintExecutionRuntime, buildBlueprintLaunchSpec, buildStoppedRuntimeEvidence, controlBlueprintExecution, initializeBlueprintExecutionProgressBridge, launchBlueprintExecution, persistBlueprintExecutionArtifacts, persistBlueprintExecutionMetadata, recordLaunchFailure, reconcileBlueprintRuntimeSnapshot, readBlueprintExecutionState, syncBlueprintExecutionProgress, writeBlueprintRuntimeSnapshot, } from './execution.js';
|
|
11
11
|
import { advanceTask as advanceTaskMutation, finalizeBlueprint as finalizeBlueprintMutation, promoteBlueprint as promoteBlueprintMutation, } from './mutations.js';
|
|
12
12
|
import { BlueprintAuditFailedError, executeBlueprintSubcommand } from './router-dispatch.js';
|
|
@@ -40,7 +40,10 @@ function assertBlueprintCanMoveToStatus(blueprint, nextStatus) {
|
|
|
40
40
|
* when the lookup fails in unrelated contexts (e.g. `wp --help`).
|
|
41
41
|
*/
|
|
42
42
|
function resolveRepoBlueprintTemplatePath() {
|
|
43
|
-
return
|
|
43
|
+
return resolvePackageAssetPreferred([
|
|
44
|
+
'docs/templates/blueprint.md',
|
|
45
|
+
'catalog/docs/templates/blueprint.md',
|
|
46
|
+
]);
|
|
44
47
|
}
|
|
45
48
|
function todayIsoDate() {
|
|
46
49
|
return new Date().toISOString().split('T')[0] ?? new Date().toISOString();
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { readdirSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { resolvePackageAssetPreferred } from '#utils/package-assets.js';
|
|
4
4
|
/**
|
|
5
|
-
* Default templates directory: docs/templates/
|
|
6
|
-
*
|
|
5
|
+
* Default templates directory: docs/templates/ in a source checkout, falling
|
|
6
|
+
* back to the shipped catalog/docs/templates/ in the published package (same
|
|
7
|
+
* strategy as resolveRepoBlueprintTemplatePath in router.ts).
|
|
7
8
|
*/
|
|
8
9
|
function defaultTemplatesDir() {
|
|
9
|
-
return path.dirname(
|
|
10
|
+
return path.dirname(resolvePackageAssetPreferred([
|
|
11
|
+
'docs/templates/blueprint.md',
|
|
12
|
+
'catalog/docs/templates/blueprint.md',
|
|
13
|
+
]));
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
16
|
* List available templates from `templatesDir` (defaults to docs/templates/).
|
|
@@ -5,6 +5,8 @@ export const AGENT_HOSTS = ['codex', 'claude', 'opencode'];
|
|
|
5
5
|
export const REQUIRED_CORE_CAPABILITIES = ['verify', 'plan-refine'];
|
|
6
6
|
export const VISIBILITY_STATUSES = ['visible-now', 'visible-after-restart', 'not-visible'];
|
|
7
7
|
export function parseAgentHosts(value) {
|
|
8
|
+
if (value?.trim() === 'none')
|
|
9
|
+
return [];
|
|
8
10
|
if (!value || value.trim().length === 0 || value.trim() === 'all')
|
|
9
11
|
return [...AGENT_HOSTS];
|
|
10
12
|
const out = [];
|
|
@@ -19,7 +21,7 @@ export function parseAgentHosts(value) {
|
|
|
19
21
|
unknown.push(token);
|
|
20
22
|
}
|
|
21
23
|
if (unknown.length > 0) {
|
|
22
|
-
throw new Error(`Unknown host(s): ${unknown.join(', ')}. Expected one of: ${AGENT_HOSTS.join(', ')}, all.`);
|
|
24
|
+
throw new Error(`Unknown host(s): ${unknown.join(', ')}. Expected one of: ${AGENT_HOSTS.join(', ')}, all, none.`);
|
|
23
25
|
}
|
|
24
26
|
return [...new Set(out)];
|
|
25
27
|
}
|
|
@@ -54,7 +56,7 @@ export function hostSkillRoots(repoRoot, host, homeDir = homedir()) {
|
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
export function auditHostSkillVisibility(input) {
|
|
57
|
-
const selectedHosts = input.hosts
|
|
59
|
+
const selectedHosts = input.hosts ? [...input.hosts] : [...AGENT_HOSTS];
|
|
58
60
|
const requiredCapabilities = input.requiredCapabilities && input.requiredCapabilities.length > 0
|
|
59
61
|
? [...input.requiredCapabilities]
|
|
60
62
|
: [...REQUIRED_CORE_CAPABILITIES];
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* config keys, and generated surfaces it owns while leaving consumer-owned
|
|
7
7
|
* divergent files untouched unless `--overwrite` is passed.
|
|
8
8
|
*/
|
|
9
|
-
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
10
|
import { basename, dirname, join, relative } from 'node:path';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import { isTelemetryEnabled, reportTthw } from '#telemetry/setup-tthw';
|
|
@@ -26,7 +26,7 @@ import { GENERATED_PATHS_BLOCK, patchGitignore } from './gitignore-patcher.js';
|
|
|
26
26
|
import { scaffoldAgentsMd } from './scaffold-agents-md.js';
|
|
27
27
|
import { scaffoldBlueprints } from './scaffold-blueprints.js';
|
|
28
28
|
import { scaffoldDocs } from './scaffold-docs.js';
|
|
29
|
-
import { scaffoldBaseKit } from './scaffold-base-kit.js';
|
|
29
|
+
import { BASE_KIT_QUALITY_TARGETS, collectRuntimeContractGuidance, scaffoldBaseKit, } from './scaffold-base-kit.js';
|
|
30
30
|
import { scaffoldMonorepoNav } from './scaffold-monorepo-nav.js';
|
|
31
31
|
import { REQUIRED_CORE_CAPABILITIES, auditHostSkillVisibility, parseAgentHosts, serializeHostVisibility, summarizeHostVisibility, } from './host-visibility.js';
|
|
32
32
|
import { scaffoldAgentHooks, trustCodexWebpressoHooksForRepo, trustCodexPresetHooksForUser, } from './scaffolders/agent-hooks/index.js';
|
|
@@ -103,6 +103,31 @@ function inferBlueprintsDirOverride(repoRoot, existingConfig) {
|
|
|
103
103
|
}
|
|
104
104
|
return relativePath;
|
|
105
105
|
}
|
|
106
|
+
function readPackageJsonSafe(repoRoot) {
|
|
107
|
+
const packageJsonPath = join(repoRoot, 'package.json');
|
|
108
|
+
if (!existsSync(packageJsonPath)) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
return JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function printRuntimeContractGuidance(packageJson) {
|
|
119
|
+
const guidance = collectRuntimeContractGuidance(packageJson);
|
|
120
|
+
console.log('\nRuntime-owned tooling contract:');
|
|
121
|
+
console.log(' wp now owns execution for test, e2e, lint, format, and typecheck.');
|
|
122
|
+
console.log(' Keep local dependencies that your tests, configs, or tsconfig types import directly.');
|
|
123
|
+
if (guidance.keepLocalAuthoringDeps.length > 0) {
|
|
124
|
+
console.log(` Keep local authoring deps when imported directly: ${guidance.keepLocalAuthoringDeps.join(', ')}`);
|
|
125
|
+
}
|
|
126
|
+
if (guidance.reviewForRemovalDeps.length > 0) {
|
|
127
|
+
console.log(` Review execution-only deps for removal if they only powered local binaries: ${guidance.reviewForRemovalDeps.join(', ')}`);
|
|
128
|
+
}
|
|
129
|
+
console.log(' Do not blanket-remove devDependencies just because wp can execute the tool.');
|
|
130
|
+
}
|
|
106
131
|
export async function runInit(flags) {
|
|
107
132
|
const startMs = Date.now();
|
|
108
133
|
const cwd = flags.cwd ?? process.cwd();
|
|
@@ -612,6 +637,14 @@ export async function runInit(flags) {
|
|
|
612
637
|
console.log(` drifted: ${summary.drifted}`);
|
|
613
638
|
if (options.dryRun)
|
|
614
639
|
console.log(` would-change: ${summary['skipped-dry']}`);
|
|
640
|
+
if (tier3Selection.includes('base-kit')) {
|
|
641
|
+
const qualityTargets = new Set(BASE_KIT_QUALITY_TARGETS);
|
|
642
|
+
const qualityResults = baseKitResults.filter((result) => qualityTargets.has(relative(consumer.repoRoot, result.targetPath).replaceAll('\\', '/')));
|
|
643
|
+
const qualityCreated = qualityResults.filter((result) => result.action === 'created').length;
|
|
644
|
+
const qualityPreserved = qualityResults.filter((result) => result.action === 'identical').length;
|
|
645
|
+
const qualityDryRun = qualityResults.filter((result) => result.action === 'skipped-dry').length;
|
|
646
|
+
console.log(` repo quality scaffold: ${options.dryRun ? `${qualityDryRun} would be created` : `${qualityCreated} created, ${qualityPreserved} preserved`}`);
|
|
647
|
+
}
|
|
615
648
|
if (summary.drifted > 0) {
|
|
616
649
|
console.log('\n Note: some consumer-owned files exist with different content and were left unchanged.\n' +
|
|
617
650
|
' Review the drift or re-run with `--overwrite` to force eligible managed files.');
|
|
@@ -629,8 +662,13 @@ export async function runInit(flags) {
|
|
|
629
662
|
};
|
|
630
663
|
writeConfig(consumer.repoRoot, config);
|
|
631
664
|
console.log('\nHost skill visibility:');
|
|
632
|
-
|
|
633
|
-
console.log(
|
|
665
|
+
if (visibilityAudit.selectedHosts.length === 0) {
|
|
666
|
+
console.log(' hosts: - skipped (--host none)');
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
for (const line of summarizeHostVisibility(consumer.repoRoot, visibilityAudit)) {
|
|
670
|
+
console.log(line);
|
|
671
|
+
}
|
|
634
672
|
}
|
|
635
673
|
const missing = visibilityAudit.results.filter((result) => result.status === 'not-visible');
|
|
636
674
|
if (missing.length > 0) {
|
|
@@ -659,7 +697,8 @@ export async function runInit(flags) {
|
|
|
659
697
|
}
|
|
660
698
|
}
|
|
661
699
|
}
|
|
662
|
-
|
|
700
|
+
printRuntimeContractGuidance(options.dryRun ? consumer.packageJson : readPackageJsonSafe(consumer.repoRoot) ?? consumer.packageJson);
|
|
701
|
+
console.log('\nwp init: setup phases finished.');
|
|
663
702
|
if (omxFailure === 'not-found')
|
|
664
703
|
return EXIT_SETUP_FAIL;
|
|
665
704
|
if (omxFailure === 'spawn-failed')
|
|
@@ -698,7 +737,7 @@ export async function runInit(flags) {
|
|
|
698
737
|
if (!options.dryRun) {
|
|
699
738
|
console.log([
|
|
700
739
|
'',
|
|
701
|
-
'✅ Setup complete.',
|
|
740
|
+
'✅ Setup complete for the verified phases above.',
|
|
702
741
|
'',
|
|
703
742
|
' Next: wp blueprint new "your first task"',
|
|
704
743
|
' wp gain # token savings after your first session',
|
|
@@ -730,7 +769,7 @@ export function registerInitCommand(cli, commandName = 'init') {
|
|
|
730
769
|
.command(commandName, description)
|
|
731
770
|
.option('--with <skills>', withHelp)
|
|
732
771
|
.option('--without <skills>', withoutHelp)
|
|
733
|
-
.option('--host <hosts>', 'Comma-separated host targets: codex, claude, opencode, all')
|
|
772
|
+
.option('--host <hosts>', 'Comma-separated host targets: codex, claude, opencode, all, none')
|
|
734
773
|
.option('--all', 'Install every skill (Tier-1 + Tier-2 + all Tier-3)')
|
|
735
774
|
.option('--overwrite', 'Force full-file replacement for eligible managed files (default: reconcile owned content and preserve divergent consumer files)')
|
|
736
775
|
.option('--dry-run', 'Show what would change without writing anything')
|
|
@@ -5,5 +5,17 @@ export interface ScaffoldBaseKitInput {
|
|
|
5
5
|
options: MergeOptions;
|
|
6
6
|
globalInstall?: boolean;
|
|
7
7
|
}
|
|
8
|
+
export interface RuntimeContractGuidance {
|
|
9
|
+
keepLocalAuthoringDeps: string[];
|
|
10
|
+
reviewForRemovalDeps: string[];
|
|
11
|
+
}
|
|
12
|
+
interface PackageJsonLike {
|
|
13
|
+
dependencies?: Record<string, string>;
|
|
14
|
+
devDependencies?: Record<string, string>;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export declare function collectRuntimeContractGuidance(packageJson: PackageJsonLike | null | undefined): RuntimeContractGuidance;
|
|
18
|
+
export declare const BASE_KIT_QUALITY_TARGETS: string[];
|
|
8
19
|
export declare function scaffoldBaseKit(input: ScaffoldBaseKitInput): MergeResult[];
|
|
20
|
+
export {};
|
|
9
21
|
//# sourceMappingURL=scaffold-base-kit.d.ts.map
|