Skip to content

fix(openspec): refresh against new v1.x workflow modules#1047

Open
pedramamini wants to merge 2 commits into
mainfrom
fix/1046-openspec-refresh-v1-format
Open

fix(openspec): refresh against new v1.x workflow modules#1047
pedramamini wants to merge 2 commits into
mainfrom
fix/1046-openspec-refresh-v1-format

Conversation

@pedramamini
Copy link
Copy Markdown
Collaborator

@pedramamini pedramamini commented May 26, 2026

Summary

  • OpenSpec restructured around v1.0: the monolithic openspec/AGENTS.md is gone and per-workflow prompts now live in TypeScript modules under src/core/templates/workflows/ (new-change.ts, apply-change.ts, archive-change.ts), each exposing an instructions template literal.
  • Rewrite refreshOpenSpecPrompts (and the standalone scripts/refresh-openspec.mjs) to fetch those three files and extract the template-literal body, unescaping the only escape upstream uses (\\\`` → `` ``).
  • Re-bundle the v1.3.1 prompts via the refreshed script so fresh installs ship up-to-date defaults instead of the v0.19.0 snapshot they had been pinned to since [Bug] OpenSpec commands not updating #178.
  • Update the manager and IPC handler tests to mock the new four-call fetch shape.

Closes #1046

Test plan

  • npm run lint (after npm run build:prompts) — clean
  • npm run lint:eslint — clean
  • npx vitest run src/__tests__/main/openspec-manager.test.ts src/__tests__/main/ipc/handlers/openspec.test.ts — 36/36 pass
  • node scripts/refresh-openspec.mjs against current upstream — pulls v1.3.1 and writes the three workflow prompts
  • Manual smoke: open Settings → AI Commands → OpenSpec, click "Check for Updates", confirm version flips from 0.19.0 to 1.3.1 and the three prompts now show the v1.x artifact-driven workflow text

Summary by CodeRabbit

  • Documentation

    • Significantly enhanced OpenSpec workflow prompts with comprehensive step-by-step guidance for proposal creation, implementing changes, and archiving workflows, including detailed status checks, confirmation flows, and structured output templates.
  • Chores

    • Updated OpenSpec refresh mechanism and metadata with latest version information.

Review Change Stack

pedramamini and others added 2 commits May 26, 2026 06:23
OpenSpec restructured its repo around v1.0: workflow prompts moved out
of the monolithic openspec/AGENTS.md (which is now empty at the repo
root) into per-workflow TypeScript modules under
src/core/templates/workflows/. The old refresh logic still pointed at
openspec/AGENTS.md, so every "Check for Updates" 404'd and left users
pinned to bundled v0.19.0 prompts.

- Rewrite refreshOpenSpecPrompts and the refresh-openspec script to
  fetch new-change.ts / apply-change.ts / archive-change.ts and extract
  the `instructions` template literal from each.
- Re-bundle the v1.3.1 prompts so fresh installs ship up-to-date
  defaults instead of v0.19.0.
- Update tests for the new fetch shape.

Closes #1046
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

📝 Walkthrough

Walkthrough

This PR updates the OpenSpec prompt refresh mechanism to fetch per-workflow TypeScript modules from the upstream repository and extract their instructions template literals, replacing the prior AGENTS.md parsing. Version is bumped from v0.19.0 to v1.3.1. All three stage prompts (proposal, apply, archive) are rewritten with detailed step-by-step workflows and guardrails.

Changes

OpenSpec TS Module Extraction and Prompts

