@rijalpermana/spec-forge 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cli.js +16 -1
- package/package.json +1 -1
- package/templates/mockup.html +45 -0
package/README.md
CHANGED
|
@@ -70,6 +70,7 @@ forge smelt btn-fraud-check # interactive Q&A -> brief.md + prd.md stub
|
|
|
70
70
|
|
|
71
71
|
forge schema btn-fraud-check # schema.dbml (requires prd.md)
|
|
72
72
|
forge contract btn-fraud-check # api-contract.md (requires prd.md)
|
|
73
|
+
forge mockup btn-fraud-check # mockup.html (requires prd.md)
|
|
73
74
|
forge tasks btn-fraud-check # tasks.md (requires prd.md)
|
|
74
75
|
forge testcase btn-fraud-check # testcases.md (requires prd.md)
|
|
75
76
|
forge verify btn-fraud-check # reports missing files / unresolved [TODO]s
|
|
@@ -132,6 +133,7 @@ the writing.
|
|
|
132
133
|
| `forge smelt <feature>` | — | `brief.md`, `prd.md` (stub), `INDEX.md` entry (`draft`) | Yes — refuses if `brief.md` exists |
|
|
133
134
|
| `forge schema <feature>` | `prd.md` | `schema.dbml` (stub) | Yes |
|
|
134
135
|
| `forge contract <feature>` | `prd.md` | `api-contract.md` (stub) | Yes |
|
|
136
|
+
| `forge mockup <feature>` | `prd.md` | `mockup.html` (stub) | Yes |
|
|
135
137
|
| `forge tasks <feature>` | `prd.md` | `tasks.md` (stub) | Yes |
|
|
136
138
|
| `forge testcase <feature>` | `prd.md` | `testcases.md` (stub) | Yes |
|
|
137
139
|
| `forge verify <feature>` | — | Console report, `INDEX.md` status → `active` if complete | N/A (read-only on spec files) |
|
|
@@ -149,6 +151,7 @@ your-project/
|
|
|
149
151
|
│ ├── prd.md # goal, actors, user stories, business rules, out-of-scope
|
|
150
152
|
│ ├── schema.dbml # entities derived from prd.md
|
|
151
153
|
│ ├── api-contract.md # Title / endpoint / Request / Response / Note format
|
|
154
|
+
│ ├── mockup.html # throwaway wireframe (plain HTML/CSS, no framework)
|
|
152
155
|
│ ├── tasks.md # WBS, sequenced data -> logic -> UI
|
|
153
156
|
│ └── testcases.md # No/Scenario/Case/Type/Expected/Actual/Status/Remark table
|
|
154
157
|
├── .claude/commands/forge/ # if target = claude
|
package/dist/cli.js
CHANGED
|
@@ -6775,6 +6775,9 @@ var require_prompts3 = __commonJS((exports, module) => {
|
|
|
6775
6775
|
module.exports = isNodeLT("8.6.0") ? require_dist() : require_lib();
|
|
6776
6776
|
});
|
|
6777
6777
|
|
|
6778
|
+
// src/cli.ts
|
|
6779
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
6780
|
+
|
|
6778
6781
|
// node_modules/commander/esm.mjs
|
|
6779
6782
|
var import__ = __toESM(require_commander(), 1);
|
|
6780
6783
|
var {
|
|
@@ -6869,6 +6872,14 @@ var COMMAND_SPECS = [
|
|
|
6869
6872
|
` + `Response: [full JSON example]
|
|
6870
6873
|
` + "Note: [only if needed]"
|
|
6871
6874
|
},
|
|
6875
|
+
{
|
|
6876
|
+
name: "mockup",
|
|
6877
|
+
argumentHint: "[feature-name]",
|
|
6878
|
+
description: "Scaffold mockup.html, then draft it from prd.md",
|
|
6879
|
+
requiresPrd: true,
|
|
6880
|
+
readOnly: false,
|
|
6881
|
+
instructions: GROUND_IN_RULES + "Read {{prd}} and fill {{mockup}} — a throwaway wireframe (plain HTML/CSS, no " + "framework, no build step) covering the screens/states implied by the PRD's user " + "stories: primary view, secondary views or modals, and empty/loading/error states " + "where the PRD calls for them. This is for reviewing flow and layout, not visual " + "design or production markup — don't invent screens, fields, or copy that aren't " + "traceable to the PRD."
|
|
6882
|
+
},
|
|
6872
6883
|
{
|
|
6873
6884
|
name: "tasks",
|
|
6874
6885
|
argumentHint: "[feature-name]",
|
|
@@ -6913,6 +6924,7 @@ var SPEC_FILES = {
|
|
|
6913
6924
|
prd: "prd.md",
|
|
6914
6925
|
schema: "schema.dbml",
|
|
6915
6926
|
contract: "api-contract.md",
|
|
6927
|
+
mockup: "mockup.html",
|
|
6916
6928
|
tasks: "tasks.md",
|
|
6917
6929
|
testcases: "testcases.md"
|
|
6918
6930
|
};
|
|
@@ -7587,8 +7599,10 @@ Every forge drafting command (smelt, schema, contract, tasks, testcase) ` + `wil
|
|
|
7587
7599
|
}
|
|
7588
7600
|
|
|
7589
7601
|
// src/cli.ts
|
|
7602
|
+
var require2 = createRequire2(import.meta.url);
|
|
7603
|
+
var { version } = require2("../package.json");
|
|
7590
7604
|
var program2 = new Command;
|
|
7591
|
-
program2.name("forge").description("Spec-driven development CLI — scaffolds specs, schemas, API contracts, tasks, and test cases.").version(
|
|
7605
|
+
program2.name("forge").description("Spec-driven development CLI — scaffolds specs, schemas, API contracts, tasks, and test cases.").version(version);
|
|
7592
7606
|
program2.command("init").description("Scaffold specs/ folder and an AI-tool bridge in the current project").option("-t, --target <target>", "bridge target: claude, cursor, windsurf, or generic", "claude").action((options) => init({ target: options.target }));
|
|
7593
7607
|
program2.command("bridge <target>").description("(Re)generate AI-tool bridge commands: claude, cursor, windsurf, or generic").action((target) => bridge(target));
|
|
7594
7608
|
program2.command("scan").description("Inventory the existing project structure into specs/CODEBASE.md").option("-d, --depth <n>", "directory-tree depth to include in the report", "2").action((options) => scan({ depth: Number(options.depth) }));
|
|
@@ -7596,6 +7610,7 @@ program2.command("rules").description("Scaffold specs/RULES.md — project conve
|
|
|
7596
7610
|
program2.command("smelt <feature>").description("Extract raw requirements into a grounding brief and stub the PRD").option("-f, --from <file>", "extract from an existing BRD/requirements document instead of interactive Q&A").action((feature, options) => smelt(feature, { from: options.from }));
|
|
7597
7611
|
program2.command("schema <feature>").description("Scaffold schema.dbml (requires prd.md)").action(makeScaffoldCommand({ file: SPEC_FILES.schema, label: "schema" }));
|
|
7598
7612
|
program2.command("contract <feature>").description("Scaffold api-contract.md (requires prd.md)").action(makeScaffoldCommand({ file: SPEC_FILES.contract, label: "contract" }));
|
|
7613
|
+
program2.command("mockup <feature>").description("Scaffold mockup.html (requires prd.md)").action(makeScaffoldCommand({ file: SPEC_FILES.mockup, label: "mockup" }));
|
|
7599
7614
|
program2.command("tasks <feature>").description("Scaffold tasks.md WBS (requires prd.md)").action(makeScaffoldCommand({ file: SPEC_FILES.tasks, label: "tasks" }));
|
|
7600
7615
|
program2.command("testcase <feature>").description("Scaffold testcases.md (requires prd.md)").action(makeScaffoldCommand({ file: SPEC_FILES.testcases, label: "testcase" }));
|
|
7601
7616
|
program2.command("verify <feature>").description("Check that all spec files exist and have no unresolved [TODO] markers").action(verify);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rijalpermana/spec-forge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Spec-driven development CLI: scaffolds specs, schemas, API contracts, task lists, and test cases; bridges into Claude Code as slash commands.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!-- Mockup — {{feature}}
|
|
2
|
+
Generated by `forge mockup {{feature}}`. Derive screens/sections from prd.md's
|
|
3
|
+
user stories — do not invent flows that aren't grounded in the PRD. This is a
|
|
4
|
+
throwaway wireframe for review, not production markup: plain HTML/CSS, no
|
|
5
|
+
framework, no build step. Open directly in a browser. -->
|
|
6
|
+
<!doctype html>
|
|
7
|
+
<html lang="en">
|
|
8
|
+
<head>
|
|
9
|
+
<meta charset="utf-8" />
|
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
11
|
+
<title>{{feature}} — mockup</title>
|
|
12
|
+
<style>
|
|
13
|
+
:root { color-scheme: light dark; }
|
|
14
|
+
body { font-family: system-ui, sans-serif; max-width: 960px; margin: 2rem auto; padding: 0 1rem; line-height: 1.5; }
|
|
15
|
+
header { border-bottom: 1px solid #8888; margin-bottom: 1.5rem; padding-bottom: 1rem; }
|
|
16
|
+
h1 { font-size: 1.25rem; margin: 0; }
|
|
17
|
+
.note { color: #888; font-size: 0.85rem; }
|
|
18
|
+
section { margin-bottom: 2rem; padding: 1rem; border: 1px dashed #8886; border-radius: 8px; }
|
|
19
|
+
section h2 { font-size: 1rem; margin-top: 0; }
|
|
20
|
+
.todo { color: #b8860b; font-weight: 600; }
|
|
21
|
+
button, input, select { font: inherit; padding: 0.4rem 0.6rem; }
|
|
22
|
+
</style>
|
|
23
|
+
</head>
|
|
24
|
+
<body>
|
|
25
|
+
<header>
|
|
26
|
+
<h1>{{feature}}</h1>
|
|
27
|
+
<p class="note">Wireframe only — grounded in prd.md. Replace each placeholder section below.</p>
|
|
28
|
+
</header>
|
|
29
|
+
|
|
30
|
+
<section>
|
|
31
|
+
<h2>[TODO] Primary screen / view</h2>
|
|
32
|
+
<p class="todo">[TODO] Lay out the main UI for this feature's core user story — key fields, actions, and states (empty, loading, error).</p>
|
|
33
|
+
</section>
|
|
34
|
+
|
|
35
|
+
<section>
|
|
36
|
+
<h2>[TODO] Secondary screen / modal (if any)</h2>
|
|
37
|
+
<p class="todo">[TODO] Add a screen per additional user story from prd.md, or delete this section if there's only one.</p>
|
|
38
|
+
</section>
|
|
39
|
+
|
|
40
|
+
<section>
|
|
41
|
+
<h2>[TODO] Notes</h2>
|
|
42
|
+
<p class="todo">[TODO] Call out anything ambiguous in prd.md that this mockup had to assume.</p>
|
|
43
|
+
</section>
|
|
44
|
+
</body>
|
|
45
|
+
</html>
|