wingfoil 0.2.1
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/LICENSE +21 -0
- package/README.md +334 -0
- package/dist/cli/error.d.ts +11 -0
- package/dist/cli/error.d.ts.map +1 -0
- package/dist/cli/error.js +27 -0
- package/dist/cli/error.js.map +1 -0
- package/dist/cli/exit.d.ts +19 -0
- package/dist/cli/exit.d.ts.map +1 -0
- package/dist/cli/exit.js +14 -0
- package/dist/cli/exit.js.map +1 -0
- package/dist/cli/index.d.ts +28 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +36 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-command.d.ts +34 -0
- package/dist/cli/init-command.d.ts.map +1 -0
- package/dist/cli/init-command.js +100 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/mcp-command.d.ts +24 -0
- package/dist/cli/mcp-command.d.ts.map +1 -0
- package/dist/cli/mcp-command.js +42 -0
- package/dist/cli/mcp-command.js.map +1 -0
- package/dist/cli/output.d.ts +13 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +28 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/program.d.ts +12 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +279 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/registrar.d.ts +69 -0
- package/dist/cli/registrar.d.ts.map +1 -0
- package/dist/cli/registrar.js +82 -0
- package/dist/cli/registrar.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +45 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/approval-authority.d.ts +83 -0
- package/dist/core/approval-authority.d.ts.map +1 -0
- package/dist/core/approval-authority.js +112 -0
- package/dist/core/approval-authority.js.map +1 -0
- package/dist/core/builtin-asset.d.ts +71 -0
- package/dist/core/builtin-asset.d.ts.map +1 -0
- package/dist/core/builtin-asset.js +137 -0
- package/dist/core/builtin-asset.js.map +1 -0
- package/dist/core/builtin-integrity.d.ts +32 -0
- package/dist/core/builtin-integrity.d.ts.map +1 -0
- package/dist/core/builtin-integrity.js +148 -0
- package/dist/core/builtin-integrity.js.map +1 -0
- package/dist/core/confinement.d.ts +57 -0
- package/dist/core/confinement.d.ts.map +1 -0
- package/dist/core/confinement.js +108 -0
- package/dist/core/confinement.js.map +1 -0
- package/dist/core/context.d.ts +187 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +192 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/directive-assign.d.ts +131 -0
- package/dist/core/directive-assign.d.ts.map +1 -0
- package/dist/core/directive-assign.js +352 -0
- package/dist/core/directive-assign.js.map +1 -0
- package/dist/core/directives-list.d.ts +80 -0
- package/dist/core/directives-list.d.ts.map +1 -0
- package/dist/core/directives-list.js +148 -0
- package/dist/core/directives-list.js.map +1 -0
- package/dist/core/exit-code.d.ts +85 -0
- package/dist/core/exit-code.d.ts.map +1 -0
- package/dist/core/exit-code.js +163 -0
- package/dist/core/exit-code.js.map +1 -0
- package/dist/core/git-identity.d.ts +32 -0
- package/dist/core/git-identity.d.ts.map +1 -0
- package/dist/core/git-identity.js +72 -0
- package/dist/core/git-identity.js.map +1 -0
- package/dist/core/index.d.ts +388 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +1331 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/init.d.ts +78 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +167 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/loaders.d.ts +174 -0
- package/dist/core/loaders.d.ts.map +1 -0
- package/dist/core/loaders.js +364 -0
- package/dist/core/loaders.js.map +1 -0
- package/dist/core/memory-add-type.d.ts +43 -0
- package/dist/core/memory-add-type.d.ts.map +1 -0
- package/dist/core/memory-add-type.js +151 -0
- package/dist/core/memory-add-type.js.map +1 -0
- package/dist/core/memory-transition.d.ts +111 -0
- package/dist/core/memory-transition.d.ts.map +1 -0
- package/dist/core/memory-transition.js +269 -0
- package/dist/core/memory-transition.js.map +1 -0
- package/dist/core/registry.d.ts +189 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +66 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/relevance.d.ts +86 -0
- package/dist/core/relevance.d.ts.map +1 -0
- package/dist/core/relevance.js +258 -0
- package/dist/core/relevance.js.map +1 -0
- package/dist/core/require-reason.d.ts +27 -0
- package/dist/core/require-reason.d.ts.map +1 -0
- package/dist/core/require-reason.js +95 -0
- package/dist/core/require-reason.js.map +1 -0
- package/dist/core/types.d.ts +45 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +22 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/usage-error.d.ts +20 -0
- package/dist/core/usage-error.d.ts.map +1 -0
- package/dist/core/usage-error.js +29 -0
- package/dist/core/usage-error.js.map +1 -0
- package/dist/core/write-guard.d.ts +99 -0
- package/dist/core/write-guard.d.ts.map +1 -0
- package/dist/core/write-guard.js +247 -0
- package/dist/core/write-guard.js.map +1 -0
- package/dist/directives/create.d.ts +47 -0
- package/dist/directives/create.d.ts.map +1 -0
- package/dist/directives/create.js +82 -0
- package/dist/directives/create.js.map +1 -0
- package/dist/directives/index.d.ts +20 -0
- package/dist/directives/index.d.ts.map +1 -0
- package/dist/directives/index.js +32 -0
- package/dist/directives/index.js.map +1 -0
- package/dist/directives/roles-edit.d.ts +53 -0
- package/dist/directives/roles-edit.d.ts.map +1 -0
- package/dist/directives/roles-edit.js +286 -0
- package/dist/directives/roles-edit.js.map +1 -0
- package/dist/directives/schema.d.ts +65 -0
- package/dist/directives/schema.d.ts.map +1 -0
- package/dist/directives/schema.js +68 -0
- package/dist/directives/schema.js.map +1 -0
- package/dist/dna/edit.d.ts +61 -0
- package/dist/dna/edit.d.ts.map +1 -0
- package/dist/dna/edit.js +429 -0
- package/dist/dna/edit.js.map +1 -0
- package/dist/dna/index.d.ts +24 -0
- package/dist/dna/index.d.ts.map +1 -0
- package/dist/dna/index.js +59 -0
- package/dist/dna/index.js.map +1 -0
- package/dist/dna/mutate.d.ts +74 -0
- package/dist/dna/mutate.d.ts.map +1 -0
- package/dist/dna/mutate.js +318 -0
- package/dist/dna/mutate.js.map +1 -0
- package/dist/dna/path.d.ts +175 -0
- package/dist/dna/path.d.ts.map +1 -0
- package/dist/dna/path.js +289 -0
- package/dist/dna/path.js.map +1 -0
- package/dist/dna/roles.d.ts +57 -0
- package/dist/dna/roles.d.ts.map +1 -0
- package/dist/dna/roles.js +50 -0
- package/dist/dna/roles.js.map +1 -0
- package/dist/dna/schema.d.ts +172 -0
- package/dist/dna/schema.d.ts.map +1 -0
- package/dist/dna/schema.js +182 -0
- package/dist/dna/schema.js.map +1 -0
- package/dist/dna/set.d.ts +145 -0
- package/dist/dna/set.d.ts.map +1 -0
- package/dist/dna/set.js +428 -0
- package/dist/dna/set.js.map +1 -0
- package/dist/mcp/dna-resource.d.ts +16 -0
- package/dist/mcp/dna-resource.d.ts.map +1 -0
- package/dist/mcp/dna-resource.js +56 -0
- package/dist/mcp/dna-resource.js.map +1 -0
- package/dist/mcp/index.d.ts +49 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +60 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/memory-resource.d.ts +17 -0
- package/dist/mcp/memory-resource.d.ts.map +1 -0
- package/dist/mcp/memory-resource.js +133 -0
- package/dist/mcp/memory-resource.js.map +1 -0
- package/dist/mcp/prompt.d.ts +48 -0
- package/dist/mcp/prompt.d.ts.map +1 -0
- package/dist/mcp/prompt.js +176 -0
- package/dist/mcp/prompt.js.map +1 -0
- package/dist/mcp/read-only.d.ts +42 -0
- package/dist/mcp/read-only.d.ts.map +1 -0
- package/dist/mcp/read-only.js +93 -0
- package/dist/mcp/read-only.js.map +1 -0
- package/dist/mcp/registrar.d.ts +54 -0
- package/dist/mcp/registrar.d.ts.map +1 -0
- package/dist/mcp/registrar.js +72 -0
- package/dist/mcp/registrar.js.map +1 -0
- package/dist/mcp/server.d.ts +58 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +64 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/workflow-resource.d.ts +17 -0
- package/dist/mcp/workflow-resource.d.ts.map +1 -0
- package/dist/mcp/workflow-resource.js +63 -0
- package/dist/mcp/workflow-resource.js.map +1 -0
- package/dist/memory/add.d.ts +50 -0
- package/dist/memory/add.d.ts.map +1 -0
- package/dist/memory/add.js +131 -0
- package/dist/memory/add.js.map +1 -0
- package/dist/memory/audit.d.ts +177 -0
- package/dist/memory/audit.d.ts.map +1 -0
- package/dist/memory/audit.js +287 -0
- package/dist/memory/audit.js.map +1 -0
- package/dist/memory/commit-message.d.ts +146 -0
- package/dist/memory/commit-message.d.ts.map +1 -0
- package/dist/memory/commit-message.js +203 -0
- package/dist/memory/commit-message.js.map +1 -0
- package/dist/memory/entry.d.ts +56 -0
- package/dist/memory/entry.d.ts.map +1 -0
- package/dist/memory/entry.js +28 -0
- package/dist/memory/entry.js.map +1 -0
- package/dist/memory/frontmatter-edit.d.ts +68 -0
- package/dist/memory/frontmatter-edit.d.ts.map +1 -0
- package/dist/memory/frontmatter-edit.js +333 -0
- package/dist/memory/frontmatter-edit.js.map +1 -0
- package/dist/memory/git-log.d.ts +32 -0
- package/dist/memory/git-log.d.ts.map +1 -0
- package/dist/memory/git-log.js +100 -0
- package/dist/memory/git-log.js.map +1 -0
- package/dist/memory/history.d.ts +142 -0
- package/dist/memory/history.d.ts.map +1 -0
- package/dist/memory/history.js +250 -0
- package/dist/memory/history.js.map +1 -0
- package/dist/memory/index.d.ts +58 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +107 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/query.d.ts +150 -0
- package/dist/memory/query.d.ts.map +1 -0
- package/dist/memory/query.js +307 -0
- package/dist/memory/query.js.map +1 -0
- package/dist/memory/reject.d.ts +11 -0
- package/dist/memory/reject.d.ts.map +1 -0
- package/dist/memory/reject.js +32 -0
- package/dist/memory/reject.js.map +1 -0
- package/dist/memory/schema.d.ts +104 -0
- package/dist/memory/schema.d.ts.map +1 -0
- package/dist/memory/schema.js +161 -0
- package/dist/memory/schema.js.map +1 -0
- package/dist/memory/state-machine.d.ts +166 -0
- package/dist/memory/state-machine.d.ts.map +1 -0
- package/dist/memory/state-machine.js +431 -0
- package/dist/memory/state-machine.js.map +1 -0
- package/dist/memory/submit.d.ts +11 -0
- package/dist/memory/submit.d.ts.map +1 -0
- package/dist/memory/submit.js +44 -0
- package/dist/memory/submit.js.map +1 -0
- package/dist/storage/builtin-directives.d.ts +54 -0
- package/dist/storage/builtin-directives.d.ts.map +1 -0
- package/dist/storage/builtin-directives.js +152 -0
- package/dist/storage/builtin-directives.js.map +1 -0
- package/dist/storage/commit.d.ts +92 -0
- package/dist/storage/commit.d.ts.map +1 -0
- package/dist/storage/commit.js +201 -0
- package/dist/storage/commit.js.map +1 -0
- package/dist/storage/confinement.d.ts +93 -0
- package/dist/storage/confinement.d.ts.map +1 -0
- package/dist/storage/confinement.js +164 -0
- package/dist/storage/confinement.js.map +1 -0
- package/dist/storage/document.d.ts +27 -0
- package/dist/storage/document.d.ts.map +1 -0
- package/dist/storage/document.js +52 -0
- package/dist/storage/document.js.map +1 -0
- package/dist/storage/errors.d.ts +36 -0
- package/dist/storage/errors.d.ts.map +1 -0
- package/dist/storage/errors.js +46 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/frontmatter.d.ts +27 -0
- package/dist/storage/frontmatter.d.ts.map +1 -0
- package/dist/storage/frontmatter.js +37 -0
- package/dist/storage/frontmatter.js.map +1 -0
- package/dist/storage/git-root.d.ts +17 -0
- package/dist/storage/git-root.d.ts.map +1 -0
- package/dist/storage/git-root.js +49 -0
- package/dist/storage/git-root.js.map +1 -0
- package/dist/storage/index.d.ts +29 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +66 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/init-state.d.ts +9 -0
- package/dist/storage/init-state.d.ts.map +1 -0
- package/dist/storage/init-state.js +24 -0
- package/dist/storage/init-state.js.map +1 -0
- package/dist/storage/layout.d.ts +51 -0
- package/dist/storage/layout.d.ts.map +1 -0
- package/dist/storage/layout.js +88 -0
- package/dist/storage/layout.js.map +1 -0
- package/dist/storage/memory-path.d.ts +72 -0
- package/dist/storage/memory-path.d.ts.map +1 -0
- package/dist/storage/memory-path.js +127 -0
- package/dist/storage/memory-path.js.map +1 -0
- package/dist/storage/snapshot.d.ts +16 -0
- package/dist/storage/snapshot.d.ts.map +1 -0
- package/dist/storage/snapshot.js +72 -0
- package/dist/storage/snapshot.js.map +1 -0
- package/dist/storage/templates.d.ts +88 -0
- package/dist/storage/templates.d.ts.map +1 -0
- package/dist/storage/templates.js +422 -0
- package/dist/storage/templates.js.map +1 -0
- package/dist/validation/error-mapper.d.ts +16 -0
- package/dist/validation/error-mapper.d.ts.map +1 -0
- package/dist/validation/error-mapper.js +18 -0
- package/dist/validation/error-mapper.js.map +1 -0
- package/dist/validation/errors.d.ts +69 -0
- package/dist/validation/errors.d.ts.map +1 -0
- package/dist/validation/errors.js +69 -0
- package/dist/validation/errors.js.map +1 -0
- package/dist/validation/id.d.ts +16 -0
- package/dist/validation/id.d.ts.map +1 -0
- package/dist/validation/id.js +177 -0
- package/dist/validation/id.js.map +1 -0
- package/dist/validation/index.d.ts +18 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +37 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/secret-scan.d.ts +129 -0
- package/dist/validation/secret-scan.d.ts.map +1 -0
- package/dist/validation/secret-scan.js +367 -0
- package/dist/validation/secret-scan.js.map +1 -0
- package/dist/validation/two-pass.d.ts +24 -0
- package/dist/validation/two-pass.d.ts.map +1 -0
- package/dist/validation/two-pass.js +24 -0
- package/dist/validation/two-pass.js.map +1 -0
- package/dist/validation/warning.d.ts +31 -0
- package/dist/validation/warning.d.ts.map +1 -0
- package/dist/validation/warning.js +81 -0
- package/dist/validation/warning.js.map +1 -0
- package/dist/validation/yaml.d.ts +9 -0
- package/dist/validation/yaml.d.ts.map +1 -0
- package/dist/validation/yaml.js +30 -0
- package/dist/validation/yaml.js.map +1 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +16 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/schema.d.ts +89 -0
- package/dist/workflow/schema.d.ts.map +1 -0
- package/dist/workflow/schema.js +73 -0
- package/dist/workflow/schema.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type ScaffoldFile } from './layout';
|
|
2
|
+
/** A methodology starter template: the methodologies it seeds and the delivery sub-workflow it adds. */
|
|
3
|
+
export interface TemplateDefinition {
|
|
4
|
+
/** Canonical display name, e.g. `Scrum` (matched case-insensitively by {@link resolveTemplate}). */
|
|
5
|
+
readonly name: string;
|
|
6
|
+
/** One-line human description surfaced in the wizard and generated headers. */
|
|
7
|
+
readonly description: string;
|
|
8
|
+
/** Methodologies written into `dna.yaml` `stacks.methodologies`. */
|
|
9
|
+
readonly methodologies: readonly string[];
|
|
10
|
+
/** Lower-case slug used for the delivery workflow filename (`<slug>-delivery.yaml`). */
|
|
11
|
+
readonly slug: string;
|
|
12
|
+
/** Human sentence describing the delivery cadence, embedded in the delivery workflow. */
|
|
13
|
+
readonly cadence: string;
|
|
14
|
+
}
|
|
15
|
+
/** The built-in methodology templates. Order fixed for deterministic listing (REQ-SYS-07). */
|
|
16
|
+
export declare const TEMPLATES: readonly TemplateDefinition[];
|
|
17
|
+
/** Canonical template names, in registry order (used by the wizard prompt and error messages). */
|
|
18
|
+
export declare const TEMPLATE_NAMES: readonly string[];
|
|
19
|
+
/** The template the wizard falls back to when the user selects nothing (first registered template). */
|
|
20
|
+
export declare const DEFAULT_TEMPLATE: string;
|
|
21
|
+
/** Resolve a (case-insensitive) template name to its canonical definition, or `null` if unknown. */
|
|
22
|
+
export declare function resolveTemplate(name: string): TemplateDefinition | null;
|
|
23
|
+
/** The single git subject `wingfoil init` commits (names the chosen template; deterministic). */
|
|
24
|
+
export declare function initProjectCommitMessage(def: TemplateDefinition): string;
|
|
25
|
+
/**
|
|
26
|
+
* Which pillar a {@link BuiltinTemplateSource} belongs to — `directive` for a P3.8 built-in directive
|
|
27
|
+
* `.md` file, `workflow` for a P4.17 built-in workflow `.yaml` file. Drives which pillar schema
|
|
28
|
+
* `core/builtin-integrity.ts`'s `verifyBuiltinTemplates` checks the source against, and which of
|
|
29
|
+
* REQ-SEC-10's two exact abort-message shapes a failure produces.
|
|
30
|
+
*/
|
|
31
|
+
export type BuiltinTemplateKind = 'directive' | 'workflow';
|
|
32
|
+
/**
|
|
33
|
+
* One shipped built-in template asset, as raw content — a directive's full `.md` text (frontmatter +
|
|
34
|
+
* body) or a workflow's full `.yaml` text, exactly as it would be written under `.wingfoil/directives/
|
|
35
|
+
* built-in/` or `.wingfoil/workflows/built-in/`. This is the pure DATA shape only; `name`/`kind` are
|
|
36
|
+
* enough to identify and classify a source, and pillar-schema validation itself is a cross-pillar
|
|
37
|
+
* concern that lives in `core/builtin-integrity.ts` (this module never imports a pillar schema —
|
|
38
|
+
* REQ-SYS-02 keeps `storage` decoupled from `directives`/`workflow`).
|
|
39
|
+
*/
|
|
40
|
+
export interface BuiltinTemplateSource {
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly kind: BuiltinTemplateKind;
|
|
43
|
+
readonly content: string;
|
|
44
|
+
}
|
|
45
|
+
/** Scaffold directory holding the P3.8 built-in directive templates (spec-011 storage layout). */
|
|
46
|
+
export declare const BUILTIN_DIRECTIVES_DIR = ".wingfoil/directives/built-in";
|
|
47
|
+
/** Scaffold directory holding the P4.17 built-in workflow templates (spec-011 storage layout). */
|
|
48
|
+
export declare const BUILTIN_WORKFLOWS_DIR = ".wingfoil/workflows/built-in";
|
|
49
|
+
/**
|
|
50
|
+
* Derive the built-in template assets to schema-check (REQ-SEC-10) from the very `ScaffoldFile[]`
|
|
51
|
+
* that `initStorage` is about to write — so the CHECKED set and the INSTALLED set are the same set by
|
|
52
|
+
* construction.
|
|
53
|
+
*
|
|
54
|
+
* This replaces the hand-maintained `BUILTIN_TEMPLATE_SOURCES` constant the first pass of
|
|
55
|
+
* `task-044-builtin-template-integrity` shipped. A standalone registry is fail-open by omission: a
|
|
56
|
+
* later task (`task-057` for P3.8, or a P4.17 workflow-template task) can add an asset to
|
|
57
|
+
* {@link templateScaffold} and forget the registry, installing a template nothing ever checks while
|
|
58
|
+
* every existing test stays green. Deriving makes "installed but unchecked" unrepresentable rather
|
|
59
|
+
* than merely untested — the fix `dl-031-req-sec-10-integrity-depth` flagged. (dl-031 ratified that
|
|
60
|
+
* schema validation IS the REQ-SEC-10 contract; there is deliberately no digest or manifest here.)
|
|
61
|
+
*
|
|
62
|
+
* Pure and order-preserving over `files` (REQ-SYS-07), so the derived order — and hence
|
|
63
|
+
* `verifyBuiltinTemplates`' first-failure choice — is the caller's own order, deterministic whenever
|
|
64
|
+
* that is. Both of today's callers qualify, for different reasons: {@link templateScaffold} returns a
|
|
65
|
+
* genuinely path-sorted list, whereas `scaffoldFiles` (./layout) returns a fixed hand-written literal
|
|
66
|
+
* that is stable but NOT sorted (see its doc comment). Reproducible is what matters here, not sorted.
|
|
67
|
+
*
|
|
68
|
+
* BOTH scaffolds flow through here since `task-054-project-directives`: `scaffoldFiles()` now reserves
|
|
69
|
+
* `.wingfoil/directives/built-in/` for the P3.5 layout, and `initWingfoilStorage` derives its checked
|
|
70
|
+
* set from it exactly as `initWingfoilProject` does from {@link templateScaffold}
|
|
71
|
+
* (`bug-018-init-storage-bypasses-integrity-guard`). Being generic over `ScaffoldFile[]` is what made
|
|
72
|
+
* that a one-line wiring rather than a second mechanism.
|
|
73
|
+
*
|
|
74
|
+
* What it returns is a fact about the scaffold CONTENT, not a property of this function: for
|
|
75
|
+
* {@link templateScaffold} it is the six P3.8 built-in directives `task-057-builtin-directive-templates`
|
|
76
|
+
* ships (`./builtin-directives`, rendered by `builtinDirectiveMd`), for `scaffoldFiles` it is `[]` (a
|
|
77
|
+
* `.gitkeep` only), and the workflows built-in directory still holds a `.gitkeep` only. Any asset added
|
|
78
|
+
* later is checked with no edit here. Each shipped built-in must satisfy its pillar schema on its own —
|
|
79
|
+
* `test/storage/builtin-directives.test.ts` runs every directive template through the real guard.
|
|
80
|
+
*/
|
|
81
|
+
export declare function builtinTemplateSources(files: readonly ScaffoldFile[]): BuiltinTemplateSource[];
|
|
82
|
+
/**
|
|
83
|
+
* The COMPLETE spec-011 `.wingfoil/` layout for `def`, as a `ScaffoldFile[]` sorted by path
|
|
84
|
+
* (deterministic — REQ-SYS-07). Consumed by `initStorage(root, files, message)`; every path is under
|
|
85
|
+
* `.wingfoil/` so init never writes outside the WingFoil root.
|
|
86
|
+
*/
|
|
87
|
+
export declare function templateScaffold(def: TemplateDefinition): ScaffoldFile[];
|
|
88
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/storage/templates.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAE3D,wGAAwG;AACxG,MAAM,WAAW,kBAAkB;IACjC,oGAAoG;IACpG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAkBD,8FAA8F;AAC9F,eAAO,MAAM,SAAS,EAAE,SAAS,kBAAkB,EAAoB,CAAC;AAExE,kGAAkG;AAClG,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAiC,CAAC;AAE9E,uGAAuG;AACvG,eAAO,MAAM,gBAAgB,EAAE,MAAmB,CAAC;AAEnD,oGAAoG;AACpG,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAGvE;AAED,iGAAiG;AACjG,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAExE;AAID;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,UAAU,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,kGAAkG;AAClG,eAAO,MAAM,sBAAsB,kCAAwC,CAAC;AAE5E,kGAAkG;AAClG,eAAO,MAAM,qBAAqB,iCAAuC,CAAC;AAyB1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,qBAAqB,EAAE,CAO9F;AA8QD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE,CA2CxE"}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BUILTIN_WORKFLOWS_DIR = exports.BUILTIN_DIRECTIVES_DIR = exports.DEFAULT_TEMPLATE = exports.TEMPLATE_NAMES = exports.TEMPLATES = void 0;
|
|
4
|
+
exports.resolveTemplate = resolveTemplate;
|
|
5
|
+
exports.initProjectCommitMessage = initProjectCommitMessage;
|
|
6
|
+
exports.builtinTemplateSources = builtinTemplateSources;
|
|
7
|
+
exports.templateScaffold = templateScaffold;
|
|
8
|
+
/**
|
|
9
|
+
* Methodology templates for `wingfoil init` (task-029-implement-wingfoil-init, P5.1.1,
|
|
10
|
+
* spec-011-storage-layout). task-018 delivered only the minimal committed skeleton
|
|
11
|
+
* (`scaffoldFiles()` in ./layout) and EXPLICITLY deferred the complete spec-011 layout — `roles.yaml`,
|
|
12
|
+
* the `workflows/{built-in,custom}` split, `memory/templates/`, and real starter content — to this
|
|
13
|
+
* module. `templateScaffold(def)` returns that complete layout as a `ScaffoldFile[]` the same
|
|
14
|
+
* `initStorage(root, files, message)` write+commit path consumes. (The `directives/{built-in,custom}`
|
|
15
|
+
* split was deferred here too, until `task-054-project-directives` pulled it back into the minimal
|
|
16
|
+
* skeleton as well: P3.5 requires it after init, on whichever path ran.)
|
|
17
|
+
*
|
|
18
|
+
* A "template" (Scrum, Kanban — the names the P5.1.1 BDD uses as examples) is an AUTHORING starter:
|
|
19
|
+
* it selects the project's methodologies (written into `dna.yaml` `stacks.methodologies`) and a
|
|
20
|
+
* methodology-flavoured delivery sub-workflow; it is not a spec-mandated schema. All generated content
|
|
21
|
+
* is a pure function of the `TemplateDefinition` — no wall-clock, no randomness, no environment read —
|
|
22
|
+
* so `wingfoil init --template X` is byte-identical run to run (REQ-SYS-07), and the returned list is
|
|
23
|
+
* sorted by path so callers may diff the set safely.
|
|
24
|
+
*/
|
|
25
|
+
const builtin_directives_1 = require("./builtin-directives");
|
|
26
|
+
const layout_1 = require("./layout");
|
|
27
|
+
const SCRUM = {
|
|
28
|
+
name: 'Scrum',
|
|
29
|
+
description: 'Sprint-based iterative delivery with fixed-length timeboxes.',
|
|
30
|
+
methodologies: ['Scrum', 'Specification by Example (BDD)', 'TDD'],
|
|
31
|
+
slug: 'scrum',
|
|
32
|
+
cadence: 'Work is delivered in fixed-length sprints; each sprint plans, builds, reviews and retrospects a slice of the backlog.',
|
|
33
|
+
};
|
|
34
|
+
const KANBAN = {
|
|
35
|
+
name: 'Kanban',
|
|
36
|
+
description: 'Continuous-flow delivery with work-in-progress limits.',
|
|
37
|
+
methodologies: ['Kanban', 'Specification by Example (BDD)', 'TDD'],
|
|
38
|
+
slug: 'kanban',
|
|
39
|
+
cadence: 'Work flows continuously across the board under explicit WIP limits; there are no timeboxed iterations.',
|
|
40
|
+
};
|
|
41
|
+
/** The built-in methodology templates. Order fixed for deterministic listing (REQ-SYS-07). */
|
|
42
|
+
exports.TEMPLATES = [SCRUM, KANBAN];
|
|
43
|
+
/** Canonical template names, in registry order (used by the wizard prompt and error messages). */
|
|
44
|
+
exports.TEMPLATE_NAMES = exports.TEMPLATES.map((t) => t.name);
|
|
45
|
+
/** The template the wizard falls back to when the user selects nothing (first registered template). */
|
|
46
|
+
exports.DEFAULT_TEMPLATE = SCRUM.name;
|
|
47
|
+
/** Resolve a (case-insensitive) template name to its canonical definition, or `null` if unknown. */
|
|
48
|
+
function resolveTemplate(name) {
|
|
49
|
+
const wanted = name.trim().toLowerCase();
|
|
50
|
+
return exports.TEMPLATES.find((t) => t.name.toLowerCase() === wanted) ?? null;
|
|
51
|
+
}
|
|
52
|
+
/** The single git subject `wingfoil init` commits (names the chosen template; deterministic). */
|
|
53
|
+
function initProjectCommitMessage(def) {
|
|
54
|
+
return `chore(wingfoil): initialize .wingfoil/ with the ${def.name} template (P5.1.1)`;
|
|
55
|
+
}
|
|
56
|
+
/** Scaffold directory holding the P3.8 built-in directive templates (spec-011 storage layout). */
|
|
57
|
+
exports.BUILTIN_DIRECTIVES_DIR = `${layout_1.WINGFOIL_DIR}/directives/built-in`;
|
|
58
|
+
/** Scaffold directory holding the P4.17 built-in workflow templates (spec-011 storage layout). */
|
|
59
|
+
exports.BUILTIN_WORKFLOWS_DIR = `${layout_1.WINGFOIL_DIR}/workflows/built-in`;
|
|
60
|
+
/**
|
|
61
|
+
* The built-in source one scaffold file contributes, or `null` when the file is not a built-in
|
|
62
|
+
* template asset.
|
|
63
|
+
*
|
|
64
|
+
* Kind comes from the DIRECTORY holding the file, never from its extension: an unexpected file shape
|
|
65
|
+
* under a built-in directory is then still CHECKED (and fails, naming itself) instead of being waved
|
|
66
|
+
* through by an extension filter — the fail-closed reading. `name` is the basename with its final
|
|
67
|
+
* extension stripped. Dotfile placeholders (`.gitkeep`, which reserve an empty directory in git and
|
|
68
|
+
* carry no template content) are the single exclusion.
|
|
69
|
+
*/
|
|
70
|
+
function builtinSourceOf(file) {
|
|
71
|
+
const base = file.path.slice(file.path.lastIndexOf('/') + 1);
|
|
72
|
+
if (base === '' || base.startsWith('.'))
|
|
73
|
+
return null;
|
|
74
|
+
let kind;
|
|
75
|
+
if (file.path.startsWith(`${exports.BUILTIN_DIRECTIVES_DIR}/`))
|
|
76
|
+
kind = 'directive';
|
|
77
|
+
else if (file.path.startsWith(`${exports.BUILTIN_WORKFLOWS_DIR}/`))
|
|
78
|
+
kind = 'workflow';
|
|
79
|
+
else
|
|
80
|
+
return null;
|
|
81
|
+
const dot = base.lastIndexOf('.');
|
|
82
|
+
return { name: dot > 0 ? base.slice(0, dot) : base, kind, content: file.content };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Derive the built-in template assets to schema-check (REQ-SEC-10) from the very `ScaffoldFile[]`
|
|
86
|
+
* that `initStorage` is about to write — so the CHECKED set and the INSTALLED set are the same set by
|
|
87
|
+
* construction.
|
|
88
|
+
*
|
|
89
|
+
* This replaces the hand-maintained `BUILTIN_TEMPLATE_SOURCES` constant the first pass of
|
|
90
|
+
* `task-044-builtin-template-integrity` shipped. A standalone registry is fail-open by omission: a
|
|
91
|
+
* later task (`task-057` for P3.8, or a P4.17 workflow-template task) can add an asset to
|
|
92
|
+
* {@link templateScaffold} and forget the registry, installing a template nothing ever checks while
|
|
93
|
+
* every existing test stays green. Deriving makes "installed but unchecked" unrepresentable rather
|
|
94
|
+
* than merely untested — the fix `dl-031-req-sec-10-integrity-depth` flagged. (dl-031 ratified that
|
|
95
|
+
* schema validation IS the REQ-SEC-10 contract; there is deliberately no digest or manifest here.)
|
|
96
|
+
*
|
|
97
|
+
* Pure and order-preserving over `files` (REQ-SYS-07), so the derived order — and hence
|
|
98
|
+
* `verifyBuiltinTemplates`' first-failure choice — is the caller's own order, deterministic whenever
|
|
99
|
+
* that is. Both of today's callers qualify, for different reasons: {@link templateScaffold} returns a
|
|
100
|
+
* genuinely path-sorted list, whereas `scaffoldFiles` (./layout) returns a fixed hand-written literal
|
|
101
|
+
* that is stable but NOT sorted (see its doc comment). Reproducible is what matters here, not sorted.
|
|
102
|
+
*
|
|
103
|
+
* BOTH scaffolds flow through here since `task-054-project-directives`: `scaffoldFiles()` now reserves
|
|
104
|
+
* `.wingfoil/directives/built-in/` for the P3.5 layout, and `initWingfoilStorage` derives its checked
|
|
105
|
+
* set from it exactly as `initWingfoilProject` does from {@link templateScaffold}
|
|
106
|
+
* (`bug-018-init-storage-bypasses-integrity-guard`). Being generic over `ScaffoldFile[]` is what made
|
|
107
|
+
* that a one-line wiring rather than a second mechanism.
|
|
108
|
+
*
|
|
109
|
+
* What it returns is a fact about the scaffold CONTENT, not a property of this function: for
|
|
110
|
+
* {@link templateScaffold} it is the six P3.8 built-in directives `task-057-builtin-directive-templates`
|
|
111
|
+
* ships (`./builtin-directives`, rendered by `builtinDirectiveMd`), for `scaffoldFiles` it is `[]` (a
|
|
112
|
+
* `.gitkeep` only), and the workflows built-in directory still holds a `.gitkeep` only. Any asset added
|
|
113
|
+
* later is checked with no edit here. Each shipped built-in must satisfy its pillar schema on its own —
|
|
114
|
+
* `test/storage/builtin-directives.test.ts` runs every directive template through the real guard.
|
|
115
|
+
*/
|
|
116
|
+
function builtinTemplateSources(files) {
|
|
117
|
+
const sources = [];
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
const source = builtinSourceOf(file);
|
|
120
|
+
if (source !== null)
|
|
121
|
+
sources.push(source);
|
|
122
|
+
}
|
|
123
|
+
return sources;
|
|
124
|
+
}
|
|
125
|
+
// --- Content generators -----------------------------------------------------------------------
|
|
126
|
+
// Every generator is a pure function of its inputs (REQ-SYS-07): fixed strings only, no Date/random.
|
|
127
|
+
const wf = (relative) => `${layout_1.WINGFOIL_DIR}/${relative}`;
|
|
128
|
+
/** The Memory element types spec-011 requires a template scaffold for, in fixed order. */
|
|
129
|
+
const MEMORY_TYPES = ['adr', 'bug', 'decision-log', 'release', 'release-line', 'task', 'tech-spec'];
|
|
130
|
+
/**
|
|
131
|
+
* Default `id_pattern` per scaffolded type (task-002-validation-id-engine's `{n}`/`{slug}` token
|
|
132
|
+
* grammar, `src/validation/id.ts`) — required by `memoryAdd` (`src/core/index.ts`) even though
|
|
133
|
+
* `memory.yaml`'s own schema only marks the field `.optional()` (bug-005-init-scaffold-fails-schema-validation:
|
|
134
|
+
* without this, a freshly-`init`'d project's `wingfoil memory add` fails on every type). Mirrors this
|
|
135
|
+
* repository's own dogfooded `docs/self/.wingfoil/memory.yaml` scheme, a sensible [AUTHORING] default
|
|
136
|
+
* a user is free to change.
|
|
137
|
+
*/
|
|
138
|
+
const MEMORY_ID_PATTERNS = {
|
|
139
|
+
adr: 'adr-{n}-{slug}',
|
|
140
|
+
bug: 'bug-{n}-{slug}',
|
|
141
|
+
'decision-log': 'dl-{n}-{slug}',
|
|
142
|
+
release: 'release-{n}',
|
|
143
|
+
'release-line': 'rl-{n}',
|
|
144
|
+
task: 'task-{n}-{slug}',
|
|
145
|
+
'tech-spec': 'spec-{n}-{slug}',
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* The cross-cutting CUSTOM directives every starter project gets under `directives/custom/` — AUTHORING
|
|
149
|
+
* starters the user tailors. The six P3.8 categories are not here: since
|
|
150
|
+
* `task-057-builtin-directive-templates` they ship as official built-ins (`./builtin-directives`,
|
|
151
|
+
* installed under `directives/built-in/`), replacing the generated `custom/` stand-ins that would
|
|
152
|
+
* otherwise shadow them on every fresh project (`dl-037`: a same-id `custom/` file wins and is reported).
|
|
153
|
+
*/
|
|
154
|
+
const DIRECTIVES = [
|
|
155
|
+
{ name: 'determinism', title: 'Determinism', summary: 'No wall-clock, randomness, or unordered iteration in context-building paths; prefer declared config.' },
|
|
156
|
+
{ name: 'doc-versioning', title: 'Documentation versioning', summary: 'Bump a document version only on the first edit after it was committed; update its date when bumping.' },
|
|
157
|
+
{ name: 'security-secrets', title: 'Secret hygiene', summary: 'Never commit credentials or secrets; the repository is the single source of truth and is shared.' },
|
|
158
|
+
{ name: 'traceability', title: 'Traceability', summary: 'Maintain the feature -> story -> acceptance -> requirement -> task chain across every change.' },
|
|
159
|
+
];
|
|
160
|
+
function dnaYaml(def) {
|
|
161
|
+
// `stacks.methodologies` / `team.roles` are `MethodologyEntry`/`RoleEntry` OBJECT arrays
|
|
162
|
+
// (`{name, ...}`) per `spec-002-dna-yaml-schema`'s `DnaYaml` schema (`src/dna/schema.ts`) — a bare
|
|
163
|
+
// string list here fails `DnaYaml.safeParse` the moment `dna show`/`dna set`/`paths` load this file
|
|
164
|
+
// (bug-005-init-scaffold-fails-schema-validation). `team.members` is a REQUIRED (if possibly empty)
|
|
165
|
+
// array too; an empty list is schema-valid (the `Team` schema's role cross-check is vacuous over no
|
|
166
|
+
// members) and is the right default for a fresh, person-less scaffold — the user adds real members
|
|
167
|
+
// via `dna set` once the project has a team.
|
|
168
|
+
const methodologies = def.methodologies.map((m) => ` - name: ${m}`).join('\n');
|
|
169
|
+
return `# Project DNA (P2.4) — scaffolded by \`wingfoil init\` (${def.name} template).
|
|
170
|
+
# Structural map of the project: modules, stacks, team + roles, resource paths. Customize freely.
|
|
171
|
+
version: 1
|
|
172
|
+
|
|
173
|
+
project:
|
|
174
|
+
name: "" # your project name
|
|
175
|
+
description: ""
|
|
176
|
+
methodology: ${def.name} # ${def.description}
|
|
177
|
+
|
|
178
|
+
# Modules — the parts of the system (anatomy for navigation). Add your own.
|
|
179
|
+
modules: []
|
|
180
|
+
|
|
181
|
+
# Stacks — technologies + methodologies in use. The methodologies come from the ${def.name} template.
|
|
182
|
+
stacks:
|
|
183
|
+
technologies: []
|
|
184
|
+
methodologies:
|
|
185
|
+
${methodologies}
|
|
186
|
+
|
|
187
|
+
# Team & roles — AI agents execute as developer/reviewer/qa/architect and never hold approval authority.
|
|
188
|
+
team:
|
|
189
|
+
members: []
|
|
190
|
+
roles:
|
|
191
|
+
- name: developer
|
|
192
|
+
- name: reviewer
|
|
193
|
+
- name: qa
|
|
194
|
+
- name: architect
|
|
195
|
+
- name: product-owner
|
|
196
|
+
- name: tech-lead
|
|
197
|
+
- name: approver
|
|
198
|
+
|
|
199
|
+
# Resource paths — query categories used to navigate the project.
|
|
200
|
+
paths:
|
|
201
|
+
sources: []
|
|
202
|
+
tests: []
|
|
203
|
+
docs: []
|
|
204
|
+
config: [.wingfoil]
|
|
205
|
+
governance: []
|
|
206
|
+
`;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The scaffolded `memory.yaml` (P1.13, `spec-001-memory-yaml-schema`) — type registry **plus** the
|
|
210
|
+
* `defaults.states` machine every scaffolded type runs on.
|
|
211
|
+
*
|
|
212
|
+
* That `defaults` block is `bug-030-init-memory-yaml-has-no-state-machine` (task-071): this generator
|
|
213
|
+
* used to emit types only, while its own header comment promised "(per type) its state machine", so a
|
|
214
|
+
* freshly-`init`-ed project had no machine anywhere and `resolveStateMachine` refused every transition
|
|
215
|
+
* verb. The engine now also carries a built-in default (`DEFAULT_STATE_MACHINE`, `src/memory/state-machine.ts`)
|
|
216
|
+
* for hand-written files that declare nothing; the block is written out here anyway, and the header
|
|
217
|
+
* comment corrected to describe it, so the machine governing a new project is **visible and editable
|
|
218
|
+
* in the user's own file** rather than an invisible engine constant. It is `spec-001`'s worked
|
|
219
|
+
* `defaults` example verbatim, so this stays inside the top-level shape that spec already specifies
|
|
220
|
+
* (`defaults:` is optional there) — no per-type machine is invented for a starter project, which would
|
|
221
|
+
* be a product decision beyond this scaffold.
|
|
222
|
+
*/
|
|
223
|
+
function memoryYaml() {
|
|
224
|
+
const types = MEMORY_TYPES.map((type) => ` ${type}:
|
|
225
|
+
path: docs/memory/${type}/{id}.md
|
|
226
|
+
id_pattern: "${MEMORY_ID_PATTERNS[type]}"
|
|
227
|
+
template:
|
|
228
|
+
file: memory/templates/${type}.md
|
|
229
|
+
frontmatter:
|
|
230
|
+
required: [id, type, title, status]`).join('\n');
|
|
231
|
+
return `# Memory element schema (P1.13) — scaffolded by \`wingfoil init\`.
|
|
232
|
+
# One entry per element type: its path pattern, its id pattern and its scaffold template. Every type
|
|
233
|
+
# below shares the \`defaults\` state machine; give a type its own \`states:\` block to override it for
|
|
234
|
+
# that type only (REQ-STATE-08).
|
|
235
|
+
version: 1
|
|
236
|
+
|
|
237
|
+
# Default state machine — applies to every type that declares no \`states:\` block of its own.
|
|
238
|
+
# \`sequence\` is the ordered forward chain (\`submit\` walks it); a \`gates\` state's forward edge needs
|
|
239
|
+
# \`approve\` instead, and its \`reject\` target is where a rejection lands. \`deprecated\` is implicit:
|
|
240
|
+
# \`memory deprecate\` reaches it from any state, so it is never listed here.
|
|
241
|
+
defaults:
|
|
242
|
+
states:
|
|
243
|
+
sequence: [ draft, pending, approved ]
|
|
244
|
+
gates:
|
|
245
|
+
pending: { reject: draft }
|
|
246
|
+
|
|
247
|
+
types:
|
|
248
|
+
${types}
|
|
249
|
+
`;
|
|
250
|
+
}
|
|
251
|
+
function rolesYaml() {
|
|
252
|
+
return `# Directive role assignments (P3.2/P3.7) — scaffolded by \`wingfoil init\`.
|
|
253
|
+
# Binds directives to roles by directive ID, independent of the built-in/custom subfolder holding the file.
|
|
254
|
+
version: 1
|
|
255
|
+
|
|
256
|
+
assignments:
|
|
257
|
+
developer:
|
|
258
|
+
- code-quality
|
|
259
|
+
- testing
|
|
260
|
+
- determinism
|
|
261
|
+
reviewer:
|
|
262
|
+
- code-review
|
|
263
|
+
- traceability
|
|
264
|
+
qa:
|
|
265
|
+
- testing
|
|
266
|
+
architect:
|
|
267
|
+
- architecture
|
|
268
|
+
- determinism
|
|
269
|
+
- traceability
|
|
270
|
+
product-owner:
|
|
271
|
+
- traceability
|
|
272
|
+
tech-lead:
|
|
273
|
+
- architecture
|
|
274
|
+
- code-review
|
|
275
|
+
|
|
276
|
+
# Global directives apply to every role.
|
|
277
|
+
global:
|
|
278
|
+
- doc-versioning
|
|
279
|
+
- documentation
|
|
280
|
+
- security-secrets
|
|
281
|
+
`;
|
|
282
|
+
}
|
|
283
|
+
/** Ordered list of custom workflow filenames the manifest composes (main workflows + delivery sub). */
|
|
284
|
+
function customWorkflowFiles(def) {
|
|
285
|
+
return [
|
|
286
|
+
'sw-life-cycle.yaml',
|
|
287
|
+
'bug-ingest.yaml',
|
|
288
|
+
'decision-log-ingest.yaml',
|
|
289
|
+
'adr-ingest.yaml',
|
|
290
|
+
`${def.slug}-delivery.yaml`,
|
|
291
|
+
];
|
|
292
|
+
}
|
|
293
|
+
function workflowsYaml(def) {
|
|
294
|
+
const includes = customWorkflowFiles(def)
|
|
295
|
+
.map((f) => ` - workflows/custom/${f}`)
|
|
296
|
+
.join('\n');
|
|
297
|
+
return `# Project Workflow main configuration (P4.1) — scaffolded by \`wingfoil init\`.
|
|
298
|
+
# This MAIN config file does not inline workflows; it include()s the custom (and, once populated,
|
|
299
|
+
# built-in) workflow files. Startable mains + the ${def.name} delivery sub-workflow are composed below.
|
|
300
|
+
version: 1
|
|
301
|
+
|
|
302
|
+
include:
|
|
303
|
+
${includes}
|
|
304
|
+
`;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* One scaffolded Directives-pillar document: YAML frontmatter + the rule text body.
|
|
308
|
+
*
|
|
309
|
+
* The frontmatter carries every field `spec-013-directive-frontmatter-schema` marks required — `id`,
|
|
310
|
+
* `name`, `type: directive`, `kind`, `title` — because that spec's realization,
|
|
311
|
+
* `DirectiveFrontmatter` (`src/directives/schema.ts`), is what `loadDirectives` (`src/core/loaders.ts`)
|
|
312
|
+
* validates every directive file against: a scaffold missing any of them makes `wingfoil directives
|
|
313
|
+
* list` fail `E_VALIDATION` on a freshly-`init`'d project (bug-006-init-directive-scaffold-schema-invalid,
|
|
314
|
+
* the Directives sibling of the `dna.yaml`/`memory.yaml` defect bug-005 fixed).
|
|
315
|
+
*
|
|
316
|
+
* `id` is the filename stem, per spec-013 ("Stable directive identifier … matches the filename stem").
|
|
317
|
+
* That is not cosmetic: it is the key `resolveRoleDirectives` (`src/core/context.ts`, spec-012 §5)
|
|
318
|
+
* binds roles on, and {@link rolesYaml} lists exactly those stems in its `assignments`/`global` blocks
|
|
319
|
+
* — so any other value would leave every scaffolded role binding dangling. Keep the two in step.
|
|
320
|
+
*
|
|
321
|
+
* `kind: custom` is correct for `directives/custom/`, the only place this generator's output is written;
|
|
322
|
+
* the P3.8 built-ins carry `kind: built-in` and have their own renderer (`builtinDirectiveMd`,
|
|
323
|
+
* `./builtin-directives`).
|
|
324
|
+
*/
|
|
325
|
+
function directiveMd(d) {
|
|
326
|
+
return `---
|
|
327
|
+
id: ${d.name}
|
|
328
|
+
name: ${d.name}
|
|
329
|
+
type: directive
|
|
330
|
+
kind: custom
|
|
331
|
+
title: "${d.title}"
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
# ${d.title}
|
|
335
|
+
|
|
336
|
+
${d.summary}
|
|
337
|
+
|
|
338
|
+
<!-- Tailor this rule to your project's needs. Directives are auto-loaded per role (roles.yaml). -->
|
|
339
|
+
`;
|
|
340
|
+
}
|
|
341
|
+
function memoryTemplateMd(type) {
|
|
342
|
+
return `---
|
|
343
|
+
id: ""
|
|
344
|
+
type: ${type}
|
|
345
|
+
title: ""
|
|
346
|
+
status: draft
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
<!-- ${type} body. \`wingfoil memory add\` copies this scaffold verbatim; \`memory submit\` replaces
|
|
350
|
+
these placeholder comments with real content and fills the required frontmatter fields. -->
|
|
351
|
+
`;
|
|
352
|
+
}
|
|
353
|
+
function mainWorkflowYaml(name, description, phasesYaml) {
|
|
354
|
+
return `# ${description}
|
|
355
|
+
name: ${name}
|
|
356
|
+
kind: main
|
|
357
|
+
description: "${description}"
|
|
358
|
+
${phasesYaml}`;
|
|
359
|
+
}
|
|
360
|
+
function deliveryWorkflowYaml(def) {
|
|
361
|
+
return `# ${def.name} delivery loop (sub-workflow) — scaffolded by \`wingfoil init\`.
|
|
362
|
+
# ${def.cadence}
|
|
363
|
+
name: ${def.slug}-delivery
|
|
364
|
+
kind: sub
|
|
365
|
+
description: "${def.name} delivery loop"
|
|
366
|
+
phases:
|
|
367
|
+
- name: plan
|
|
368
|
+
description: "Select the next slice of work to deliver."
|
|
369
|
+
- name: build
|
|
370
|
+
description: "Implement the work test-first (TDD)."
|
|
371
|
+
- name: review
|
|
372
|
+
description: "Review against the directives; run unit + acceptance tests."
|
|
373
|
+
- name: deliver
|
|
374
|
+
description: "Integrate the completed work."
|
|
375
|
+
`;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* The COMPLETE spec-011 `.wingfoil/` layout for `def`, as a `ScaffoldFile[]` sorted by path
|
|
379
|
+
* (deterministic — REQ-SYS-07). Consumed by `initStorage(root, files, message)`; every path is under
|
|
380
|
+
* `.wingfoil/` so init never writes outside the WingFoil root.
|
|
381
|
+
*/
|
|
382
|
+
function templateScaffold(def) {
|
|
383
|
+
const files = [
|
|
384
|
+
// Top-level pillar config (spec-011 "Top-level config files").
|
|
385
|
+
{ path: wf('dna.yaml'), content: dnaYaml(def) },
|
|
386
|
+
{ path: wf('memory.yaml'), content: memoryYaml() },
|
|
387
|
+
{ path: wf('roles.yaml'), content: rolesYaml() },
|
|
388
|
+
{ path: wf('workflows.yaml'), content: workflowsYaml(def) },
|
|
389
|
+
// Directives built-in/custom split (spec-011): the six P3.8 built-ins (task-057) + custom starters.
|
|
390
|
+
...builtin_directives_1.BUILTIN_DIRECTIVE_TEMPLATES.map((t) => ({ path: `${exports.BUILTIN_DIRECTIVES_DIR}/${t.id}.md`, content: (0, builtin_directives_1.builtinDirectiveMd)(t) })),
|
|
391
|
+
...DIRECTIVES.map((d) => ({ path: wf(`directives/custom/${d.name}.md`), content: directiveMd(d) })),
|
|
392
|
+
// Memory templates — one scaffold per element type (spec-011).
|
|
393
|
+
...MEMORY_TYPES.map((type) => ({ path: wf(`memory/templates/${type}.md`), content: memoryTemplateMd(type) })),
|
|
394
|
+
// Workflows built-in/custom split (spec-011).
|
|
395
|
+
{ path: `${exports.BUILTIN_WORKFLOWS_DIR}/.gitkeep`, content: '' },
|
|
396
|
+
{
|
|
397
|
+
path: wf('workflows/custom/sw-life-cycle.yaml'),
|
|
398
|
+
content: mainWorkflowYaml('sw-life-cycle', 'The end-to-end software life cycle', `phases:
|
|
399
|
+
- name: inception
|
|
400
|
+
- name: specification
|
|
401
|
+
- name: delivery
|
|
402
|
+
include: workflows/custom/${def.slug}-delivery.yaml
|
|
403
|
+
- name: sunset
|
|
404
|
+
`),
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
path: wf('workflows/custom/bug-ingest.yaml'),
|
|
408
|
+
content: mainWorkflowYaml('bug-ingest', 'Capture a bug on demand', 'phases:\n - name: capture\n'),
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
path: wf('workflows/custom/decision-log-ingest.yaml'),
|
|
412
|
+
content: mainWorkflowYaml('decision-log-ingest', 'Capture a decision-log on demand', 'phases:\n - name: capture\n'),
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
path: wf('workflows/custom/adr-ingest.yaml'),
|
|
416
|
+
content: mainWorkflowYaml('adr-ingest', 'Capture an ADR on demand', 'phases:\n - name: capture\n'),
|
|
417
|
+
},
|
|
418
|
+
{ path: wf(`workflows/custom/${def.slug}-delivery.yaml`), content: deliveryWorkflowYaml(def) },
|
|
419
|
+
];
|
|
420
|
+
return files.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/storage/templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod-issue → {@link ValidationError} mapper (spec-009-validation-strategy §3).
|
|
3
|
+
*
|
|
4
|
+
* Every Pass-1 Zod issue is mapped to an `E_*` code via the caller-supplied `ErrorMap` (keyed by
|
|
5
|
+
* dot-path). Any issue whose path has no entry falls back to `E_VALIDATION`, so no failure is ever
|
|
6
|
+
* silently dropped for lack of a specific code.
|
|
7
|
+
*/
|
|
8
|
+
import type { ZodError } from 'zod';
|
|
9
|
+
import { ValidationError } from './errors';
|
|
10
|
+
/**
|
|
11
|
+
* Map a Zod parse failure to a {@link ValidationError} (spec-009 §3): each issue's dot-path is looked
|
|
12
|
+
* up in `errorMap` for its `E_*` code, falling back to `E_VALIDATION` so no issue is dropped. `filePath`
|
|
13
|
+
* is attached to every issue for operator-facing messages.
|
|
14
|
+
*/
|
|
15
|
+
export declare function toValidationError(zodError: ZodError, filePath: string, errorMap?: Record<string, string>): ValidationError;
|
|
16
|
+
//# sourceMappingURL=error-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-mapper.d.ts","sourceRoot":"","sources":["../../src/validation/error-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAEpC,OAAO,EAAgB,eAAe,EAAmB,MAAM,UAAU,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACpC,eAAe,CAOjB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toValidationError = toValidationError;
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
/**
|
|
6
|
+
* Map a Zod parse failure to a {@link ValidationError} (spec-009 §3): each issue's dot-path is looked
|
|
7
|
+
* up in `errorMap` for its `E_*` code, falling back to `E_VALIDATION` so no issue is dropped. `filePath`
|
|
8
|
+
* is attached to every issue for operator-facing messages.
|
|
9
|
+
*/
|
|
10
|
+
function toValidationError(zodError, filePath, errorMap = {}) {
|
|
11
|
+
const issues = zodError.issues.map((issue) => {
|
|
12
|
+
const path = issue.path.join('.');
|
|
13
|
+
const code = errorMap[path] ?? errors_1.E_VALIDATION;
|
|
14
|
+
return { code, path, file: filePath, message: issue.message };
|
|
15
|
+
});
|
|
16
|
+
return new errors_1.ValidationError(issues);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=error-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-mapper.js","sourceRoot":"","sources":["../../src/validation/error-mapper.ts"],"names":[],"mappings":";;AAgBA,8CAWC;AAlBD,qCAA0E;AAE1E;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,QAAkB,EAClB,QAAgB,EAChB,WAAmC,EAAE;IAErC,MAAM,MAAM,GAAsB,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,qBAAY,CAAC;QAC5C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,wBAAe,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared validation error types and exit codes (spec-009-validation-strategy §3).
|
|
3
|
+
*
|
|
4
|
+
* A single {@link ValidationError} carries the full list of mapped issues from one validation run
|
|
5
|
+
* so no failure is ever silently dropped. Its {@link ValidationError.exitCode} follows spec-009 §3,
|
|
6
|
+
* which keys the code on the **nature** of the failure, not on the pass that detects it: parse and
|
|
7
|
+
* system-integrity failures exit `2`; every other validation failure — field-level, mapped, generic,
|
|
8
|
+
* and business-rule failures detected in Pass 2 (e.g. `E_INVALID_TRANSITION`, `E_INVALID_STATE`) —
|
|
9
|
+
* exits `1`, matching spec-008's exit-code table.
|
|
10
|
+
*/
|
|
11
|
+
/** A single mapped validation failure — one Zod issue or one semantic-check failure. */
|
|
12
|
+
export interface ValidationIssue {
|
|
13
|
+
/** `E_*` code from the shared convention (spec-009 §3), e.g. `E_INVALID_ID`, `E_VALIDATION`. */
|
|
14
|
+
readonly code: string;
|
|
15
|
+
/** Dot-joined path to the offending field (empty string for whole-document failures). */
|
|
16
|
+
readonly path: string;
|
|
17
|
+
/** Path of the file the failure was found in. */
|
|
18
|
+
readonly file: string;
|
|
19
|
+
/** Human-readable description (typically the raw Zod message). */
|
|
20
|
+
readonly message: string;
|
|
21
|
+
/**
|
|
22
|
+
* Optional longer explanation kept apart from {@link message} — for a failure whose `message` is a
|
|
23
|
+
* pinned contract string, the diagnostic that says *why* travels here instead of replacing it
|
|
24
|
+
* (`dl-032-illegal-transition-message-contract`, option (c)). Absent for most issues.
|
|
25
|
+
*/
|
|
26
|
+
readonly detail?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Process exit code for a validation failure whose worst issue is a mapped `E_INVALID_*` /
|
|
30
|
+
* `E_INVALID_*_SCHEMA` or the generic `E_VALIDATION` fallback (spec-009 §3, spec-008 exit table).
|
|
31
|
+
*/
|
|
32
|
+
export declare const EXIT_VALIDATION = 1;
|
|
33
|
+
/**
|
|
34
|
+
* Process exit code for a parse or system-integrity failure — `E_YAML_PARSE_ERROR`, and the
|
|
35
|
+
* cross-file integrity checks that presuppose a parseable tree: the input could not be understood,
|
|
36
|
+
* or the installation is inconsistent (spec-009 §3, spec-008 exit table). **Not** every Pass-2
|
|
37
|
+
* failure: spec-009 §3 keys exit codes on the nature of the failure, not the pass, so a business-rule
|
|
38
|
+
* failure found in Pass 2 (an illegal transition, an invalid state) exits {@link EXIT_VALIDATION}.
|
|
39
|
+
*/
|
|
40
|
+
export declare const EXIT_INTEGRITY = 2;
|
|
41
|
+
/** `E_*` code emitted when a file cannot be parsed as YAML at all, before Zod runs (spec-009 §3). */
|
|
42
|
+
export declare const E_YAML_PARSE_ERROR = "E_YAML_PARSE_ERROR";
|
|
43
|
+
/** Generic fallback code for any issue with no explicit `ErrorMap` entry (spec-009 §3). */
|
|
44
|
+
export declare const E_VALIDATION = "E_VALIDATION";
|
|
45
|
+
/**
|
|
46
|
+
* The single error type thrown by every validation path. Extends {@link Error} so it integrates
|
|
47
|
+
* with normal throw/catch, but always carries the structured {@link issues} list and the process
|
|
48
|
+
* {@link exitCode} the CLI/MCP surface should exit with.
|
|
49
|
+
*/
|
|
50
|
+
export declare class ValidationError extends Error {
|
|
51
|
+
readonly issues: readonly ValidationIssue[];
|
|
52
|
+
readonly exitCode: number;
|
|
53
|
+
constructor(issues: ValidationIssue[], exitCode?: number);
|
|
54
|
+
/**
|
|
55
|
+
* Build a pre-parse YAML failure. Exits `2` (integrity) because it means the file could not even
|
|
56
|
+
* be turned into a data structure — Zod never ran.
|
|
57
|
+
*/
|
|
58
|
+
static yamlParse(filePath: string, message: string): ValidationError;
|
|
59
|
+
/**
|
|
60
|
+
* Build a **system-integrity** failure detected after parsing. Exits `2` ({@link EXIT_INTEGRITY}).
|
|
61
|
+
* Use it only when the input could not be understood or the installation is inconsistent (e.g. a
|
|
62
|
+
* loader's cross-file check, a malformed `id_pattern`). It is **not** the constructor for every
|
|
63
|
+
* Pass-2 check: spec-009 §3 keys exit codes on the nature of the failure, not the detecting pass,
|
|
64
|
+
* so a business-rule failure found in Pass 2 (`E_INVALID_TRANSITION`, `E_INVALID_STATE`) is built
|
|
65
|
+
* with the plain constructor and exits `1`.
|
|
66
|
+
*/
|
|
67
|
+
static semantic(issues: ValidationIssue[]): ValidationError;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/validation/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,gGAAgG;IAChG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,qGAAqG;AACrG,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD,2FAA2F;AAC3F,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,MAAM,EAAE,eAAe,EAAE,EAAE,QAAQ,GAAE,MAAwB;IAazE;;;OAGG;IACH,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,eAAe;IAOpE;;;;;;;OAOG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,eAAe;CAG5D"}
|