Layer / File(s) Summary
Workflow TS Extraction Mechanism
scripts/refresh-openspec.mjs, src/main/openspec-manager.ts, src/prompts/openspec/index.ts, src/prompts/openspec/metadata.json
New UPSTREAM_WORKFLOWS mapping and extractInstructions() helper parse instructions: \...`from fetched TypeScript modules.getLatestRef()resolves the latest upstream release via GitHub API (falls back tomain). refreshOpenSpec()andrefreshOpenSpecPrompts()` now fetch raw workflow modules, extract instructions, write prompts only on diff, and update metadata with resolved version/timestamp/commit SHA.
Test Coverage for Extraction Flow
src/__tests__/main/openspec-manager.test.ts, src/__tests__/main/ipc/handlers/openspec.test.ts
Added buildWorkflowTs() helper to generate minimal upstream workflow stubs. Mock fetch sequences return workflow TS payloads for release/proposal/apply/archive. Assertions verify upstream URLs fetched and extracted instruction text matches. Failure cases cover release lookup failure cascading to all workflow fetch failures. IPC handler test expects updated error message referencing v1.3.1.
Proposal, Apply, and Archive Prompt Updates
src/prompts/openspec/openspec.proposal.md, src/prompts/openspec/openspec.apply.md, src/prompts/openspec/openspec.archive.md
Proposal workflow: asks for change name, conditionally selects schema, scaffolds change, checks artifact readiness, fetches first-artifact instructions, outputs readiness summary. Apply workflow: selects/infers change, checks schema/status, fetches dynamic instructions, reads context files, iterates tasks with checkbox updates, pauses on clarity/design/error conditions, outputs progress/completion/pause summaries. Archive workflow: selects change, checks artifact and task completion with user confirmation, assesses delta-spec sync state, optionally syncs specs, moves to dated archive directory, outputs success summary.

Sequence Diagram(s)

sequenceDiagram
  participant RefreshScript as refresh-openspec.mjs
  participant GitHubAPI as GitHub API
  participant RawGitHub as Raw GitHub Content
  participant FSWrite as Filesystem
  participant ManagerTs as openspec-manager.ts
  RefreshScript->>GitHubAPI: Fetch latest release tag
  GitHubAPI-->>RefreshScript: Return v1.3.1 or fallback to main
  RefreshScript->>RawGitHub: Fetch proposal.ts, apply.ts, archive.ts
  RawGitHub-->>RefreshScript: Return TypeScript module content
  RefreshScript->>RefreshScript: Extract instructions: `...` from each TS
  RefreshScript->>FSWrite: Write openspec.proposal.md, openspec.apply.md, openspec.archive.md
  RefreshScript->>FSWrite: Write metadata.json with v1.3.1, lastRefreshed, commitSha
  ManagerTs->>RawGitHub: Fetch workflow modules via same flow
  ManagerTs->>ManagerTs: extractInstructions() and regex match
  ManagerTs->>FSWrite: Write user prompt files with extracted content
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • RunMaestro/Maestro#820: Both PRs modify refreshOpenSpecPrompts() in src/main/openspec-manager.ts, but this PR replaces the old AGENTS.md section-parsing logic with per-workflow TS instructions extraction, while the retrieved PR mainly refactors surrounding command-management/customization plumbing while keeping the AGENTS.md flow.

Suggested labels

ready to merge

Poem

🐰 From AGENTS old to templates new,
We fetch each workflow's promised view—
TypeScript instructions lit the way,
v1.3.1 saves the day!
Three stages bloom with step-by-step grace,
The rabbit's den finds a better place! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly identifies the main change: updating the OpenSpec refresh logic to work with new v1.x TypeScript workflow modules instead of the deprecated AGENTS.md format.
Linked Issues check ✅ Passed The PR successfully addresses #1046 by updating refresh logic to fetch v1.3.1 workflow TypeScript modules, implementing the per-workflow prompt extraction mechanism, and re-bundling the prompts for fresh installs.
Out of Scope Changes check ✅ Passed All changes directly support the OpenSpec refresh mechanism migration: script updates, test adjustments, prompt file rewrites, metadata updates, and documentation corrections are all aligned with the v1.x workflow module transition.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1046-openspec-refresh-v1-format

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 26, 2026

Greptile Summary

