opencode-swarm 7.100.0 → 7.101.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/{evidence-summary-service-ch74hb16.js → evidence-summary-service-c4d1c2t3.js} +1 -1
- package/dist/cli/{guardrail-explain-q8pj9691.js → guardrail-explain-ma84cj3s.js} +3 -3
- package/dist/cli/{index-y3x3gvy6.js → index-bnkd9ejn.js} +279 -22
- package/dist/cli/{index-jg6m72g7.js → index-mz3j0me8.js} +3 -3
- package/dist/cli/{index-q5cae5d7.js → index-rmh6nqbp.js} +375 -51
- package/dist/cli/{index-tj0jek4p.js → index-wc8g49dp.js} +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/commands/sdd.d.ts +2 -0
- package/dist/git/branch.d.ts +16 -0
- package/dist/index.js +1823 -1239
- package/dist/lang/runtime.d.ts +3 -0
- package/dist/sdd/effective-spec.d.ts +204 -3
- package/package.json +1 -1
package/dist/lang/runtime.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
1
2
|
import type { Parser as ParserType } from 'web-tree-sitter';
|
|
2
3
|
export type Parser = ParserType;
|
|
3
4
|
/**
|
|
@@ -21,6 +22,8 @@ export declare const _internals: {
|
|
|
21
22
|
parserInit: (opts?: {
|
|
22
23
|
locateFile: (scriptName: string) => string;
|
|
23
24
|
}) => Promise<void>;
|
|
25
|
+
getModuleDir: () => string;
|
|
26
|
+
fileExists: typeof existsSync;
|
|
24
27
|
};
|
|
25
28
|
/**
|
|
26
29
|
* Pure path resolver for the grammars directory given a base directory.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type EffectiveSpecSource = 'swarm' | 'openspec_projection';
|
|
1
|
+
export type EffectiveSpecSource = 'swarm' | 'openspec_projection' | 'speckit_projection';
|
|
2
2
|
export interface OpenSpecArtifact {
|
|
3
3
|
relPath: string;
|
|
4
4
|
bytes: number;
|
|
@@ -29,17 +29,218 @@ export interface SddStatus {
|
|
|
29
29
|
errors: string[];
|
|
30
30
|
warnings: string[];
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
/** A single Spec-Kit feature directory containing a spec.md. */
|
|
33
|
+
export interface SpeckitFeatureEntry {
|
|
34
|
+
/** Full directory name, e.g. `001-feature-name`. */
|
|
35
|
+
featureId: string;
|
|
36
|
+
/** Posix-normalized path relative to the repo root, e.g. `specs/001-feature-name/spec.md`. */
|
|
37
|
+
specRelPath: string;
|
|
38
|
+
}
|
|
39
|
+
/** Result returned by {@link detectSpeckit}. */
|
|
40
|
+
export interface SpeckitDetection {
|
|
41
|
+
/** Whether the `.specify/` marker directory is present at the repo root (A-001). */
|
|
42
|
+
markerPresent: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Detected feature directories, sorted lexicographically by {@link SpeckitFeatureEntry.featureId}.
|
|
45
|
+
* Empty when no `specs/<feature>/spec.md` files are found (or when markerPresent is false).
|
|
46
|
+
*/
|
|
47
|
+
features: SpeckitFeatureEntry[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Discriminated union returned by {@link resolveSpeckitProjection} (task 1.4).
|
|
51
|
+
*
|
|
52
|
+
* Each kind carries exactly the information the command layer (task 2.2) needs to
|
|
53
|
+
* produce the correct error message per FR-008, FR-012, FR-013 without re-detecting.
|
|
54
|
+
*
|
|
55
|
+
* - `not_speckit` — no `.specify/` marker at the repo root (A-001).
|
|
56
|
+
* - `empty` — marker present but no `specs/NNN/spec.md` feature dirs (FR-012).
|
|
57
|
+
* - `ambiguous` — more than one feature and no `options.feature` given (FR-008);
|
|
58
|
+
* `features` = sorted feature ids for naming in the error message.
|
|
59
|
+
* - `unknown_feature` — `options.feature` was given but matches no detected feature.
|
|
60
|
+
* - `zero_requirements`— the selected feature's spec.md yielded zero parsable functional
|
|
61
|
+
* requirements (covers unreadable/oversized *input* files too) (FR-013).
|
|
62
|
+
* - `too_large` — requirements parsed, but the projected *output* exceeds the byte
|
|
63
|
+
* cap and is refused; `bytes` is the projected size. Distinct from
|
|
64
|
+
* zero_requirements so the command layer reports the real reason.
|
|
65
|
+
* - `ok` — a valid projection was built; `spec` is ready for use, `feature`
|
|
66
|
+
* identifies the projected feature dir name.
|
|
67
|
+
*/
|
|
68
|
+
export type SpeckitResolution = {
|
|
69
|
+
kind: 'not_speckit';
|
|
70
|
+
} | {
|
|
71
|
+
kind: 'empty';
|
|
72
|
+
} | {
|
|
73
|
+
kind: 'ambiguous';
|
|
74
|
+
features: string[];
|
|
75
|
+
} | {
|
|
76
|
+
kind: 'unknown_feature';
|
|
77
|
+
feature: string;
|
|
78
|
+
available: string[];
|
|
79
|
+
} | {
|
|
80
|
+
kind: 'zero_requirements';
|
|
81
|
+
feature: string;
|
|
82
|
+
} | {
|
|
83
|
+
kind: 'too_large';
|
|
84
|
+
feature: string;
|
|
85
|
+
bytes: number;
|
|
86
|
+
} | {
|
|
87
|
+
kind: 'ok';
|
|
88
|
+
spec: EffectiveSpec;
|
|
89
|
+
feature: string;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Detect whether `directory` is a GitHub Spec-Kit project (FR-001, A-001).
|
|
93
|
+
*
|
|
94
|
+
* Detection key: the `.specify/` marker directory at the repo root.
|
|
95
|
+
* A repo with `specs/` but no `.specify/` is NOT a Spec-Kit repo (A-001).
|
|
96
|
+
*
|
|
97
|
+
* When the marker is present, enumerates all direct children of `specs/` that
|
|
98
|
+
* contain a `spec.md` file. The enumeration is:
|
|
99
|
+
* - One level deep (depth is bounded by construction — stronger than MAX_WALK_DEPTH).
|
|
100
|
+
* - Bounded by MAX_SPEC_FILES.
|
|
101
|
+
* - Symlink-safe: directories and spec.md files that are symlinks are skipped.
|
|
102
|
+
* - Size-bounded: spec.md files exceeding MAX_SOURCE_BYTES are skipped.
|
|
103
|
+
* - Error-swallowing: unreadable directories are skipped silently.
|
|
104
|
+
* - Deterministic: feature entries are sorted lexicographically by featureId.
|
|
105
|
+
*
|
|
106
|
+
* Does NOT read or parse spec.md content — detection only (FR-001).
|
|
107
|
+
*/
|
|
108
|
+
export declare function detectSpeckit(directory: string): SpeckitDetection;
|
|
109
|
+
/**
|
|
110
|
+
* Resolve a Spec-Kit feature projection with a discriminated result (FR-008, FR-012, FR-013).
|
|
111
|
+
*
|
|
112
|
+
* Returns one of six kinds so the command layer can produce the right error message without
|
|
113
|
+
* re-running detection:
|
|
114
|
+
* - `not_speckit` — no `.specify/` marker (A-001).
|
|
115
|
+
* - `empty` — marker present but no feature dirs (FR-012).
|
|
116
|
+
* - `ambiguous` — multiple features, no `options.feature` (FR-008).
|
|
117
|
+
* - `unknown_feature` — `options.feature` not among detected features.
|
|
118
|
+
* - `zero_requirements` — feature found but yields zero parsable FRs, or spec.md unreadable
|
|
119
|
+
* (FR-013; covers oversized files too).
|
|
120
|
+
* - `ok` — valid EffectiveSpec built (FR-002, FR-003, FR-004, FR-005).
|
|
121
|
+
*
|
|
122
|
+
* This function is the single source of truth for feature selection logic.
|
|
123
|
+
* {@link buildSpeckitProjectionSync} delegates here and maps `ok → spec | null`.
|
|
124
|
+
*/
|
|
125
|
+
export declare function resolveSpeckitProjection(directory: string, options?: {
|
|
126
|
+
feature?: string;
|
|
127
|
+
}): SpeckitResolution;
|
|
128
|
+
/**
|
|
129
|
+
* Project a single Spec-Kit feature into an EffectiveSpec (FR-002, FR-003, FR-004, FR-005).
|
|
130
|
+
*
|
|
131
|
+
* Delegates all selection and build logic to {@link resolveSpeckitProjection} — that function
|
|
132
|
+
* is the single source of truth for feature selection. This wrapper preserves the existing
|
|
133
|
+
* `EffectiveSpec | null` contract so all call sites (task 2.2, tests) are unchanged.
|
|
134
|
+
*
|
|
135
|
+
* Returns null when resolution is anything other than `ok` (not_speckit, empty, ambiguous,
|
|
136
|
+
* unknown_feature, zero_requirements). Callers that need the failure reason should call
|
|
137
|
+
* {@link resolveSpeckitProjection} directly.
|
|
138
|
+
*/
|
|
139
|
+
export declare function buildSpeckitProjectionSync(directory: string, options?: {
|
|
140
|
+
feature?: string;
|
|
141
|
+
}): EffectiveSpec | null;
|
|
142
|
+
export declare function loadSddStatusSync(directory: string, opts?: ReadEffectiveSpecOpts): SddStatus;
|
|
33
143
|
export declare function buildOpenSpecProjectionSync(directory: string, options?: {
|
|
34
144
|
changeId?: string;
|
|
35
145
|
}): EffectiveSpec | null;
|
|
36
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Resolver options for {@link readEffectiveSpecSync} (task 2.1, FR-009).
|
|
148
|
+
*
|
|
149
|
+
* Both fields are optional so that all 13 existing single-argument call sites
|
|
150
|
+
* continue to work unchanged.
|
|
151
|
+
*/
|
|
152
|
+
export interface ReadEffectiveSpecOpts {
|
|
153
|
+
/**
|
|
154
|
+
* Explicit provider selection (FR-009 step b).
|
|
155
|
+
* When given, the specified provider is used directly after the native swarm
|
|
156
|
+
* spec check. A `'swarm'` selection with no `.swarm/spec.md` returns null.
|
|
157
|
+
*/
|
|
158
|
+
source?: 'swarm' | 'openspec' | 'speckit';
|
|
159
|
+
/**
|
|
160
|
+
* Feature selector forwarded to {@link buildSpeckitProjectionSync} when the
|
|
161
|
+
* effective provider is Spec-Kit. Ignored for `source: 'openspec'` or
|
|
162
|
+
* `source: 'swarm'` (feature-vs-non-speckit source validation is enforced at
|
|
163
|
+
* the command layer in task 2.2, not here).
|
|
164
|
+
*/
|
|
165
|
+
feature?: string;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Read (or build) the effective spec for a directory, applying deterministic
|
|
169
|
+
* source precedence (FR-009, FR-010, FR-011).
|
|
170
|
+
*
|
|
171
|
+
* **Precedence:**
|
|
172
|
+
* a. `.swarm/spec.md` present → return the native swarm spec. This branch is
|
|
173
|
+
* IDENTICAL to the pre-task-2.1 code and wins even over an explicit
|
|
174
|
+
* `opts.source` — native swarm spec always wins (FR-009).
|
|
175
|
+
* b. `opts.source` given → use that provider: `'openspec'` calls
|
|
176
|
+
* {@link buildOpenSpecProjectionSync}; `'speckit'` calls
|
|
177
|
+
* {@link buildSpeckitProjectionSync}; `'swarm'` with no `.swarm/spec.md`
|
|
178
|
+
* returns null.
|
|
179
|
+
* c. Auto-detect:
|
|
180
|
+
* - **No `.specify/` marker** → byte-identical to pre-task-2.1 behavior:
|
|
181
|
+
* call {@link buildOpenSpecProjectionSync} and return its result (FR-011).
|
|
182
|
+
* - **`.specify/` present but no feature dirs** (empty marker) → Spec-Kit is
|
|
183
|
+
* NOT counted as a competing source; behaves like the no-marker case.
|
|
184
|
+
* - **`.specify/` with ≥1 feature dir and no openspec projection** → return
|
|
185
|
+
* the Spec-Kit projection.
|
|
186
|
+
* - **`.specify/` with ≥1 feature dir AND openspec yields a projection** →
|
|
187
|
+
* AMBIGUOUS (FR-010): emit a concrete diagnostic via `console.warn` (the
|
|
188
|
+
* anti-silent-suppression requirement; critic Finding 2) and return null.
|
|
189
|
+
* The diagnostic is independent of the return value so it fires even when
|
|
190
|
+
* no consumer inspects the null return (e.g. the drift gate, which only
|
|
191
|
+
* checks for null to decide advisory-vs-blocking mode).
|
|
192
|
+
*
|
|
193
|
+
* **Backward-compat (FR-011):** when `.detectSpeckit(directory).markerPresent`
|
|
194
|
+
* is false, the function is byte-identical to pre-task-2.1. The additional
|
|
195
|
+
* `detectSpeckit` call (a single `fs.existsSync`) is the only overhead.
|
|
196
|
+
*
|
|
197
|
+
* **Deviation from task-2.1 literal text:** the task body says "Spec-Kit
|
|
198
|
+
* present (`detectSpeckit(dir).markerPresent`)" but plan.md task 3.1 and the
|
|
199
|
+
* test note both state that an empty `.specify/` "would never reach the
|
|
200
|
+
* ambiguity branch." `markerPresent` is true for empty-specify, so it cannot
|
|
201
|
+
* be the discriminator. We use `features.length > 0` instead, which is
|
|
202
|
+
* symmetric with "OpenSpec present (yields a projection)" and makes empty
|
|
203
|
+
* `.specify/` a non-competing source, matching both citations.
|
|
204
|
+
*/
|
|
205
|
+
export declare function readEffectiveSpecSync(directory: string, opts?: ReadEffectiveSpecOpts): EffectiveSpec | null;
|
|
37
206
|
export declare function writeProjectedSpecSync(directory: string, options?: {
|
|
38
207
|
changeId?: string;
|
|
39
208
|
dryRun?: boolean;
|
|
209
|
+
/** When `'speckit'`, builds a Spec-Kit projection instead of OpenSpec (task 2.2). */
|
|
210
|
+
source?: 'openspec' | 'speckit';
|
|
211
|
+
/** Feature selector forwarded to buildSpeckitProjectionSync when source is speckit. */
|
|
212
|
+
feature?: string;
|
|
40
213
|
}): {
|
|
41
214
|
written: boolean;
|
|
42
215
|
projection: EffectiveSpec | null;
|
|
43
216
|
archivePath?: string;
|
|
44
217
|
path: string;
|
|
45
218
|
};
|
|
219
|
+
/**
|
|
220
|
+
* Validate Spec-Kit artifacts READ-ONLY (FR-007, task 2.3).
|
|
221
|
+
*
|
|
222
|
+
* MUST NOT write or modify any Spec-Kit artifact — it only reads spec.md and
|
|
223
|
+
* tasks.md to report structural problems.
|
|
224
|
+
*
|
|
225
|
+
* Returns the {@link SpeckitResolution} from {@link resolveSpeckitProjection}
|
|
226
|
+
* alongside a flat `problems` array. Returning both avoids a second
|
|
227
|
+
* `resolveSpeckitProjection` call in the command layer (which would need the
|
|
228
|
+
* projection's hash / sourcePaths from `resolution.spec`).
|
|
229
|
+
*
|
|
230
|
+
* **Problems reported** (only when `resolution.kind` is `'ok'` or
|
|
231
|
+
* `'zero_requirements'` — i.e. when we have a feature to inspect):
|
|
232
|
+
* - Zero parsable functional requirements (`zero_requirements` kind, FR-013).
|
|
233
|
+
* - Missing required spec.md sections (`SPECKIT_REQUIRED_SECTIONS`).
|
|
234
|
+
* - `tasks.md` task lines that carry no `[US#]` user-story reference (FR-007).
|
|
235
|
+
*
|
|
236
|
+
* For other resolution kinds (`not_speckit`, `empty`, `ambiguous`,
|
|
237
|
+
* `unknown_feature`, `too_large`) the command layer uses
|
|
238
|
+
* {@link formatSpeckitError} on the returned resolution — same messaging path
|
|
239
|
+
* as task 2.2 (plan.md task 2.3 requirement: no second messaging scheme).
|
|
240
|
+
*/
|
|
241
|
+
export declare function validateSpeckit(directory: string, options?: {
|
|
242
|
+
feature?: string;
|
|
243
|
+
}): {
|
|
244
|
+
resolution: SpeckitResolution;
|
|
245
|
+
problems: string[];
|
|
246
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.101.0",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|