@rsaglobaltech/specgate 0.22.0 → 0.22.2
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/CHANGELOG.md +135 -51
- package/README.md +81 -96
- package/dist/packages/core/src/domain/CapabilitySpecMerge.js +83 -0
- package/dist/packages/core/src/domain/CapabilitySpecMerge.js.map +1 -0
- package/dist/packages/core/test/unit/capability-spec-merge.test.js +104 -0
- package/dist/packages/core/test/unit/capability-spec-merge.test.js.map +1 -0
- package/dist/packages/mcp-spec-driven/src/native-tools.js +1 -1
- package/dist/packages/mcp-spec-driven/src/native-tools.js.map +1 -1
- package/dist/scripts/agents/commands.js +7 -7
- package/dist/scripts/agents/commands.js.map +1 -1
- package/dist/scripts/agents/detect.js +1 -0
- package/dist/scripts/agents/detect.js.map +1 -1
- package/dist/scripts/agents/init.js +13 -0
- package/dist/scripts/agents/init.js.map +1 -1
- package/dist/scripts/alm/cli.js +3 -2
- package/dist/scripts/alm/cli.js.map +1 -1
- package/dist/scripts/cli/commands/change/ChangeCommand.js +22 -1
- package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
- package/dist/scripts/cli/commands/change/TicketCommand.js +64 -6
- package/dist/scripts/cli/commands/change/TicketCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/CheckCommand.js +15 -5
- package/dist/scripts/cli/commands/quality/CheckCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/DoctorCommand.js +22 -8
- package/dist/scripts/cli/commands/quality/DoctorCommand.js.map +1 -1
- package/dist/scripts/docs/journey-storyboard.js +34 -17
- package/dist/scripts/docs/journey-storyboard.js.map +1 -1
- package/dist/scripts/docs/nav.js +155 -143
- package/dist/scripts/docs/nav.js.map +1 -1
- package/dist/scripts/docs/record-journey.js +46 -19
- package/dist/scripts/docs/record-journey.js.map +1 -1
- package/dist/scripts/docs/terminal-storyboard.js +15 -11
- package/dist/scripts/docs/terminal-storyboard.js.map +1 -1
- package/dist/scripts/draft/drafting-guide.js +4 -0
- package/dist/scripts/draft/drafting-guide.js.map +1 -1
- package/dist/scripts/draft/ticket-guide.js +4 -0
- package/dist/scripts/draft/ticket-guide.js.map +1 -1
- package/dist/scripts/harness/init.js +85 -25
- package/dist/scripts/harness/init.js.map +1 -1
- package/dist/scripts/harness/prompt.js +13 -1
- package/dist/scripts/harness/prompt.js.map +1 -1
- package/dist/scripts/lib/base-ids.js +7 -0
- package/dist/scripts/lib/base-ids.js.map +1 -1
- package/dist/scripts/lib/change-base.js +230 -0
- package/dist/scripts/lib/change-base.js.map +1 -0
- package/dist/scripts/lib/change-overlap.js +234 -0
- package/dist/scripts/lib/change-overlap.js.map +1 -0
- package/dist/scripts/lib/surface.js +8 -0
- package/dist/scripts/lib/surface.js.map +1 -1
- package/dist/scripts/lib/ticket-keys.js +48 -3
- package/dist/scripts/lib/ticket-keys.js.map +1 -1
- package/dist/scripts/merge-capability-spec.js +87 -0
- package/dist/scripts/merge-capability-spec.js.map +1 -0
- package/dist/scripts/vcs/github-pr.js +1 -1
- package/dist/scripts/vcs/github-pr.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,126 +12,111 @@
|
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
Specgate keeps what your product must do in the repository, as numbered
|
|
16
|
+
requirements with Gherkin scenarios, next to the code and the tests that prove
|
|
17
|
+
them. A test that mentions a requirement's id (`REQ-007`) is the link, and the
|
|
18
|
+
traceability matrix is generated from those mentions. The gate, `specgate check`,
|
|
19
|
+
fails a pull request when a delivered requirement has no scenario or no test
|
|
20
|
+
that names it, or when your test suite fails.
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
## ⚡ Install
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
You need **Node.js 22 or later**.
|
|
22
25
|
|
|
23
26
|
```bash
|
|
24
|
-
npm
|
|
25
|
-
|
|
26
|
-
cd your-repo # or an empty directory
|
|
27
|
-
specgate init # adopts the code that is there, touching none of it;
|
|
28
|
-
# scaffolds a new project where there is none
|
|
29
|
-
specgate ci init # the gate as a CI job — GitHub, GitLab, Azure or Jenkins,
|
|
30
|
-
# detected from the repository
|
|
31
|
-
specgate check # the gate, locally
|
|
27
|
+
npm install --save-dev @rsaglobaltech/specgate # in a project with a package.json
|
|
28
|
+
npx specgate --help
|
|
32
29
|
```
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
Without installing it (an empty folder, a Java or Python project), prefix each
|
|
32
|
+
command with `npx @rsaglobaltech/specgate@latest` instead of `npx specgate`.
|
|
33
|
+
With Docker and no Node.js: `docker run --rm -v "$PWD:/workspace" ghcr.io/rsaglobaltech/specgate check`.
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
Then run `init` once:
|
|
38
36
|
|
|
39
|
-
|
|
37
|
+
- **In a repository that has code** (`package.json`, `pom.xml`, `go.mod`, …),
|
|
38
|
+
`specgate init` adopts it in place: it adds `spec.md`, `features/` and
|
|
39
|
+
`docs/specs/`, and changes no source file.
|
|
40
|
+
- **In an empty folder**, `npx @rsaglobaltech/specgate@latest init` scaffolds a
|
|
41
|
+
new specification project. A wizard asks for the project's name, type, stack
|
|
42
|
+
and test toolchain, then creates it in a new sub-folder named after the
|
|
43
|
+
project, for example `./my-spec-driven-app/`. `--yes` takes every default
|
|
44
|
+
without asking. It writes the specification files, not application code.
|
|
45
|
+
|
|
46
|
+
Step by step, with every output shown: [Getting started](docs/getting-started.md).
|
|
47
|
+
|
|
48
|
+
## 🔁 The lifecycle — four verbs
|
|
40
49
|
|
|
41
50
|
```bash
|
|
42
|
-
specgate propose add-pdf-invoices # a change: proposal,
|
|
43
|
-
# write REQ-007 and its scenario in the delta, a test that mentions REQ-007, the code
|
|
44
|
-
specgate apply
|
|
45
|
-
specgate status # what is
|
|
51
|
+
specgate propose add-pdf-invoices # open a change: a proposal, a delta to write, REQ ids reserved
|
|
52
|
+
# write REQ-007 and its scenario in the delta, a test that mentions REQ-007, then the code
|
|
53
|
+
specgate apply REQ-007 # refused until a test names it and the gate passes; then Implemented
|
|
54
|
+
specgate status # what is left, and the next command to run
|
|
46
55
|
specgate archive add-pdf-invoices # once every requirement in it is Implemented
|
|
47
56
|
```
|
|
48
57
|
|
|
49
|
-
`specgate check`
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
`apply` refuses a requirement no test names and writes nothing while the gate
|
|
54
|
-
fails. **Mentioning `REQ-NNN` in a test is the link**; the matrix is generated.
|
|
55
|
-
From a plan: `specgate propose --from-brief`. Old names (`draft`, `done`…) keep
|
|
56
|
-
working; everything else is in `specgate --help --all`.
|
|
58
|
+
`specgate check` runs the same gate before a pull request and in CI;
|
|
59
|
+
`specgate ci init` writes the CI job for GitHub, GitLab, Azure or Jenkins.
|
|
60
|
+
You archive a change on its branch, before the pull request, so the spec and
|
|
61
|
+
the code reach review together.
|
|
57
62
|
|
|
58
|
-
##
|
|
63
|
+
## 📥 Where work comes from
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
Every piece of work enters the same lifecycle. Pick the entry that matches what
|
|
66
|
+
you have:
|
|
61
67
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
| **L4** | Agent-driven delivery, one requirement at a time | `agents init`, `harness run` | ~1 week |
|
|
68
|
+
| You have | Run | Guide |
|
|
69
|
+
| --- | --- | --- |
|
|
70
|
+
| One behaviour to add or change | `specgate propose <change-id>` | [Propose one change](docs/start/existing-2-specify.md) |
|
|
71
|
+
| A client brief, or a plan for a new product | `specgate propose --from-brief` | [From a client brief](docs/from-a-brief.md) |
|
|
72
|
+
| A Jira story with acceptance criteria | `specgate propose --from-ticket <KEY>` | [From a Jira ticket](docs/from-a-ticket.md) |
|
|
68
73
|
|
|
69
74
|
## 🛠️ What it does
|
|
70
75
|
|
|
71
|
-
**A gate that does not lie.** `
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
**
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
**Your agent works the same loop.** `specgate agents init` gives Claude Code, Cursor,
|
|
93
|
-
Copilot, Windsurf, Aider, Gemini, Cline, Codex or Antigravity the loop as slash commands
|
|
94
|
-
(`/specgate:propose`, `/specgate:apply`, …) from one definition. Every daily command speaks
|
|
95
|
-
JSON with stable codes and a `fix` on each. MCP ships in the package: `specgate mcp install --client claude`.
|
|
96
|
-
→ [Agents](docs/agents.md) · [The agent contract](docs/specs/agent-contract.md) · [Automation and MCP](docs/automation.md)
|
|
97
|
-
|
|
98
|
-
**Domain knowledge as a dependency.** A pack is a versioned, schema-validated
|
|
99
|
-
domain model. Install it, pin it, upgrade it deliberately — and review the
|
|
100
|
-
upgrade as intent with `specops diff --as-change`, not as a file diff.
|
|
101
|
-
→ [Domain packs: 7 proven in the pilots, 11 starter examples](docs/domain-packs.md) · [Supply chain](docs/supply-chain.md)
|
|
102
|
-
|
|
103
|
-
**Unattended delivery.** `specgate harness run` drives plan → agent → verify →
|
|
104
|
-
apply for every pending requirement, each in its own git worktree; it merges only
|
|
105
|
-
with `--chain`, only what passed the gate. The agent is any shell command with
|
|
106
|
-
`{prompt_file}`; `specgate studio` shows it at work, at `/live`. `specgate alm sync`
|
|
107
|
-
keeps Jira, Azure Boards or GitHub Issues in step.
|
|
108
|
-
→ [The harness](docs/harness.md) · [Jira, Azure Boards and GitHub Issues](docs/alm.md)
|
|
109
|
-
|
|
110
|
-
**Tested as you install it.** Every release runs an end-to-end suite over every
|
|
111
|
-
command, against the packed tarball, on Linux, macOS and Windows; releases
|
|
112
|
-
since 0.14 come from building real products with it, from brief to running app.
|
|
76
|
+
- **A gate that does not lie.** `check` fails when a delivered requirement has
|
|
77
|
+
no scenario, no test that names it, or points at a missing file. A `Draft`
|
|
78
|
+
owes nothing yet, so the gate is green on day one.
|
|
79
|
+
→ [Validating](docs/validating.md)
|
|
80
|
+
- **Reviews that read intent.** A change is a delta: only what moves. The
|
|
81
|
+
reviewer reads the requirement, its scenario and its test.
|
|
82
|
+
→ [Your team's first pull request](docs/first-pr.md)
|
|
83
|
+
- **Drafts held to their source.** A draft from a brief or a ticket is checked
|
|
84
|
+
against that text: every value it uses must come from the source or be listed
|
|
85
|
+
as an assumption. → [From a client brief](docs/from-a-brief.md)
|
|
86
|
+
- **Your agent works the same loop.** `specgate agents init` installs the loop
|
|
87
|
+
as slash commands for Claude Code, Cursor, Copilot and other agent tools; an
|
|
88
|
+
MCP server ships in the package. → [Agent tools](docs/agents.md)
|
|
89
|
+
- **Unattended delivery.** `specgate harness run` hands each pending requirement
|
|
90
|
+
to your coding agent in its own git worktree and keeps only what passes the
|
|
91
|
+
gate. → [The harness](docs/harness.md)
|
|
92
|
+
- **Domain knowledge as a dependency.** Versioned domain packs install
|
|
93
|
+
requirements a team has already proved. → [Domain packs](docs/domain-packs.md)
|
|
94
|
+
- **Already on OpenSpec?** `specgate verify` checks what OpenSpec calls done
|
|
95
|
+
against your tests. → [Already on OpenSpec](docs/openspec.md)
|
|
113
96
|
|
|
114
97
|
## 🆚 How it compares
|
|
115
98
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
| Draft
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
99
|
+
Specgate does each of the things below. What the closest alternatives cover:
|
|
100
|
+
|
|
101
|
+
| Capability | [OpenSpec](https://github.com/Fission-AI/OpenSpec) | [spec-kit](https://github.com/github/spec-kit) | [Cursor rules](https://docs.cursor.com/context/rules-for-ai) |
|
|
102
|
+
| ----------------------------- | :------------------------------------------------: | :--------------------------------------------: | :----------------------------------------------------------: |
|
|
103
|
+
| Change lifecycle | ✅ | ❌ | ❌ |
|
|
104
|
+
| Traceability matrix + CI gate | ❌ | ⚠️ | ❌ |
|
|
105
|
+
| Draft checked against a brief | ❌ | ⚠️ | ❌ |
|
|
106
|
+
| Work from Jira tickets | ❌ | ❌ | ❌ |
|
|
107
|
+
| Versioned domain packs | ❌ | ⚠️ | ❌ |
|
|
108
|
+
| Vendor-neutral | ✅ | ✅ | ❌ |
|
|
126
109
|
|
|
127
|
-
OpenSpec is the closest tool: if you want the change loop without
|
|
128
|
-
|
|
110
|
+
OpenSpec is the closest tool: if you want the change loop without an enforced
|
|
111
|
+
gate, it fits better. → [Full comparison](docs/comparisons.md)
|
|
129
112
|
|
|
130
113
|
## 📚 Documentation
|
|
131
114
|
|
|
132
|
-
- [Getting started](docs/getting-started.md)
|
|
133
|
-
- [
|
|
134
|
-
- [
|
|
115
|
+
- [Getting started](docs/getting-started.md) — install, pick your path, the four verbs
|
|
116
|
+
- [From a Jira ticket](docs/from-a-ticket.md) · [From a client brief](docs/from-a-brief.md)
|
|
117
|
+
- [Concepts](docs/concepts.md) — the ideas and vocabulary behind every command
|
|
118
|
+
- [Commands](docs/commands.md) — every command and flag
|
|
119
|
+
- [FAQ](docs/faq.md) · [Troubleshooting](docs/troubleshooting.md) · [Docs site](https://rsaglobaltech.github.io/specgate/)
|
|
135
120
|
|
|
136
121
|
## 🧰 Companion tools
|
|
137
122
|
|
|
@@ -140,8 +125,8 @@ OpenSpec is the closest tool: if you want the change loop without packs or an en
|
|
|
140
125
|
|
|
141
126
|
## 🤝 Contributing
|
|
142
127
|
|
|
143
|
-
PRs welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) (
|
|
144
|
-
|
|
128
|
+
PRs welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) · [MAINTAINERS.md](MAINTAINERS.md) ·
|
|
129
|
+
[SECURITY.md](SECURITY.md) for private reports.
|
|
145
130
|
|
|
146
131
|
## 📄 License
|
|
147
132
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Merge a capability spec requirement by requirement (REQ-166).
|
|
4
|
+
*
|
|
5
|
+
* Git merges `docs/specs/capabilities/<x>/spec.md` by lines. Two changes
|
|
6
|
+
* archived on two branches into the same capability — common once work is one
|
|
7
|
+
* change per ticket — meet as a conflict even when they add different
|
|
8
|
+
* requirements, and as an add/add conflict when the capability is new on both.
|
|
9
|
+
* The unit that two branches actually share or not is a requirement: the
|
|
10
|
+
* `### Requirement: REQ-nnn` heading and everything up to the next one.
|
|
11
|
+
*
|
|
12
|
+
* Per requirement, the usual three-way rule: a side that left it as in the
|
|
13
|
+
* base yields to the side that changed it; two equal changes are one; two
|
|
14
|
+
* different changes are a conflict on that requirement alone. Requirements are
|
|
15
|
+
* written in id order. Pure: three texts in, one text out.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.requirementBlocks = requirementBlocks;
|
|
19
|
+
exports.mergeCapabilitySpec = mergeCapabilitySpec;
|
|
20
|
+
const HEADING = /^### Requirement: (REQ-[\w.]+)/m;
|
|
21
|
+
function parse(text) {
|
|
22
|
+
const normal = text.replace(/\r\n/g, "\n");
|
|
23
|
+
const first = normal.search(HEADING);
|
|
24
|
+
if (first === -1)
|
|
25
|
+
return { preamble: normal, blocks: new Map() };
|
|
26
|
+
const blocks = new Map();
|
|
27
|
+
for (const part of normal.slice(first).split(/(?=^### Requirement: )/m)) {
|
|
28
|
+
const id = HEADING.exec(part)?.[1];
|
|
29
|
+
if (id)
|
|
30
|
+
blocks.set(id, part.replace(/\n*$/, "\n"));
|
|
31
|
+
}
|
|
32
|
+
return { preamble: normal.slice(0, first), blocks };
|
|
33
|
+
}
|
|
34
|
+
/** Each `### Requirement:` block of a capability spec, by id (REQ-168 reads them too). */
|
|
35
|
+
function requirementBlocks(text) {
|
|
36
|
+
return parse(text).blocks;
|
|
37
|
+
}
|
|
38
|
+
const numeric = (id) => Number(/(\d+)/.exec(id)?.[1] ?? 0);
|
|
39
|
+
/** Three-way choice for one unit; `null` when both sides changed it differently. */
|
|
40
|
+
function choose(base, ours, theirs) {
|
|
41
|
+
if (ours === theirs)
|
|
42
|
+
return { value: ours };
|
|
43
|
+
if (ours === base)
|
|
44
|
+
return { value: theirs };
|
|
45
|
+
if (theirs === base)
|
|
46
|
+
return { value: ours };
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const markers = (ours, theirs) => `<<<<<<< ours\n${ours ?? ""}=======\n${theirs ?? ""}>>>>>>> theirs\n`;
|
|
50
|
+
function mergeCapabilitySpec(base, ours, theirs) {
|
|
51
|
+
const [b, o, t] = [parse(base), parse(ours), parse(theirs)];
|
|
52
|
+
if (b.blocks.size + o.blocks.size + t.blocks.size === 0) {
|
|
53
|
+
return { content: ours, conflicts: [], unparsable: true };
|
|
54
|
+
}
|
|
55
|
+
const conflicts = [];
|
|
56
|
+
// A capability new on both sides has no base: its heading is whichever side wrote one.
|
|
57
|
+
const pre = choose(b.preamble || undefined, o.preamble || undefined, t.preamble || undefined);
|
|
58
|
+
let preamble;
|
|
59
|
+
if (pre)
|
|
60
|
+
preamble = pre.value ?? "";
|
|
61
|
+
else if (!b.preamble)
|
|
62
|
+
preamble = o.preamble || t.preamble;
|
|
63
|
+
else {
|
|
64
|
+
preamble = markers(o.preamble, t.preamble);
|
|
65
|
+
conflicts.push("preamble");
|
|
66
|
+
}
|
|
67
|
+
const ids = [...new Set([...b.blocks.keys(), ...o.blocks.keys(), ...t.blocks.keys()])].sort((x, y) => numeric(x) - numeric(y) || x.localeCompare(y));
|
|
68
|
+
const parts = [];
|
|
69
|
+
for (const id of ids) {
|
|
70
|
+
const picked = choose(b.blocks.get(id), o.blocks.get(id), t.blocks.get(id));
|
|
71
|
+
if (picked) {
|
|
72
|
+
if (picked.value !== undefined)
|
|
73
|
+
parts.push(picked.value);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
parts.push(markers(o.blocks.get(id), t.blocks.get(id)));
|
|
77
|
+
conflicts.push(id);
|
|
78
|
+
}
|
|
79
|
+
const body = parts.map((p) => p.replace(/\n*$/, "\n")).join("\n");
|
|
80
|
+
const head = preamble.replace(/\n*$/, "\n\n");
|
|
81
|
+
return { content: `${head}${body}`, conflicts };
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=CapabilitySpecMerge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CapabilitySpecMerge.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/CapabilitySpecMerge.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AA8BH,8CAEC;AAmBD,kDAsCC;AA/ED,MAAM,OAAO,GAAG,iCAAiC,CAAC;AAOlD,SAAS,KAAK,CAAC,IAAY;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,KAAK,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC;QACxE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AACtD,CAAC;AAED,0FAA0F;AAC1F,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AAC5B,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAEnE,oFAAoF;AACpF,SAAS,MAAM,CACb,IAAwB,EACxB,IAAwB,EACxB,MAA0B;IAE1B,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC5C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC5C,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC5C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,IAAwB,EAAE,MAA0B,EAAE,EAAE,CACvE,iBAAiB,IAAI,IAAI,EAAE,YAAY,MAAM,IAAI,EAAE,kBAAkB,CAAC;AAExE,SAAgB,mBAAmB,CACjC,IAAY,EACZ,IAAY,EACZ,MAAc;IAEd,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,uFAAuF;IACvF,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;IAC9F,IAAI,QAAgB,CAAC;IACrB,IAAI,GAAG;QAAE,QAAQ,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;SAC/B,IAAI,CAAC,CAAC,CAAC,QAAQ;QAAE,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC;SACrD,CAAC;QACJ,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC3C,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CACzF,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CACxD,CAAC;IACF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5E,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzD,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxD,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The requirement-wise merge of a capability spec (REQ-166).
|
|
4
|
+
*
|
|
5
|
+
* Each case is a way two branches meet in `docs/specs/capabilities/<x>/spec.md`
|
|
6
|
+
* — and a requirement lost without a conflict is the outcome worse than one.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
const node_test_1 = require("node:test");
|
|
43
|
+
const assert = __importStar(require("node:assert/strict"));
|
|
44
|
+
const CapabilitySpecMerge_1 = require("../../src/domain/CapabilitySpecMerge");
|
|
45
|
+
const req = (n, text = "The system SHALL do it.") => [
|
|
46
|
+
`### Requirement: REQ-${n} — Rule ${n}`,
|
|
47
|
+
"",
|
|
48
|
+
text,
|
|
49
|
+
"",
|
|
50
|
+
`#### Scenario: SCN-${n} — Case`,
|
|
51
|
+
"",
|
|
52
|
+
"- GIVEN a",
|
|
53
|
+
"- WHEN b",
|
|
54
|
+
"- THEN c",
|
|
55
|
+
"",
|
|
56
|
+
].join("\n");
|
|
57
|
+
const spec = (...blocks) => ["# Owners", "", "## Requirements", "", ...blocks].join("\n");
|
|
58
|
+
const ids = (content) => [...content.matchAll(/^### Requirement: (REQ-\d+)/gm)].map((m) => m[1]);
|
|
59
|
+
(0, node_test_1.test)("REQ-166 SCN-166a: two sides adding to a capability that did not exist merge cleanly, in id order", () => {
|
|
60
|
+
const result = (0, CapabilitySpecMerge_1.mergeCapabilitySpec)("", spec(req("009")), spec(req("006"), req("007")));
|
|
61
|
+
assert.deepEqual(result.conflicts, []);
|
|
62
|
+
assert.deepEqual(ids(result.content), ["REQ-006", "REQ-007", "REQ-009"]);
|
|
63
|
+
assert.match(result.content, /^# Owners\n\n## Requirements\n\n### Requirement: REQ-006/);
|
|
64
|
+
});
|
|
65
|
+
(0, node_test_1.test)("REQ-166: a change on one side only is taken, the other side untouched", () => {
|
|
66
|
+
const base = spec(req("006"), req("007"));
|
|
67
|
+
const ours = spec(req("006", "The system SHALL ignore case."), req("007"));
|
|
68
|
+
const theirs = spec(req("006"), req("007"), req("008"));
|
|
69
|
+
const result = (0, CapabilitySpecMerge_1.mergeCapabilitySpec)(base, ours, theirs);
|
|
70
|
+
assert.deepEqual(result.conflicts, []);
|
|
71
|
+
assert.match(result.content, /SHALL ignore case/);
|
|
72
|
+
assert.deepEqual(ids(result.content), ["REQ-006", "REQ-007", "REQ-008"]);
|
|
73
|
+
});
|
|
74
|
+
(0, node_test_1.test)("REQ-166: a requirement removed on one side and untouched on the other is removed", () => {
|
|
75
|
+
const base = spec(req("006"), req("007"));
|
|
76
|
+
const result = (0, CapabilitySpecMerge_1.mergeCapabilitySpec)(base, spec(req("006")), base);
|
|
77
|
+
assert.deepEqual(result.conflicts, []);
|
|
78
|
+
assert.deepEqual(ids(result.content), ["REQ-006"]);
|
|
79
|
+
});
|
|
80
|
+
(0, node_test_1.test)("REQ-166: the same rewrite on both sides is no conflict", () => {
|
|
81
|
+
const base = spec(req("009"));
|
|
82
|
+
const both = spec(req("009", "The system SHALL accept + and 8 to 15 digits."));
|
|
83
|
+
const result = (0, CapabilitySpecMerge_1.mergeCapabilitySpec)(base, both, both);
|
|
84
|
+
assert.deepEqual(result.conflicts, []);
|
|
85
|
+
assert.match(result.content, /8 to 15 digits/);
|
|
86
|
+
});
|
|
87
|
+
(0, node_test_1.test)("REQ-166 SCN-166b: two different rewrites conflict on that requirement alone", () => {
|
|
88
|
+
const base = spec(req("006"), req("009"));
|
|
89
|
+
const ours = spec(req("006", "The system SHALL ignore case."), req("009", "International numbers are accepted."));
|
|
90
|
+
const theirs = spec(req("006"), req("009", "An empty telephone is accepted."));
|
|
91
|
+
const result = (0, CapabilitySpecMerge_1.mergeCapabilitySpec)(base, ours, theirs);
|
|
92
|
+
assert.deepEqual(result.conflicts, ["REQ-009"]);
|
|
93
|
+
assert.match(result.content, /SHALL ignore case/, "the other requirement is merged");
|
|
94
|
+
const markers = result.content.match(/^<<<<<<< ours$[\s\S]*?^>>>>>>> theirs$/m);
|
|
95
|
+
assert.ok(markers, result.content);
|
|
96
|
+
assert.match(markers[0], /International numbers/);
|
|
97
|
+
assert.match(markers[0], /An empty telephone/);
|
|
98
|
+
assert.doesNotMatch(markers[0], /REQ-006/);
|
|
99
|
+
});
|
|
100
|
+
(0, node_test_1.test)("REQ-166: a file that is not a capability spec is left to git", () => {
|
|
101
|
+
const result = (0, CapabilitySpecMerge_1.mergeCapabilitySpec)("a\n", "b\n", "c\n");
|
|
102
|
+
assert.equal(result.unparsable, true);
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=capability-spec-merge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-spec-merge.test.js","sourceRoot":"","sources":["../../../../../packages/core/test/unit/capability-spec-merge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -95,7 +95,7 @@ function assertContractEditable(toolName, projectDir) {
|
|
|
95
95
|
return;
|
|
96
96
|
throw new Error(toolName +
|
|
97
97
|
" writes files the specification contract protects, and no change is open." +
|
|
98
|
-
" Open one first: specgate
|
|
98
|
+
" Open one first: specgate propose <id>." +
|
|
99
99
|
' To allow it permanently, set "mcpAllowContractEdits": true in .specgate/config.json.');
|
|
100
100
|
}
|
|
101
101
|
class ProjectHelper {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-tools.js","sourceRoot":"","sources":["../../../../packages/mcp-spec-driven/src/native-tools.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBH,sCASC;AAUD,oDAOC;AAGD,wDAQC;AAvDD,4CAA8B;AAC9B,gDAAkC;AAUlC;;;;;;GAMG;AACH,SAAgB,aAAa,CAAC,UAAkB;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,OAAO,EAAE;aACN,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;aACzC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,oBAAoB,CAAC,UAAkB;IACrD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;QACvF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,qBAAqB,KAAK,IAAI,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,+DAA+D;AAC/D,SAAgB,sBAAsB,CAAC,QAAgB,EAAE,UAAkB;IACzE,IAAI,aAAa,CAAC,UAAU,CAAC,IAAI,oBAAoB,CAAC,UAAU,CAAC;QAAE,OAAO;IAC1E,MAAM,IAAI,KAAK,CACb,QAAQ;QACN,2EAA2E;QAC3E,
|
|
1
|
+
{"version":3,"file":"native-tools.js","sourceRoot":"","sources":["../../../../packages/mcp-spec-driven/src/native-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,15 +32,15 @@ exports.STEPS = [
|
|
|
32
32
|
summary: "Turn the plan or brief into requirements, one module at a time.",
|
|
33
33
|
when: "The project starts from a plan or brief (`docs/brief.md`), or the user names a module of it to specify.",
|
|
34
34
|
argumentHint: "<module>",
|
|
35
|
-
run: ["specgate
|
|
35
|
+
run: ["specgate propose --from-brief", "specgate propose --from-brief <module>"],
|
|
36
36
|
guidance: [
|
|
37
|
-
"No `docs/brief.md`: show the person what `specgate
|
|
38
|
-
"If `specgate
|
|
37
|
+
"No `docs/brief.md`: show the person what `specgate propose --from-brief` prints about a brief, and stop — the brief is theirs to write (`specgate propose --from-brief --new-brief` gives them one to fill in).",
|
|
38
|
+
"If `specgate propose --from-brief` says the brief has no front matter, or that it needs fixes: follow `docs/specs/BRIEF-SETUP.md`. Write or fix only the front matter at the top of `docs/brief.md` — never a word below it — run `specgate propose --from-brief` again, then **stop** and show the front matter to the person to review. Draft no module in the same turn.",
|
|
39
39
|
"If the front matter is complete and the brief has no `## Module:` sections: follow `docs/specs/BRIEF-CARDS.md`. Add one section per module — Rules, Examples, Questions — from the brief's own text, keep every line already there, then **stop** and show the sections to the person.",
|
|
40
|
-
"Before a module is drafted, `specgate
|
|
41
|
-
"Without a module, `specgate
|
|
42
|
-
"`specgate
|
|
43
|
-
"Write only inside `docs/specs/changes/draft-<module>/`. Then run `specgate
|
|
40
|
+
"Before a module is drafted, `specgate propose --from-brief --check` must report no error: it checks the brief's fields, a section per module, and rules with examples. Its warnings are for the person to judge.",
|
|
41
|
+
"Without a module, `specgate propose --from-brief` lists the brief's modules and names the next one. Draft that one.",
|
|
42
|
+
"`specgate propose --from-brief <module>` opens the draft and writes `DRAFTING.md` inside it. Follow it exactly: it has the module's section of the brief, the values to use, the reserved ids, the actors and surfaces, and every format the checklist reads.",
|
|
43
|
+
"Write only inside `docs/specs/changes/draft-<module>/`. Then run `specgate propose --from-brief <module>` again and fix every finding until it says **Ready to review**.",
|
|
44
44
|
"A `D6_unlisted_value` is a value the brief never gave: use the brief's value, list it in `assumptions.md`, or make it a question. Never invent a business rule — what only the client can decide goes in `questions.md`.",
|
|
45
45
|
"Do not archive. End with the open questions for the person: they review the draft and answer what they can. Then each requirement is built test first and delivered with `specgate apply REQ-NNN`; a person runs `specgate archive draft-<module>` once all of them are applied.",
|
|
46
46
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../scripts/agents/commands.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAcU,QAAA,KAAK,GAAgB;IAChC;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,2CAA2C;QACjD,GAAG,EAAE,CAAC,wBAAwB,CAAC;QAC/B,QAAQ,EAAE;YACR,8EAA8E;YAC9E,uFAAuF;YACvF,wEAAwE;SACzE;KACF;IACD;QACE,wEAAwE;QACxE,0EAA0E;QAC1E,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,iEAAiE;QAC1E,IAAI,EAAE,yGAAyG;QAC/G,YAAY,EAAE,UAAU;QACxB,GAAG,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../scripts/agents/commands.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAcU,QAAA,KAAK,GAAgB;IAChC;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,2CAA2C;QACjD,GAAG,EAAE,CAAC,wBAAwB,CAAC;QAC/B,QAAQ,EAAE;YACR,8EAA8E;YAC9E,uFAAuF;YACvF,wEAAwE;SACzE;KACF;IACD;QACE,wEAAwE;QACxE,0EAA0E;QAC1E,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,iEAAiE;QAC1E,IAAI,EAAE,yGAAyG;QAC/G,YAAY,EAAE,UAAU;QACxB,GAAG,EAAE,CAAC,+BAA+B,EAAE,wCAAwC,CAAC;QAChF,QAAQ,EAAE;YACR,iNAAiN;YACjN,6WAA6W;YAC7W,wRAAwR;YACxR,kNAAkN;YAClN,qHAAqH;YACrH,+PAA+P;YAC/P,0KAA0K;YAC1K,0NAA0N;YAC1N,kRAAkR;SACnR;KACF;IACD;QACE,yEAAyE;QACzE,gEAAgE;QAChE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,0EAA0E;QACnF,IAAI,EAAE,2FAA2F;QACjG,GAAG,EAAE;YACH,8BAA8B;YAC9B,8CAA8C;YAC9C,2CAA2C;SAC5C;QACD,QAAQ,EAAE;YACR,4JAA4J;YAC5J,+KAA+K;YAC/K,mIAAmI;YACnI,gFAAgF;SACjF;KACF;IACD;QACE,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,iFAAiF;QAC1F,IAAI,EAAE,8FAA8F;QACpG,GAAG,EAAE,CAAC,iDAAiD,CAAC;QACxD,QAAQ,EAAE;YACR,gHAAgH;YAChH,qJAAqJ;YACrJ,0CAA0C;SAC3C;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,wEAAwE;QACjF,IAAI,EAAE,oGAAoG;QAC1G,GAAG,EAAE;YACH,wBAAwB;YACxB,2CAA2C;YAC3C,iCAAiC;SAClC;QACD,QAAQ,EAAE;YACR,oDAAoD;YACpD,6JAA6J;YAC7J,4FAA4F;YAC5F,sEAAsE;YACtE,mIAAmI;SACpI;KACF;IACD;QACE,sEAAsE;QACtE,sEAAsE;QACtE,8DAA8D;QAC9D,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,+DAA+D;QACxE,IAAI,EAAE,yDAAyD;QAC/D,GAAG,EAAE,CAAC,uBAAuB,CAAC;QAC9B,QAAQ,EAAE;YACR,kEAAkE;YAClE,kFAAkF;YAClF,yFAAyF;SAC1F;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,4EAA4E;QACrF,IAAI,EAAE,uGAAuG;QAC7G,GAAG,EAAE;YACH,6CAA6C;YAC7C,wCAAwC;YACxC,qCAAqC;SACtC;QACD,QAAQ,EAAE;YACR,+GAA+G;YAC/G,wHAAwH;YACxH,oEAAoE;YACpE,+FAA+F;SAChG;KACF;IACD;QACE,yEAAyE;QACzE,kDAAkD;QAClD,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,0EAA0E;QACnF,IAAI,EAAE,mFAAmF;QACzF,GAAG,EAAE,CAAC,iCAAiC,CAAC;QACxC,QAAQ,EAAE;YACR,wGAAwG;YACxG,6FAA6F;SAC9F;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,gEAAgE;QACzE,IAAI,EAAE,2CAA2C;QACjD,GAAG,EAAE,CAAC,eAAe,EAAE,uBAAuB,CAAC;QAC/C,QAAQ,EAAE;YACR,yGAAyG;YACzG,kHAAkH;SACnH;KACF;CACF,CAAC;AAEF,0EAA0E;AAC7D,QAAA,aAAa,GAAG;IAC3B,mHAAmH;IACnH,kKAAkK;IAClK,2GAA2G;IAC3G,iFAAiF;IACjF,2HAA2H;CAC5H,CAAC"}
|
|
@@ -60,6 +60,7 @@ const MARKERS = [
|
|
|
60
60
|
["cline", [".clinerules"]],
|
|
61
61
|
["codex", [".codex"]],
|
|
62
62
|
["antigravity", [".agents"]],
|
|
63
|
+
["opencode", [".opencode", "opencode.json", "opencode.jsonc"]],
|
|
63
64
|
];
|
|
64
65
|
function detectAgents(projectDir) {
|
|
65
66
|
return MARKERS.filter(([tool, files]) => init_1.TOOLS[tool] && files.some((f) => fs.existsSync(path.join(projectDir, f)))).map(([tool]) => tool);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../scripts/agents/detect.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../scripts/agents/detect.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBH,oCAIC;AAMD,sDA8BC;AAzDD,4CAA8B;AAC9B,gDAAkC;AAClC,iCAAgD;AAEhD,MAAM,OAAO,GAAsC;IACjD,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpC,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACvC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC9D,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC7C,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAC9B,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpC,CAAC,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;IAC1B,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,eAAe,EAAE,gBAAgB,CAAC,CAAC;CAC/D,CAAC;AAEF,SAAgB,YAAY,CAAC,UAAkB;IAC7C,OAAO,OAAO,CAAC,MAAM,CACnB,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,YAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAC7F,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CACnC,UAAkB,EAClB,IAA0C,EAC1C,GAA0B;IAE1B,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO;IACtB,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,GAAG,CAAC,gEAAgE,CAAC,CAAC;QACtE,GAAG,CAAC,iFAAiF,CAAC,CAAC;QACvF,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAA,sBAAe,EAAC,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACzF,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,GAAG,CACD,UAAU,MAAM,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,2BAA2B;YAC1F,KAAK,OAAO,CAAC,MAAM,WAAW,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,4BAA4B,CAAC,CAAC,CAAC,EAAE,IAAI,CAC1G,CAAC;QACF,GAAG,CAAC,2EAA2E,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CACD,0CAA0C,GAAG,IAAK,GAAa,CAAC,OAAO,kCAAkC,CAC1G,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -334,6 +334,19 @@ exports.TOOLS = {
|
|
|
334
334
|
label: "Codex",
|
|
335
335
|
files: () => [{ path: "AGENTS.md", contents: instructionsBody("Agent instructions") }],
|
|
336
336
|
},
|
|
337
|
+
opencode: {
|
|
338
|
+
label: "OpenCode",
|
|
339
|
+
// OpenCode reads AGENTS.md itself; its commands are Markdown files under
|
|
340
|
+
// `.opencode/commands/`, invoked by file name (`/specgate-draft`), with a
|
|
341
|
+
// `description` in the front matter and `$ARGUMENTS` for what follows.
|
|
342
|
+
files: () => [
|
|
343
|
+
...commands_1.STEPS.map((s) => ({
|
|
344
|
+
path: path.join(".opencode", "commands", `${exports.AGENT_NAMESPACE}-${s.name}.md`),
|
|
345
|
+
contents: slashCommandBody(s).replace(`# /${exports.AGENT_NAMESPACE}:${s.name}`, `# /${exports.AGENT_NAMESPACE}-${s.name}`),
|
|
346
|
+
})),
|
|
347
|
+
{ path: "AGENTS.md", contents: instructionsBody("Agent instructions") },
|
|
348
|
+
],
|
|
349
|
+
},
|
|
337
350
|
antigravity: {
|
|
338
351
|
label: "Antigravity",
|
|
339
352
|
// Two files, because Antigravity reads both halves of what Specgate offers:
|