This PR adapts the OpenSpec prompt-refresh mechanism from parsing a single monolithic AGENTS.md to fetching three per-workflow TypeScript modules and extracting their instructions template-literal bodies, then re-bundles the v1.3.1 prompts as the new shipped defaults.

  • New fetch strategy: refreshOpenSpecPrompts (and the standalone scripts/refresh-openspec.mjs) now hit the GitHub releases API for the latest tag, then fetch new-change.ts, apply-change.ts, and archive-change.ts from src/core/templates/workflows/; a regex extracts the template-literal body and unescapes backslash sequences (primarily \`` for inline-code spans in the prompts).
  • Bundled prompt refresh: All three .md files are replaced with the v1.3.1 artifact-driven workflow text, and metadata.json is bumped accordingly.
  • Test updates: openspec-manager.test.ts now stubs four fetch calls (release + three TS files), asserts the constructed URLs, and validates the backtick-escape round-trip via buildWorkflowTs.

Confidence Score: 4/5

Safe to merge; the new fetch strategy, regex extraction, and unescape logic are all correct and well-tested.

The core rewrite is clean: the regex correctly handles multi-line template literals and backtick escapes, the four-call fetch shape is tested end-to-end including URL assertions, and the bundled v1.3.1 prompts match what the script produces. The noted issues are both in partial-failure handling — the .mjs script can exit 0 and write versioned metadata when one prompt was unchanged and others failed, and the runtime manager logs no warning before returning when fewer than all three prompts were written — neither affects the normal happy path.

scripts/refresh-openspec.mjs — the exit condition for total failure is slightly too permissive; src/main/openspec-manager.ts — partial-update failures are silently swallowed before returning metadata.

Important Files Changed

Filename Overview
scripts/refresh-openspec.mjs Rewrites fetch logic from AGENTS.md parsing to per-workflow TS module fetching; exit condition for total failure is slightly too permissive in the "unchanged + partial-failure" edge case.
src/main/openspec-manager.ts Core refresh logic cleanly replaced; regex extraction and unescape are correct; metadata is written even on partial fetch failures, which could show a misleading version in the UI.
src/tests/main/openspec-manager.test.ts Tests updated to four-call fetch shape, backtick-escape round-trip tested, URL path assertions added — good coverage of the new fetch strategy.
src/tests/main/ipc/handlers/openspec.test.ts Error message updated to match new throw text; change is minimal and correct.
src/prompts/openspec/metadata.json Bumped to v1.3.1 with a refreshed timestamp; straightforward data update.

Sequence Diagram

sequenceDiagram
    participant U as User / CI
    participant M as openspec-manager.ts
    participant GH as GitHub API
    participant FS as Filesystem

    U->>M: refreshOpenSpecPrompts()
    M->>GH: GET /repos/Fission-AI/OpenSpec/releases/latest
    GH-->>M: "{ tag_name: "v1.3.1" }"
    loop for each workflow (new-change, apply-change, archive-change)
        M->>GH: "GET raw.githubusercontent.com/.../v1.3.1/src/core/templates/workflows/<file>.ts"
        GH-->>M: TypeScript source
        M->>M: extractInstructions() — regex + unescape
        M->>FS: "writeFile openspec.<cmdId>.md"
    end
    M->>FS: "writeFile metadata.json (version=v1.3.1)"
    M-->>U: OpenSpecMetadata
Loading

Reviews (1): Last reviewed commit: "add image" | Re-trigger Greptile

Comment on lines +146 to +149
if (updatedCount === 0 && failures.length === Object.keys(UPSTREAM_WORKFLOWS).length) {
console.error('❌ Failed to fetch any workflow prompts');
process.exit(1);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Exit condition misses the "unchanged + partial-failure" edge case

The updatedCount === 0 && failures.length === all guard won't trigger process.exit(1) when one workflow file happens to be unchanged (content matches what's already on disk, so updatedCount is never incremented) while the other two fail to fetch. In that scenario updatedCount = 0 and failures.length = 2 < 3, so the condition is false, the script exits 0, and metadata.json is written claiming the full new version even though 2/3 prompts weren't refreshed. The manager.ts counterpart avoids this because it always writes unconditionally (making updatedCount >= 1 for any successful extraction), but the .mjs script can silently produce a misleadingly-versioned metadata file when run as a CI/release step.

