From 573bdbb8fc53b6e9724efa774358792314dd16e2 Mon Sep 17 00:00:00 2001 From: Christoph Pirkl Date: Wed, 5 Aug 2026 09:58:11 +0200 Subject: [PATCH 1/7] Add OFT snippets --- .../oft-spec-driven-development/SKILL.md | 6 +++ README.md | 11 ++-- build.gradle | 2 +- .../03-mvp-oft-template-snippets.md | 49 ++++++++++++++++++ doc/design/architecture.md | 22 ++++++-- doc/system_requirements.md | 27 ++++++++-- extension/package.json | 13 ++++- .../openfasttrace-markdown.code-snippets | 32 ++++++++++++ ...enfasttrace-restructuredtext.code-snippets | 32 ++++++++++++ extension/src/extension.ts | 1 + .../src/test/integration/extension.test.ts | 50 +++++++++++++++++++ 11 files changed, 229 insertions(+), 16 deletions(-) create mode 100644 doc/changesets/03-mvp-oft-template-snippets.md create mode 100644 extension/snippets/openfasttrace-markdown.code-snippets create mode 100644 extension/snippets/openfasttrace-restructuredtext.code-snippets diff --git a/.agents/skills/oft-spec-driven-development/SKILL.md b/.agents/skills/oft-spec-driven-development/SKILL.md index 0c91b8c..d20f37c 100644 --- a/.agents/skills/oft-spec-driven-development/SKILL.md +++ b/.agents/skills/oft-spec-driven-development/SKILL.md @@ -232,6 +232,12 @@ If the issue text is unavailable, ask the user for the issue content or a short - Preserve existing OFT IDs unless the semantics changed. - When semantics change, revise the item thoughtfully instead of making arbitrary ID churn. - Keep requirements user-facing and design technical; do not duplicate the same text in both places. +- For source and test coverage tags, use only the covering artifact type on the + left side (for example, `[impl->dsn~name~1]`); let OpenFastTrace generate the + tag item's name. Do not use `>>` forwarding to connect implementation tags + to tests. Instead, make the relevant design item need both `impl` and + `itest`, and have separate implementation and test coverage tags cover that + design item. - Prefer precise task items over broad epics in changesets. - Keep comments in code minimal and let naming carry intent, consistent with the quality requirements. - Avoid adding dependencies unless a documented design decision approves them. diff --git a/README.md b/README.md index fc38b75..259c8e4 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,13 @@ for portable editor behavior. The first supported request is `workspace/symbol`; it currently returns no symbols until workspace indexing is implemented. +### OFT templates + +In Markdown and reStructuredText documents, type an `oft-` prefix and select +one of the OpenFastTrace snippets for a feature, requirement, scenario, design, +architecture, or constraint item. The scenario snippet includes a +Given-When-Then skeleton and a `Covers:` placeholder. + ## Requirements The extension requires Java 21 or later. It uses `openfasttrace.java.home` when @@ -34,10 +41,6 @@ is needed. ## Extension Settings -Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. - -For example: - This extension contributes `openfasttrace.java.home`, an absolute path to a Java 21 or later runtime. Configure it when VS Code cannot find a suitable runtime through `JAVA_HOME` or `PATH`. diff --git a/build.gradle b/build.gradle index 55f6a42..4b52bf9 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ sonar { } requirementTracing { - inputDirectories = files('doc') + inputDirectories = files('doc', 'extension/src', 'server/src') reportVerbosity = 'FAILURE_DETAILS' filteredTags = ['mvp'] filterAcceptsItemsWithoutTag = false diff --git a/doc/changesets/03-mvp-oft-template-snippets.md b/doc/changesets/03-mvp-oft-template-snippets.md new file mode 100644 index 0000000..5d994ea --- /dev/null +++ b/doc/changesets/03-mvp-oft-template-snippets.md @@ -0,0 +1,49 @@ +# 03 MVP OFT Template Snippets + +## Goal + +Provide a small, immediately useful authoring slice by offering editable OFT +starter templates in the supported specification-document languages. + +## Scope + +In scope: + +* Contribute feature, requirement, scenario, design, architecture, and + constraint snippets for Markdown and reStructuredText. +* Add the template requirement chain to the MVP trace. +* Verify snippet availability and the scenario skeleton in a VS Code + integration test. + +Out of scope: + +* Parsing, indexing, highlighting, ID completion, and trace execution. + +## Design References + +* [System Requirements](../system_requirements.md) +* [LSP-first Architecture](../design/architecture.md) +* [Quality Requirements](../design/quality_requirements.md) + +## Task List + +### Requirements And Design + +- [x] Mark the feature, template requirement, and template-insertion scenario as MVP. +- [x] Split template snippets into their own single-scenario design item. +- [x] Add traced implementation and integration-test items for the snippet + contribution, covered by TypeScript source and integration-test tags. + +### Implementation + +- [x] Add language-native Markdown and reStructuredText snippet assets. +- [x] Register the assets in the extension manifest. + +### Verification + +- [x] Run the extension compile, lint, unit, and integration tests. +- [x] Run the full Gradle build and the MVP requirements trace. + +### Update User Documentation + +- [x] Document the templates and their invocation in README.md. diff --git a/doc/design/architecture.md b/doc/design/architecture.md index 77c6cf0..4060cbd 100644 --- a/doc/design/architecture.md +++ b/doc/design/architecture.md @@ -84,17 +84,29 @@ Covers: ### Editor Presentation `dsn~editor-presentation~1` -The VS Code adapter contributes snippets for OFT templates, a Markdown -TextMate injection grammar for immediate declaration coloring, and maps LSP -semantic tokens to OFT coverage-tag styling. It preserves the host language of -every document. +The VS Code adapter contributes a Markdown TextMate injection grammar for +immediate declaration coloring and maps LSP semantic tokens to OFT coverage-tag +styling. It preserves the host language of every document. Covers: - `scn~recognize-and-highlight-oft-content~1` -- `scn~author-an-oft-link~1` Needs: impl +### OFT Template Snippets +`dsn~oft-template-snippets~1` + +The VS Code adapter contributes language-native Markdown and reStructuredText +snippet files for the common OFT artifact templates. The templates are static, +editable starter text and do not require language-server parsing or indexing. + +Tags: mvp + +Covers: +- `scn~insert-oft-template~1` + +Needs: impl, itest + ### Trace Command and Plain-Text Report `dsn~trace-command-and-plain-text-report~1` diff --git a/doc/system_requirements.md b/doc/system_requirements.md index b6a6709..48f6eca 100644 --- a/doc/system_requirements.md +++ b/doc/system_requirements.md @@ -52,6 +52,8 @@ Needs: req The product provides item templates and context-aware completion of declared OFT IDs. +Tags: mvp + Needs: req ### Run OFT Traces @@ -163,6 +165,8 @@ Users can insert bundled templates for common OFT artifacts, including `feat`, `req`, `scn`, `dsn`, architecture, and constraint items. The scenario template includes a Given-When-Then skeleton and a covered-item placeholder. +Tags: mvp + Covers: - `feat~author-oft-items-and-links~1` @@ -302,16 +306,29 @@ Covers: Needs: dsn +### Insert an OFT Template +`scn~insert-oft-template~1` + +**Given** a user is editing a supported specification document +**When** the user inserts an OFT template +**Then** the editor inserts the selected editable template, including the +scenario Given-When-Then skeleton and Covers placeholder where applicable. + +Tags: mvp + +Covers: +- `req~insert-oft-templates~1` + +Needs: dsn + ### Author an OFT Link -`scn~author-an-oft-link~1` +`scn~author-an-oft-link~2` **Given** a user is editing a supported document or coverage tag -**When** the user inserts a template or requests completion at a valid OFT -reference position -**Then** the editor inserts the template or offers ranked workspace IDs. +**When** the user requests completion at a valid OFT reference position +**Then** the editor offers ranked workspace IDs. Covers: -- `req~insert-oft-templates~1` - `req~complete-covers-references~1` - `req~complete-coverage-tag-targets~1` diff --git a/extension/package.json b/extension/package.json index d92d99e..ccc4d32 100644 --- a/extension/package.json +++ b/extension/package.json @@ -8,13 +8,24 @@ "vscode": "^1.120.0" }, "categories": [ - "Other" + "Other", + "Snippets" ], "activationEvents": [ "onStartupFinished" ], "main": "./out/extension.js", "contributes": { + "snippets": [ + { + "language": "markdown", + "path": "./snippets/openfasttrace-markdown.code-snippets" + }, + { + "language": "restructuredtext", + "path": "./snippets/openfasttrace-restructuredtext.code-snippets" + } + ], "configuration": { "title": "OpenFastTrace", "properties": { diff --git a/extension/snippets/openfasttrace-markdown.code-snippets b/extension/snippets/openfasttrace-markdown.code-snippets new file mode 100644 index 0000000..825a832 --- /dev/null +++ b/extension/snippets/openfasttrace-markdown.code-snippets @@ -0,0 +1,32 @@ +{ + "OpenFastTrace: Feature": { + "prefix": "oft-feature", + "body": ["${1:Feature description}", "", "`feat~${2:feature-name}~${3:1}`", "", "Needs: req$0"], + "description": "Insert an OpenFastTrace feature." + }, + "OpenFastTrace: Requirement": { + "prefix": "oft-requirement", + "body": ["${1:Requirement description}", "", "`req~${2:requirement-name}~${3:1}`", "", "Covers:", "- `feat~${4:feature-name}~${5:1}`", "", "Needs: scn$0"], + "description": "Insert an OpenFastTrace requirement." + }, + "OpenFastTrace: Scenario": { + "prefix": "oft-scenario", + "body": ["${1:Scenario description}", "", "`scn~${2:scenario-name}~${3:1}`", "", "**Given** ${4:the initial context}", "**When** ${5:an action occurs}", "**Then** ${6:the expected outcome occurs}", "", "Covers:", "- `req~${7:requirement-name}~${8:1}`", "", "Needs: dsn$0"], + "description": "Insert an OpenFastTrace scenario with Given-When-Then steps." + }, + "OpenFastTrace: Design": { + "prefix": "oft-design", + "body": ["${1:Design description}", "", "`dsn~${2:design-name}~${3:1}`", "", "Covers:", "- `scn~${4:scenario-name}~${5:1}`", "", "Needs: impl$0"], + "description": "Insert an OpenFastTrace design item." + }, + "OpenFastTrace: Architecture": { + "prefix": "oft-architecture", + "body": ["${1:Architecture description}", "", "`arc~${2:architecture-name}~${3:1}`$0"], + "description": "Insert an OpenFastTrace architecture item." + }, + "OpenFastTrace: Constraint": { + "prefix": "oft-constraint", + "body": ["${1:Constraint description}", "", "`con~${2:constraint-name}~${3:1}`$0"], + "description": "Insert an OpenFastTrace constraint item." + } +} diff --git a/extension/snippets/openfasttrace-restructuredtext.code-snippets b/extension/snippets/openfasttrace-restructuredtext.code-snippets new file mode 100644 index 0000000..a7e153f --- /dev/null +++ b/extension/snippets/openfasttrace-restructuredtext.code-snippets @@ -0,0 +1,32 @@ +{ + "OpenFastTrace: Feature": { + "prefix": "oft-feature", + "body": ["${1:Feature description}", "", "``feat~${2:feature-name}~${3:1}``", "", "Needs: req$0"], + "description": "Insert an OpenFastTrace feature." + }, + "OpenFastTrace: Requirement": { + "prefix": "oft-requirement", + "body": ["${1:Requirement description}", "", "``req~${2:requirement-name}~${3:1}``", "", "Covers:", "- ``feat~${4:feature-name}~${5:1}``", "", "Needs: scn$0"], + "description": "Insert an OpenFastTrace requirement." + }, + "OpenFastTrace: Scenario": { + "prefix": "oft-scenario", + "body": ["${1:Scenario description}", "", "``scn~${2:scenario-name}~${3:1}``", "", "**Given** ${4:the initial context}", "**When** ${5:an action occurs}", "**Then** ${6:the expected outcome occurs}", "", "Covers:", "- ``req~${7:requirement-name}~${8:1}``", "", "Needs: dsn$0"], + "description": "Insert an OpenFastTrace scenario with Given-When-Then steps." + }, + "OpenFastTrace: Design": { + "prefix": "oft-design", + "body": ["${1:Design description}", "", "``dsn~${2:design-name}~${3:1}``", "", "Covers:", "- ``scn~${4:scenario-name}~${5:1}``", "", "Needs: impl$0"], + "description": "Insert an OpenFastTrace design item." + }, + "OpenFastTrace: Architecture": { + "prefix": "oft-architecture", + "body": ["${1:Architecture description}", "", "``arc~${2:architecture-name}~${3:1}``$0"], + "description": "Insert an OpenFastTrace architecture item." + }, + "OpenFastTrace: Constraint": { + "prefix": "oft-constraint", + "body": ["${1:Constraint description}", "", "``con~${2:constraint-name}~${3:1}``$0"], + "description": "Insert an OpenFastTrace constraint item." + } +} diff --git a/extension/src/extension.ts b/extension/src/extension.ts index d4a5843..d021d95 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -3,6 +3,7 @@ import * as vscode from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node'; import { resolveJavaExecutable } from './javaRuntime'; +// [impl->dsn~oft-template-snippets~1] let client: LanguageClient | undefined; export async function activate(context: vscode.ExtensionContext): Promise<{ getLanguageClient: typeof getLanguageClient }> { diff --git a/extension/src/test/integration/extension.test.ts b/extension/src/test/integration/extension.test.ts index 0e789de..cb965eb 100644 --- a/extension/src/test/integration/extension.test.ts +++ b/extension/src/test/integration/extension.test.ts @@ -1,12 +1,33 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; +// [itest->dsn~oft-template-snippets~1] interface OpenFastTraceExports { getLanguageClient(): { sendRequest(method: string, parameters: { query: string }): Thenable; } | undefined; } +const templateLabels = [ + 'OpenFastTrace: Feature', + 'OpenFastTrace: Requirement', + 'OpenFastTrace: Scenario', + 'OpenFastTrace: Design', + 'OpenFastTrace: Architecture', + 'OpenFastTrace: Constraint', +]; + +const supportedDocumentLanguages = ['markdown', 'restructuredtext']; + +interface SnippetDefinition { + body: string[]; +} + +interface SnippetContribution { + language: string; + path: string; +} + suite('OpenFastTrace extension', () => { test('starts the language server and returns an empty workspace symbol result', async () => { const extension = vscode.extensions.getExtension('itsallcode.openfasttrace'); @@ -19,4 +40,33 @@ suite('OpenFastTrace extension', () => { const symbols = await client.sendRequest('workspace/symbol', { query: '' }); assert.deepStrictEqual(symbols, []); }); + + for (const language of supportedDocumentLanguages) { + for (const templateLabel of templateLabels) { + test(`offers ${templateLabel} in ${language} documents`, async () => { + const snippets = await snippetsFor(language); + const snippet = snippets[templateLabel]; + + assert.ok(snippet, `${language} must offer ${templateLabel}`); + if (templateLabel === 'OpenFastTrace: Scenario') { + const scenario = snippet.body.join('\n'); + assert.match(scenario, /\*\*Given\*\*/); + assert.match(scenario, /\*\*When\*\*/); + assert.match(scenario, /\*\*Then\*\*/); + assert.match(scenario, /Covers:/); + } + }); + } + } }); + +async function snippetsFor(language: string): Promise> { + const extension = vscode.extensions.getExtension('itsallcode.openfasttrace'); + assert.ok(extension, 'OpenFastTrace extension must be available to the test host'); + const contributions = extension.packageJSON.contributes.snippets as SnippetContribution[]; + const contribution = contributions.find(candidate => candidate.language === language); + + assert.ok(contribution, `OpenFastTrace must contribute snippets for ${language}`); + const contents = await vscode.workspace.fs.readFile(vscode.Uri.joinPath(extension.extensionUri, contribution.path)); + return JSON.parse(new TextDecoder().decode(contents)) as Record; +} From 13e23ee11426515f686b7027f8a803683246e99a Mon Sep 17 00:00:00 2001 From: Christoph Pirkl Date: Wed, 5 Aug 2026 10:06:07 +0200 Subject: [PATCH 2/7] Fix tracing --- build.gradle | 2 +- doc/design/architecture.md | 10 +++++++ doc/system_requirements.md | 58 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4b52bf9..bb564b5 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ requirementTracing { inputDirectories = files('doc', 'extension/src', 'server/src') reportVerbosity = 'FAILURE_DETAILS' filteredTags = ['mvp'] - filterAcceptsItemsWithoutTag = false + filterAcceptsItemsWithoutTag = true } def isNonStable = { String version -> diff --git a/doc/design/architecture.md b/doc/design/architecture.md index 4060cbd..f0a4bea 100644 --- a/doc/design/architecture.md +++ b/doc/design/architecture.md @@ -88,6 +88,8 @@ The VS Code adapter contributes a Markdown TextMate injection grammar for immediate declaration coloring and maps LSP semantic tokens to OFT coverage-tag styling. It preserves the host language of every document. +Tags: backlog + Covers: - `scn~recognize-and-highlight-oft-content~1` @@ -115,6 +117,8 @@ request with workspace-relative inputs and filters. The server returns a typed trace report containing status, messages, and source locations. The adapter renders it in an Output channel and opens locations from report entries. +Tags: backlog + Covers: - `scn~trace-the-mvp-scope~1` @@ -128,6 +132,8 @@ settings. Profiles contain scope, additional paths, artifact-type filters, tag filters, and output mode. Commands and a Quick Pick select profiles; optional VS Code Tasks are an adapter, not the persistence model. +Tags: backlog + Covers: - `scn~configure-a-repeatable-filtered-trace~1` @@ -140,6 +146,8 @@ The server exposes a normalized trace-result tree through a custom LSP command. The VS Code adapter maps it to `TestController` items grouped by file, item, and trace link; each node retains its source `Location` and defect detail. +Tags: backlog + Covers: - `scn~inspect-structured-results~1` @@ -152,6 +160,8 @@ The VS Code adapter registers a command that opens the canonical upstream user guide using the host browser service. The guide itself is not bundled or duplicated. +Tags: backlog + Covers: - `scn~read-the-oft-guide~1` diff --git a/doc/system_requirements.md b/doc/system_requirements.md index 48f6eca..75b75e5 100644 --- a/doc/system_requirements.md +++ b/doc/system_requirements.md @@ -26,6 +26,8 @@ only that scope. The product recognizes OFT declarations in Markdown, reStructuredText, and coverage tags in supported workspace files. +Tags: backlog + Needs: req ### Connect the Language Server @@ -44,6 +46,8 @@ Needs: req The product finds OFT declarations and follows coverage links throughout the workspace. +Tags: backlog + Needs: req ### Author OFT Items and Links @@ -62,6 +66,8 @@ Needs: req The product runs OpenFastTrace for the workspace and presents a navigable report. +Tags: backlog + Needs: req ### Configure Repeatable Traces @@ -70,6 +76,8 @@ Needs: req The product stores named trace profiles with inputs, filters, and output-mode selection. +Tags: backlog + Needs: req ### Inspect Structured Trace Results @@ -78,6 +86,8 @@ Needs: req The product presents trace outcomes as a hierarchical result view with source navigation. +Tags: backlog + Needs: req ### Access OFT Documentation @@ -85,6 +95,8 @@ Needs: req The product opens the upstream OpenFastTrace user guide from the IDE. +Tags: backlog + Needs: req ## User Requirements @@ -95,6 +107,8 @@ Needs: req The editor highlights OFT declarations in `.md`, `.markdown`, and `.rst` documents without changing the documents' ordinary language mode. +Tags: backlog + Covers: - `feat~recognize-oft-content~1` @@ -119,6 +133,8 @@ Needs: scn The editor highlights OFT coverage tags in source, configuration, and markup files supported by the OpenFastTrace tag importer. +Tags: backlog + Covers: - `feat~recognize-oft-content~1` @@ -130,6 +146,8 @@ Needs: scn Users can find workspace declarations by full or partial OFT item ID and open the matching declaration. +Tags: backlog + Covers: - `feat~discover-and-navigate-oft-items~1` @@ -142,6 +160,8 @@ Users can go from a `Covers:` ID or either side of a coverage tag to the corresponding declaration. Missing name and revision on a coverage-tag left side are resolved from its right-side target. +Tags: backlog + Covers: - `feat~discover-and-navigate-oft-items~1` @@ -153,6 +173,8 @@ Needs: scn Users can find `Covers:` entries and source-side coverage tags that cover an OFT declaration. +Tags: backlog + Covers: - `feat~discover-and-navigate-oft-items~1` @@ -167,6 +189,8 @@ template includes a Given-When-Then skeleton and a covered-item placeholder. Tags: mvp +Tags: backlog + Covers: - `feat~author-oft-items-and-links~1` @@ -178,6 +202,8 @@ Needs: scn While editing a `Covers:` entry, users receive workspace declaration IDs ranked by full-ID prefix, name prefix, name substring, and artifact-type prefix. +Tags: backlog + Covers: - `feat~author-oft-items-and-links~1` @@ -189,6 +215,8 @@ Needs: scn After an artifact type and `->` in a likely coverage tag, users receive the same ranked declaration completion for the tag target. +Tags: backlog + Covers: - `feat~author-oft-items-and-links~1` @@ -201,6 +229,8 @@ Users can run an OFT trace using the workspace folder as the default input and read a plain-text result in the IDE. Reported IDs and defects navigate to their known source locations. +Tags: backlog + Covers: - `feat~run-oft-traces~1` @@ -212,6 +242,8 @@ Needs: scn Users can restrict a trace to selected workspace-relative paths, including source and test roots where the client can identify them. +Tags: backlog + Covers: - `feat~configure-repeatable-traces~1` @@ -223,6 +255,8 @@ Needs: scn Users can filter a trace by artifact types and OFT tags. A tag filter of `mvp` selects only MVP-tagged product artifacts. +Tags: backlog + Covers: - `feat~configure-repeatable-traces~1` @@ -234,6 +268,8 @@ Needs: scn Users can save and invoke named trace profiles with scope, paths, filters, and output mode. +Tags: backlog + Covers: - `feat~configure-repeatable-traces~1` @@ -245,6 +281,8 @@ Needs: scn Users can inspect pass/fail trace results grouped by source file, item, and incoming or outgoing link, including defect explanations and source navigation. +Tags: backlog + Covers: - `feat~inspect-structured-trace-results~1` @@ -256,6 +294,8 @@ Needs: scn Users can invoke an IDE command that opens the upstream OpenFastTrace user guide. +Tags: backlog + Covers: - `feat~access-oft-documentation~1` @@ -271,6 +311,8 @@ Needs: scn **Then** the extension highlights declarations or coverage tags in the relevant range while preserving the file's normal language support. +Tags: backlog + Covers: - `req~highlight-oft-declarations~1` - `req~highlight-coverage-tags~1` @@ -287,6 +329,8 @@ Needs: dsn Tags: mvp +Tags: backlog + Covers: - `req~start-language-server~1` @@ -299,6 +343,8 @@ Needs: dsn **When** the user searches, follows the reference, or requests implementations **Then** the IDE presents the declaration or all covering locations. +Tags: backlog + Covers: - `req~search-workspace-oft-items~1` - `req~navigate-oft-links~1` @@ -316,6 +362,8 @@ scenario Given-When-Then skeleton and Covers placeholder where applicable. Tags: mvp +Tags: backlog + Covers: - `req~insert-oft-templates~1` @@ -328,6 +376,8 @@ Needs: dsn **When** the user requests completion at a valid OFT reference position **Then** the editor offers ranked workspace IDs. +Tags: backlog + Covers: - `req~complete-covers-references~1` - `req~complete-coverage-tag-targets~1` @@ -343,6 +393,8 @@ filter **Then** the server traces only that tagged scope and the extension presents a navigable plain-text report. +Tags: backlog + Covers: - `req~trace-the-workspace~1` @@ -356,6 +408,8 @@ Needs: dsn tags, and output mode **Then** the trace uses that profile and retains it for later invocation. +Tags: backlog + Covers: - `req~select-trace-inputs~1` - `req~filter-trace-results~1` @@ -371,6 +425,8 @@ Needs: dsn **Then** the user can inspect result hierarchy, status, explanation, and source locations. +Tags: backlog + Covers: - `req~review-trace-result-tree~1` @@ -384,6 +440,8 @@ Needs: dsn **Then** the upstream guide opens in the configured external or integrated browser surface. +Tags: backlog + Covers: - `req~open-oft-user-guide~1` From 1060100f07422ee59465541e91d9fcfa625c7910 Mon Sep 17 00:00:00 2001 From: Christoph Pirkl Date: Wed, 5 Aug 2026 10:48:10 +0200 Subject: [PATCH 3/7] Mirror intellij templates --- README.md | 8 ++- .../openfasttrace-markdown.code-snippets | 61 ++++++++++++------- ...enfasttrace-restructuredtext.code-snippets | 61 ++++++++++++------- .../src/test/integration/extension.test.ts | 17 +++++- 4 files changed, 98 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 259c8e4..4e054a9 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,14 @@ implemented. ### OFT templates In Markdown and reStructuredText documents, type an `oft-` prefix and select -one of the OpenFastTrace snippets for a feature, requirement, scenario, design, -architecture, or constraint item. The scenario snippet includes a +one of the OpenFastTrace snippets for an architecture, business or technical +constraint, design, feature, quality goal, quality scenario, requirement, or +scenario item. The scenario snippet includes a Given-When-Then skeleton and a `Covers:` placeholder. +To insert a snippet, type `oft-`, press `Ctrl+Space` to open the completion +list (or wait for it to appear), then select the desired OpenFastTrace snippet. + ## Requirements The extension requires Java 21 or later. It uses `openfasttrace.java.home` when diff --git a/extension/snippets/openfasttrace-markdown.code-snippets b/extension/snippets/openfasttrace-markdown.code-snippets index 825a832..8f2eeda 100644 --- a/extension/snippets/openfasttrace-markdown.code-snippets +++ b/extension/snippets/openfasttrace-markdown.code-snippets @@ -1,32 +1,47 @@ { - "OpenFastTrace: Feature": { - "prefix": "oft-feature", - "body": ["${1:Feature description}", "", "`feat~${2:feature-name}~${3:1}`", "", "Needs: req$0"], - "description": "Insert an OpenFastTrace feature." + "OpenFastTrace: Architecture": { + "prefix": ["oft-architecture", "oft-arch"], + "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`arch~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Comment:", "", "${4:Comment}", "", "Covers:", "", "* `${5:covered-item}`", "", "Needs: dsn", "", "$0"], + "description": "OFT Architectural Requirement" }, - "OpenFastTrace: Requirement": { - "prefix": "oft-requirement", - "body": ["${1:Requirement description}", "", "`req~${2:requirement-name}~${3:1}`", "", "Covers:", "- `feat~${4:feature-name}~${5:1}`", "", "Needs: scn$0"], - "description": "Insert an OpenFastTrace requirement." + "OpenFastTrace: Business Constraint": { + "prefix": ["oft-business-constraint", "oft-bconstr"], + "body": ["${1|##,###,####,#####,######|} ${2:Title}", "`bconstr~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: req", "", "$0"], + "description": "OFT Business Constraint" }, - "OpenFastTrace: Scenario": { - "prefix": "oft-scenario", - "body": ["${1:Scenario description}", "", "`scn~${2:scenario-name}~${3:1}`", "", "**Given** ${4:the initial context}", "**When** ${5:an action occurs}", "**Then** ${6:the expected outcome occurs}", "", "Covers:", "- `req~${7:requirement-name}~${8:1}`", "", "Needs: dsn$0"], - "description": "Insert an OpenFastTrace scenario with Given-When-Then steps." + "OpenFastTrace: Constraint": { + "prefix": ["oft-constraint", "oft-constr"], + "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`constr~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: dsn", "", "$0"], + "description": "OFT Technical Constraint" }, "OpenFastTrace: Design": { - "prefix": "oft-design", - "body": ["${1:Design description}", "", "`dsn~${2:design-name}~${3:1}`", "", "Covers:", "- `scn~${4:scenario-name}~${5:1}`", "", "Needs: impl$0"], - "description": "Insert an OpenFastTrace design item." + "prefix": ["oft-design", "oft-dsn"], + "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`dsn~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Covers:", "", "* `${4:covered-item}`", "", "Needs: impl, ${5|utest,itest,stest|}", "", "$0"], + "description": "OFT Design" }, - "OpenFastTrace: Architecture": { - "prefix": "oft-architecture", - "body": ["${1:Architecture description}", "", "`arc~${2:architecture-name}~${3:1}`$0"], - "description": "Insert an OpenFastTrace architecture item." + "OpenFastTrace: Feature": { + "prefix": ["oft-feature", "oft-feat"], + "body": ["${1|##,###,####,#####,######|} ${2:Title}", "`feat~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: req", "", "$0"], + "description": "OFT Feature" }, - "OpenFastTrace: Constraint": { - "prefix": "oft-constraint", - "body": ["${1:Constraint description}", "", "`con~${2:constraint-name}~${3:1}`$0"], - "description": "Insert an OpenFastTrace constraint item." + "OpenFastTrace: Quality Goal": { + "prefix": ["oft-quality-goal", "oft-qg"], + "body": ["${1|##,###,####,#####,######|} ${2:Title}", "`qg~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: qs", "", "$0"], + "description": "OFT Quality Goal" + }, + "OpenFastTrace: Quality Scenario": { + "prefix": ["oft-quality-scenario", "oft-qs"], + "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`qs~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Covers:", "", "* `${4:covered-item}`", "", "Needs: dsn, ${5|utest,itest,stest|}", "", "$0"], + "description": "OFT Quality Scenario" + }, + "OpenFastTrace: Requirement": { + "prefix": ["oft-requirement", "oft-req"], + "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`req~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Covers:", "", "* [`${4:covered-item}`](#${5:markdown-link})", "", "Needs: req", "", "$0"], + "description": "OFT High-Level Requirement" + }, + "OpenFastTrace: Scenario": { + "prefix": ["oft-scenario", "oft-scn"], + "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`scn~${2/(.*)/${1:/kebabcase}/}~1`", "", "**Given** ${3:the initial context}", "**When** ${4:an action occurs}", "**Then** ${5:the expected outcome occurs}", "", "Covers:", "- `${6:covered-item}`", "", "Needs: dsn", "", "$0"], + "description": "OFT Scenario" } } diff --git a/extension/snippets/openfasttrace-restructuredtext.code-snippets b/extension/snippets/openfasttrace-restructuredtext.code-snippets index a7e153f..e6a6721 100644 --- a/extension/snippets/openfasttrace-restructuredtext.code-snippets +++ b/extension/snippets/openfasttrace-restructuredtext.code-snippets @@ -1,32 +1,47 @@ { - "OpenFastTrace: Feature": { - "prefix": "oft-feature", - "body": ["${1:Feature description}", "", "``feat~${2:feature-name}~${3:1}``", "", "Needs: req$0"], - "description": "Insert an OpenFastTrace feature." + "OpenFastTrace: Architecture": { + "prefix": ["oft-architecture", "oft-arch"], + "body": ["${1:Title}", "${1/./=/g}", "", "``arch~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Comment:", "", "${3:Comment}", "", "Covers:", "", "* ``${4:covered-item}``", "", "Needs: dsn", "", "$0"], + "description": "OFT Architectural Requirement" }, - "OpenFastTrace: Requirement": { - "prefix": "oft-requirement", - "body": ["${1:Requirement description}", "", "``req~${2:requirement-name}~${3:1}``", "", "Covers:", "- ``feat~${4:feature-name}~${5:1}``", "", "Needs: scn$0"], - "description": "Insert an OpenFastTrace requirement." + "OpenFastTrace: Business Constraint": { + "prefix": ["oft-business-constraint", "oft-bconstr"], + "body": ["${1:Title}", "${1/./-/g}", "", "``bconstr~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: req", "", "$0"], + "description": "OFT Business Constraint" }, - "OpenFastTrace: Scenario": { - "prefix": "oft-scenario", - "body": ["${1:Scenario description}", "", "``scn~${2:scenario-name}~${3:1}``", "", "**Given** ${4:the initial context}", "**When** ${5:an action occurs}", "**Then** ${6:the expected outcome occurs}", "", "Covers:", "- ``req~${7:requirement-name}~${8:1}``", "", "Needs: dsn$0"], - "description": "Insert an OpenFastTrace scenario with Given-When-Then steps." + "OpenFastTrace: Constraint": { + "prefix": ["oft-constraint", "oft-constr"], + "body": ["${1:Title}", "${1/./=/g}", "", "``constr~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: dsn", "", "$0"], + "description": "OFT Technical Constraint" }, "OpenFastTrace: Design": { - "prefix": "oft-design", - "body": ["${1:Design description}", "", "``dsn~${2:design-name}~${3:1}``", "", "Covers:", "- ``scn~${4:scenario-name}~${5:1}``", "", "Needs: impl$0"], - "description": "Insert an OpenFastTrace design item." + "prefix": ["oft-design", "oft-dsn"], + "body": ["${1:Title}", "${1/./=/g}", "", "``dsn~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Covers:", "", "* ``${3:covered-item}``", "", "Needs: impl, ${4|utest,itest,stest|}", "", "$0"], + "description": "OFT Design" }, - "OpenFastTrace: Architecture": { - "prefix": "oft-architecture", - "body": ["${1:Architecture description}", "", "``arc~${2:architecture-name}~${3:1}``$0"], - "description": "Insert an OpenFastTrace architecture item." + "OpenFastTrace: Feature": { + "prefix": ["oft-feature", "oft-feat"], + "body": ["${1:Title}", "${1/./-/g}", "", "``feat~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: req", "", "$0"], + "description": "OFT Feature" }, - "OpenFastTrace: Constraint": { - "prefix": "oft-constraint", - "body": ["${1:Constraint description}", "", "``con~${2:constraint-name}~${3:1}``$0"], - "description": "Insert an OpenFastTrace constraint item." + "OpenFastTrace: Quality Goal": { + "prefix": ["oft-quality-goal", "oft-qg"], + "body": ["${1:Title}", "${1/./-/g}", "", "``qg~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: qs", "", "$0"], + "description": "OFT Quality Goal" + }, + "OpenFastTrace: Quality Scenario": { + "prefix": ["oft-quality-scenario", "oft-qs"], + "body": ["${1:Title}", "${1/./=/g}", "", "``qs~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Covers:", "", "* ``${3:covered-item}``", "", "Needs: dsn, ${4|utest,itest,stest|}", "", "$0"], + "description": "OFT Quality Scenario" + }, + "OpenFastTrace: Requirement": { + "prefix": ["oft-requirement", "oft-req"], + "body": ["${1:Title}", "${1/./=/g}", "", "``req~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Covers:", "", "* ``${3:covered-item}``", "", "Needs: req", "", "$0"], + "description": "OFT High-Level Requirement" + }, + "OpenFastTrace: Scenario": { + "prefix": ["oft-scenario", "oft-scn"], + "body": ["${1:Title}", "${1/./=/g}", "", "``scn~${1/(.*)/${1:/kebabcase}/}~1``", "", "**Given** ${2:the initial context}", "**When** ${3:an action occurs}", "**Then** ${4:the expected outcome occurs}", "", "Covers:", "", "* ``${5:covered-item}``", "", "Needs: dsn", "", "$0"], + "description": "OFT Scenario" } } diff --git a/extension/src/test/integration/extension.test.ts b/extension/src/test/integration/extension.test.ts index cb965eb..f7e1d8d 100644 --- a/extension/src/test/integration/extension.test.ts +++ b/extension/src/test/integration/extension.test.ts @@ -8,7 +8,7 @@ interface OpenFastTraceExports { } | undefined; } -const templateLabels = [ +const commonTemplateLabels = [ 'OpenFastTrace: Feature', 'OpenFastTrace: Requirement', 'OpenFastTrace: Scenario', @@ -17,6 +17,13 @@ const templateLabels = [ 'OpenFastTrace: Constraint', ]; +const templateLabels = [ + ...commonTemplateLabels, + 'OpenFastTrace: Business Constraint', + 'OpenFastTrace: Quality Goal', + 'OpenFastTrace: Quality Scenario', +]; + const supportedDocumentLanguages = ['markdown', 'restructuredtext']; interface SnippetDefinition { @@ -55,6 +62,14 @@ suite('OpenFastTrace extension', () => { assert.match(scenario, /\*\*Then\*\*/); assert.match(scenario, /Covers:/); } + if (language === 'markdown') { + assert.match(snippet.body.join('\n'), /\$\{1\|/); + assert.match(snippet.body.join('\n'), /\$\{2\/\(\.\*\)\/\$\{1:\/kebabcase\}\/\}/); + } + if (language === 'restructuredtext') { + assert.match(snippet.body.join('\n'), /\$\{1\/\.\/.*\/g\}/); + assert.match(snippet.body.join('\n'), /\$\{1\/\(\.\*\)\/\$\{1:\/kebabcase\}\/\}/); + } }); } } From 43257b176386f283f6c607cbc960e58255e2e39b Mon Sep 17 00:00:00 2001 From: Christoph Pirkl Date: Wed, 5 Aug 2026 10:49:10 +0200 Subject: [PATCH 4/7] Add source comment to snippets --- extension/snippets/openfasttrace-markdown.code-snippets | 1 + extension/snippets/openfasttrace-restructuredtext.code-snippets | 1 + 2 files changed, 2 insertions(+) diff --git a/extension/snippets/openfasttrace-markdown.code-snippets b/extension/snippets/openfasttrace-markdown.code-snippets index 8f2eeda..504d375 100644 --- a/extension/snippets/openfasttrace-markdown.code-snippets +++ b/extension/snippets/openfasttrace-markdown.code-snippets @@ -1,3 +1,4 @@ +// Based on https://github.com/itsallcode/openfasttrace-intellij-plugin/blob/main/src/main/resources/liveTemplates/OpenFastTrace.xml { "OpenFastTrace: Architecture": { "prefix": ["oft-architecture", "oft-arch"], diff --git a/extension/snippets/openfasttrace-restructuredtext.code-snippets b/extension/snippets/openfasttrace-restructuredtext.code-snippets index e6a6721..c234126 100644 --- a/extension/snippets/openfasttrace-restructuredtext.code-snippets +++ b/extension/snippets/openfasttrace-restructuredtext.code-snippets @@ -1,3 +1,4 @@ +// Based on https://github.com/itsallcode/openfasttrace-intellij-plugin/blob/main/src/main/resources/liveTemplates/OpenFastTrace.xml { "OpenFastTrace: Architecture": { "prefix": ["oft-architecture", "oft-arch"], From 6bfa7ed196ebd9e18643948571bc208590eeb7b3 Mon Sep 17 00:00:00 2001 From: Christoph Pirkl Date: Wed, 5 Aug 2026 10:51:31 +0200 Subject: [PATCH 5/7] Remove misleading prefixes --- .../openfasttrace-markdown.code-snippets | 18 +++++++++--------- ...penfasttrace-restructuredtext.code-snippets | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/extension/snippets/openfasttrace-markdown.code-snippets b/extension/snippets/openfasttrace-markdown.code-snippets index 504d375..0f63240 100644 --- a/extension/snippets/openfasttrace-markdown.code-snippets +++ b/extension/snippets/openfasttrace-markdown.code-snippets @@ -1,47 +1,47 @@ // Based on https://github.com/itsallcode/openfasttrace-intellij-plugin/blob/main/src/main/resources/liveTemplates/OpenFastTrace.xml { "OpenFastTrace: Architecture": { - "prefix": ["oft-architecture", "oft-arch"], + "prefix": ["oft-architecture"], "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`arch~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Comment:", "", "${4:Comment}", "", "Covers:", "", "* `${5:covered-item}`", "", "Needs: dsn", "", "$0"], "description": "OFT Architectural Requirement" }, "OpenFastTrace: Business Constraint": { - "prefix": ["oft-business-constraint", "oft-bconstr"], + "prefix": ["oft-business-constraint"], "body": ["${1|##,###,####,#####,######|} ${2:Title}", "`bconstr~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: req", "", "$0"], "description": "OFT Business Constraint" }, "OpenFastTrace: Constraint": { - "prefix": ["oft-constraint", "oft-constr"], + "prefix": ["oft-constraint"], "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`constr~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: dsn", "", "$0"], "description": "OFT Technical Constraint" }, "OpenFastTrace: Design": { - "prefix": ["oft-design", "oft-dsn"], + "prefix": ["oft-design"], "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`dsn~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Covers:", "", "* `${4:covered-item}`", "", "Needs: impl, ${5|utest,itest,stest|}", "", "$0"], "description": "OFT Design" }, "OpenFastTrace: Feature": { - "prefix": ["oft-feature", "oft-feat"], + "prefix": ["oft-feature"], "body": ["${1|##,###,####,#####,######|} ${2:Title}", "`feat~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: req", "", "$0"], "description": "OFT Feature" }, "OpenFastTrace: Quality Goal": { - "prefix": ["oft-quality-goal", "oft-qg"], + "prefix": ["oft-quality-goal"], "body": ["${1|##,###,####,#####,######|} ${2:Title}", "`qg~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Rationale:", "", "${4:Rationale}", "", "Needs: qs", "", "$0"], "description": "OFT Quality Goal" }, "OpenFastTrace: Quality Scenario": { - "prefix": ["oft-quality-scenario", "oft-qs"], + "prefix": ["oft-quality-scenario"], "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`qs~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Covers:", "", "* `${4:covered-item}`", "", "Needs: dsn, ${5|utest,itest,stest|}", "", "$0"], "description": "OFT Quality Scenario" }, "OpenFastTrace: Requirement": { - "prefix": ["oft-requirement", "oft-req"], + "prefix": ["oft-requirement"], "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`req~${2/(.*)/${1:/kebabcase}/}~1`", "", "${3:Description}", "", "Covers:", "", "* [`${4:covered-item}`](#${5:markdown-link})", "", "Needs: req", "", "$0"], "description": "OFT High-Level Requirement" }, "OpenFastTrace: Scenario": { - "prefix": ["oft-scenario", "oft-scn"], + "prefix": ["oft-scenario"], "body": ["${1|###,####,#####,######,##|} ${2:Title}", "`scn~${2/(.*)/${1:/kebabcase}/}~1`", "", "**Given** ${3:the initial context}", "**When** ${4:an action occurs}", "**Then** ${5:the expected outcome occurs}", "", "Covers:", "- `${6:covered-item}`", "", "Needs: dsn", "", "$0"], "description": "OFT Scenario" } diff --git a/extension/snippets/openfasttrace-restructuredtext.code-snippets b/extension/snippets/openfasttrace-restructuredtext.code-snippets index c234126..4e6dbc8 100644 --- a/extension/snippets/openfasttrace-restructuredtext.code-snippets +++ b/extension/snippets/openfasttrace-restructuredtext.code-snippets @@ -1,47 +1,47 @@ // Based on https://github.com/itsallcode/openfasttrace-intellij-plugin/blob/main/src/main/resources/liveTemplates/OpenFastTrace.xml { "OpenFastTrace: Architecture": { - "prefix": ["oft-architecture", "oft-arch"], + "prefix": ["oft-architecture"], "body": ["${1:Title}", "${1/./=/g}", "", "``arch~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Comment:", "", "${3:Comment}", "", "Covers:", "", "* ``${4:covered-item}``", "", "Needs: dsn", "", "$0"], "description": "OFT Architectural Requirement" }, "OpenFastTrace: Business Constraint": { - "prefix": ["oft-business-constraint", "oft-bconstr"], + "prefix": ["oft-business-constraint"], "body": ["${1:Title}", "${1/./-/g}", "", "``bconstr~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: req", "", "$0"], "description": "OFT Business Constraint" }, "OpenFastTrace: Constraint": { - "prefix": ["oft-constraint", "oft-constr"], + "prefix": ["oft-constraint"], "body": ["${1:Title}", "${1/./=/g}", "", "``constr~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: dsn", "", "$0"], "description": "OFT Technical Constraint" }, "OpenFastTrace: Design": { - "prefix": ["oft-design", "oft-dsn"], + "prefix": ["oft-design"], "body": ["${1:Title}", "${1/./=/g}", "", "``dsn~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Covers:", "", "* ``${3:covered-item}``", "", "Needs: impl, ${4|utest,itest,stest|}", "", "$0"], "description": "OFT Design" }, "OpenFastTrace: Feature": { - "prefix": ["oft-feature", "oft-feat"], + "prefix": ["oft-feature"], "body": ["${1:Title}", "${1/./-/g}", "", "``feat~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: req", "", "$0"], "description": "OFT Feature" }, "OpenFastTrace: Quality Goal": { - "prefix": ["oft-quality-goal", "oft-qg"], + "prefix": ["oft-quality-goal"], "body": ["${1:Title}", "${1/./-/g}", "", "``qg~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Rationale:", "", "${3:Rationale}", "", "Needs: qs", "", "$0"], "description": "OFT Quality Goal" }, "OpenFastTrace: Quality Scenario": { - "prefix": ["oft-quality-scenario", "oft-qs"], + "prefix": ["oft-quality-scenario"], "body": ["${1:Title}", "${1/./=/g}", "", "``qs~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Covers:", "", "* ``${3:covered-item}``", "", "Needs: dsn, ${4|utest,itest,stest|}", "", "$0"], "description": "OFT Quality Scenario" }, "OpenFastTrace: Requirement": { - "prefix": ["oft-requirement", "oft-req"], + "prefix": ["oft-requirement"], "body": ["${1:Title}", "${1/./=/g}", "", "``req~${1/(.*)/${1:/kebabcase}/}~1``", "", "${2:Description}", "", "Covers:", "", "* ``${3:covered-item}``", "", "Needs: req", "", "$0"], "description": "OFT High-Level Requirement" }, "OpenFastTrace: Scenario": { - "prefix": ["oft-scenario", "oft-scn"], + "prefix": ["oft-scenario"], "body": ["${1:Title}", "${1/./=/g}", "", "``scn~${1/(.*)/${1:/kebabcase}/}~1``", "", "**Given** ${2:the initial context}", "**When** ${3:an action occurs}", "**Then** ${4:the expected outcome occurs}", "", "Covers:", "", "* ``${5:covered-item}``", "", "Needs: dsn", "", "$0"], "description": "OFT Scenario" } From 229f58de9382458a4200c5315f5f20b01c495f48 Mon Sep 17 00:00:00 2001 From: Christoph Pirkl Date: Wed, 5 Aug 2026 11:26:38 +0200 Subject: [PATCH 6/7] Fix duplicate tags for spec items --- doc/system_requirements.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/system_requirements.md b/doc/system_requirements.md index 75b75e5..5a85906 100644 --- a/doc/system_requirements.md +++ b/doc/system_requirements.md @@ -189,8 +189,6 @@ template includes a Given-When-Then skeleton and a covered-item placeholder. Tags: mvp -Tags: backlog - Covers: - `feat~author-oft-items-and-links~1` @@ -362,8 +360,6 @@ scenario Given-When-Then skeleton and Covers placeholder where applicable. Tags: mvp -Tags: backlog - Covers: - `req~insert-oft-templates~1` From 739e196a72decad417e07f0224744be160bb4680 Mon Sep 17 00:00:00 2001 From: Christoph Pirkl Date: Wed, 5 Aug 2026 11:29:50 +0200 Subject: [PATCH 7/7] Fix snippet file --- README.md | 2 ++ extension/snippets/openfasttrace-markdown.code-snippets | 1 - extension/snippets/openfasttrace-restructuredtext.code-snippets | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4e054a9..45ecd6b 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ Given-When-Then skeleton and a `Covers:` placeholder. To insert a snippet, type `oft-`, press `Ctrl+Space` to open the completion list (or wait for it to appear), then select the desired OpenFastTrace snippet. +Snippets are based on the [OFT IntelliJ plugin](https://github.com/itsallcode/openfasttrace-intellij-plugin/blob/main/src/main/resources/liveTemplates/OpenFastTrace.xml). + ## Requirements The extension requires Java 21 or later. It uses `openfasttrace.java.home` when diff --git a/extension/snippets/openfasttrace-markdown.code-snippets b/extension/snippets/openfasttrace-markdown.code-snippets index 0f63240..47ec377 100644 --- a/extension/snippets/openfasttrace-markdown.code-snippets +++ b/extension/snippets/openfasttrace-markdown.code-snippets @@ -1,4 +1,3 @@ -// Based on https://github.com/itsallcode/openfasttrace-intellij-plugin/blob/main/src/main/resources/liveTemplates/OpenFastTrace.xml { "OpenFastTrace: Architecture": { "prefix": ["oft-architecture"], diff --git a/extension/snippets/openfasttrace-restructuredtext.code-snippets b/extension/snippets/openfasttrace-restructuredtext.code-snippets index 4e6dbc8..38b99bb 100644 --- a/extension/snippets/openfasttrace-restructuredtext.code-snippets +++ b/extension/snippets/openfasttrace-restructuredtext.code-snippets @@ -1,4 +1,3 @@ -// Based on https://github.com/itsallcode/openfasttrace-intellij-plugin/blob/main/src/main/resources/liveTemplates/OpenFastTrace.xml { "OpenFastTrace: Architecture": { "prefix": ["oft-architecture"],