Comment on lines +391 to 397
if (updatedCount === 0) {
throw new Error(
`Failed to fetch any OpenSpec workflow prompts from ${version}: ${failures.join(', ')}`
);
}

// Update metadata with new version info
const newMetadata: OpenSpecMetadata = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Metadata is written even when some prompts failed to update

When updatedCount > 0 (at least one prompt was written) but one or more fetches failed, the function proceeds to write metadata.json with the full version tag. A user would see e.g. 1.3.1 in the UI but still be served the bundled (older) defaults for any command whose fetch failed. Consider logging the list of failed filenames at warn-level before returning so callers can surface the partial state.

Suggested change
if (updatedCount === 0) {
throw new Error(
`Failed to fetch any OpenSpec workflow prompts from ${version}: ${failures.join(', ')}`
);
}
// Update metadata with new version info
const newMetadata: OpenSpecMetadata = {
if (updatedCount === 0) {
throw new Error(
`Failed to fetch any OpenSpec workflow prompts from ${version}: ${failures.join(', ')}`
);
}
if (failures.length > 0) {
logger.warn(
`Partially refreshed OpenSpec prompts from ${version}: failed to fetch ${failures.join(', ')}`,
LOG_CONTEXT
);
}
const newMetadata: OpenSpecMetadata = {

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/__tests__/main/openspec-manager.test.ts (1)

704-759: ⚡ Quick win

Add a test for rejected workflow fetch (not just non-OK responses)

Current failure tests cover 404-style responses, but not fetch() promise rejection for a workflow file. Adding that case will lock in partial-failure behavior and prevent regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/main/openspec-manager.test.ts` around lines 704 - 759, Add a
new test case for a rejected workflow fetch by using stubFetch to return a
rejected Error for one of the workflow fetch calls (not just non-ok responses),
call refreshOpenSpecPrompts(), and assert it still uses 'main' as
commitSha/sourceVersion, writes the proposal file, does not write the missing
workflow file, and emits logger.warn for the rejected workflow (matching the
error message and '[OpenSpec]'); reference the existing test pattern and
functions stubFetch and refreshOpenSpecPrompts and the logger.warn expectations
to mirror the "missing workflows" test but with one fetch returning new
Error('network down') instead of an ok:false response.
scripts/refresh-openspec.mjs (1)

78-80: ⚡ Quick win

Narrow unescaping to backticks only

extractInstructions() currently uses replace(/\\([\s\S])/g, '$1') (line 80), which strips the backslash from any escape sequence. The file comment states upstream only uses backslash-escaping for inline-code backticks (```), so narrow the logic to backticks to match intent and avoid unintended future escape corruption.

Proposed fix
 function extractInstructions(tsContent) {
 	const match = tsContent.match(/instructions:\s*`((?:\\[\s\S]|[^`\\])*)`/);
 	if (!match) return null;
-	return match[1].replace(/\\([\s\S])/g, '$1');
+	return match[1].replace(/\\`/g, '`');
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/refresh-openspec.mjs` around lines 78 - 80, The unescape in
extractInstructions() is too broad—replace(/\\([\s\S])/g, '$1') removes
backslashes from any escape sequence; change it to only unescape backticked
inline-code escapes by replacing backslash-backtick sequences (e.g., use a regex
that targets `\\\``) so the post-match replacement on the capture from
tsContent.match(/instructions:\s*`((?:\\[\s\S]|[^`\\])*)`/) only strips
backslash from escaped backticks and leaves other escapes intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/openspec-manager.ts`:
- Around line 370-377: The loop in refreshOpenSpecPrompts currently calls
fetch(url) without a try/catch so any network rejection will throw and abort the
whole refresh; wrap the per-workflow fetch and response handling for each entry
(the code iterating over UPSTREAM_WORKFLOWS and using url, response, failures,
logger.warn) in a try/catch, on error push the filename into failures and call
logger.warn and Sentry.captureException/captureMessage with context (include
cmdId, filename and url), then continue to the next item; keep the existing
non-OK response handling unchanged but move it inside the try block so both HTTP
errors and network rejections are handled similarly.

In `@src/prompts/openspec/openspec.apply.md`:
- Line 83: Three fenced code blocks around the headings "Implementing:
<change-name> (schema: <schema-name>)", "Implementation Complete", and
"Implementation Paused" are missing language identifiers and trigger MD040;
update each opening triple-backtick to include a language (e.g., add "text") so
the fences read ```text for those three blocks in
src/prompts/openspec/openspec.apply.md.

In `@src/prompts/openspec/openspec.archive.md`:
- Around line 86-95: The fenced code block containing the "## Archive Complete"
section is missing a language tag which triggers markdownlint MD040; update the
opening fence from ``` to ```md so the block becomes a Markdown-highlighted
block (target the fenced block that starts with "## Archive Complete" and the
surrounding triple backticks in openspec.archive.md).

---

Nitpick comments:
In `@scripts/refresh-openspec.mjs`:
- Around line 78-80: The unescape in extractInstructions() is too
broad—replace(/\\([\s\S])/g, '$1') removes backslashes from any escape sequence;
change it to only unescape backticked inline-code escapes by replacing
backslash-backtick sequences (e.g., use a regex that targets `\\\``) so the
post-match replacement on the capture from
tsContent.match(/instructions:\s*`((?:\\[\s\S]|[^`\\])*)`/) only strips
backslash from escaped backticks and leaves other escapes intact.

In `@src/__tests__/main/openspec-manager.test.ts`:
- Around line 704-759: Add a new test case for a rejected workflow fetch by
using stubFetch to return a rejected Error for one of the workflow fetch calls
(not just non-ok responses), call refreshOpenSpecPrompts(), and assert it still
uses 'main' as commitSha/sourceVersion, writes the proposal file, does not write
the missing workflow file, and emits logger.warn for the rejected workflow
(matching the error message and '[OpenSpec]'); reference the existing test
pattern and functions stubFetch and refreshOpenSpecPrompts and the logger.warn
expectations to mirror the "missing workflows" test but with one fetch returning
new Error('network down') instead of an ok:false response.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 166ab025-3c3e-4ca1-ba5f-f1296c9dde9f

📥 Commits

Reviewing files that changed from the base of the PR and between 655a089 and 7457e8e.

⛔ Files ignored due to path filters (1)
  • assets/logo.png is excluded by !**/*.png
📒 Files selected for processing (9)
  • scripts/refresh-openspec.mjs
  • src/__tests__/main/ipc/handlers/openspec.test.ts
  • src/__tests__/main/openspec-manager.test.ts
  • src/main/openspec-manager.ts
  • src/prompts/openspec/index.ts
  • src/prompts/openspec/metadata.json
  • src/prompts/openspec/openspec.apply.md
  • src/prompts/openspec/openspec.archive.md
  • src/prompts/openspec/openspec.proposal.md

Comment on lines +370 to +377
for (const [cmdId, filename] of Object.entries(UPSTREAM_WORKFLOWS)) {
const url = `https://raw.githubusercontent.com/Fission-AI/OpenSpec/${version}/src/core/templates/workflows/${filename}`;
const response = await fetch(url);
if (!response.ok) {
failures.push(`${filename} (${response.status})`);
logger.warn(`Failed to fetch ${filename}: ${response.statusText}`, LOG_CONTEXT);
continue;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify there is no per-item try/catch around workflow fetch calls in refreshOpenSpecPrompts.
set -euo pipefail
rg -n -C3 'for \(const \[cmdId, filename\] of Object\.entries\(UPSTREAM_WORKFLOWS\)\)|await fetch\(url\)' src/main/openspec-manager.ts

Repository: RunMaestro/Maestro

Length of output: 545


Handle per-workflow fetch rejections in refreshOpenSpecPrompts
The loop only handles HTTP non-OK responses; a network-level fetch(url) rejection will throw and abort the whole refresh instead of continuing to the next workflow entry.

Proposed fix
 	for (const [cmdId, filename] of Object.entries(UPSTREAM_WORKFLOWS)) {
 		const url = `https://raw.githubusercontent.com/Fission-AI/OpenSpec/${version}/src/core/templates/workflows/${filename}`;
-		const response = await fetch(url);
+		let response: Response;
+		try {
+			response = await fetch(url);
+		} catch (error) {
+			failures.push(`${filename} (network error)`);
+			logger.warn(`Failed to fetch ${filename}: ${String(error)}`, LOG_CONTEXT);
+			continue;
+		}
 		if (!response.ok) {
 			failures.push(`${filename} (${response.status})`);
 			logger.warn(`Failed to fetch ${filename}: ${response.statusText}`, LOG_CONTEXT);
 			continue;
 		}

Also ensure caught errors are reported with Sentry utilities (captureException/captureMessage) with enough context.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/openspec-manager.ts` around lines 370 - 377, The loop in
refreshOpenSpecPrompts currently calls fetch(url) without a try/catch so any
network rejection will throw and abort the whole refresh; wrap the per-workflow
fetch and response handling for each entry (the code iterating over
UPSTREAM_WORKFLOWS and using url, response, failures, logger.warn) in a
try/catch, on error push the filename into failures and call logger.warn and
Sentry.captureException/captureMessage with context (include cmdId, filename and
url), then continue to the next item; keep the existing non-OK response handling
unchanged but move it inside the try block so both HTTP errors and network
rejections are handled similarly.


**Output During Implementation**

```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language identifiers to fenced code blocks

Lines 83, 97, and 114 trigger MD040. Please specify a language (e.g., text) for each fenced block.

Proposed fix
-```
+```text
 ## Implementing: <change-name> (schema: <schema-name>)
@@
-```
+```text
 ## Implementation Complete
@@
-```
+```text
 ## Implementation Paused

Also applies to: 97-97, 114-114

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 83-83: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/prompts/openspec/openspec.apply.md` at line 83, Three fenced code blocks
around the headings "Implementing: <change-name> (schema: <schema-name>)",
"Implementation Complete", and "Implementation Paused" are missing language
identifiers and trigger MD040; update each opening triple-backtick to include a
language (e.g., add "text") so the fences read ```text for those three blocks in
src/prompts/openspec/openspec.apply.md.

Comment on lines +86 to +95
```
## Archive Complete

**Change:** <change-name>
**Schema:** <schema-name>
**Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
**Specs:** ✓ Synced to main specs (or "No delta specs" or "Sync skipped")

All artifacts complete. All tasks complete.
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language identifier to the fenced output block.

The fenced block at Line 86 is missing a language tag, which triggers markdownlint MD040.

Proposed fix
-```
+```md
 ## Archive Complete
 
 **Change:** <change-name>
 **Schema:** <schema-name>
 **Archived to:** openspec/changes/archive/YYYY-MM-DD-<name>/
 **Specs:** ✓ Synced to main specs (or "No delta specs" or "Sync skipped")
 
 All artifacts complete. All tasks complete.
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 86-86: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/prompts/openspec/openspec.archive.md` around lines 86 - 95, The fenced
code block containing the "## Archive Complete" section is missing a language
tag which triggers markdownlint MD040; update the opening fence from ``` to
```md so the block becomes a Markdown-highlighted block (target the fenced block
that starts with "## Archive Complete" and the surrounding triple backticks in
openspec.archive.md).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] OpenSpec commands not updating

1 participant