@bastani/atomic 0.5.21-0 → 0.5.21

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.
@@ -218,6 +218,28 @@ Any of the named shapes above (positional or structured) accepts `-d` / `--detac
218
218
 
219
219
  **Builtin workflows are reserved** — local/global workflows cannot shadow them. Pick distinct names.
220
220
 
221
+ ### Declaring SDK compatibility (`minSDKVersion`)
222
+
223
+ Opt-in version gate for workflows that depend on a specific SDK release. **Default is unset — do not add it to new workflows unless you have a concrete reason.**
224
+
225
+ ```ts
226
+ defineWorkflow({
227
+ name: "uses-new-api",
228
+ minSDKVersion: "0.6.0", // refuse to load on older CLI
229
+ })
230
+ ```
231
+
232
+ | Behaviour | Unset (default) | Set to a version newer than the installed CLI |
233
+ |---|---|---|
234
+ | Loader | Always loads | Refuses to load, returns `IncompatibleSDKError` |
235
+ | `atomic workflow -l` | Normal row | `⚠ needs v<X> (installed v<Y>)` — dim name, visible |
236
+ | Picker | Normal row | `⚠ update required` glyph + preview explains the gap; Enter is disabled |
237
+ | `atomic workflow -n <name>` | Runs | Errors with an upgrade hint, non-zero exit |
238
+
239
+ When to set it: the workflow calls into a newly-added SDK surface (new `stage()` option, new helper export, new provider method) that older installs don't ship. Omit it for workflows that use only stable APIs — most workflows qualify.
240
+
241
+ The point of the field is to convert a silent "workflow vanished after upgrade" failure into a visible, actionable row the user can fix. See `references/discovery-and-verification.md` for semver semantics and the visible-diagnostic contract.
242
+
221
243
  ### Structural Rules
222
244
 
223
245
  Hard constraints enforced by the builder, loader, and runtime:
@@ -108,6 +108,81 @@ At load time, the runtime verifies:
108
108
  - The export has `__brand === "WorkflowDefinition"`
109
109
  - The definition has a `name` and a `run` callback
110
110
 
111
+ ## SDK version compatibility
112
+
113
+ Workflows may opt in to a minimum Atomic CLI version by declaring
114
+ `minSDKVersion` on `defineWorkflow()`. The field is **optional and
115
+ unset by default** — workflows that don't declare it are treated as
116
+ compatible with every CLI release.
117
+
118
+ ```ts
119
+ export default defineWorkflow({
120
+ name: "uses-new-stage-option",
121
+ description: "...",
122
+ minSDKVersion: "0.6.0",
123
+ })
124
+ .for<"claude">()
125
+ .run(async (ctx) => { /* ... */ })
126
+ .compile();
127
+ ```
128
+
129
+ ### When to set it
130
+
131
+ Set `minSDKVersion` when the workflow uses an SDK surface that older
132
+ CLIs don't ship — for example a new `ctx.stage()` option, a newly
133
+ exported helper, or a new provider method. The version you declare is
134
+ the **earliest release you tested against**, not a future wish list.
135
+
136
+ Skip it when the workflow only touches stable APIs. Most workflows
137
+ qualify. A needlessly high `minSDKVersion` is worse than no gate —
138
+ it'll lock users out for no reason.
139
+
140
+ ### Accepted format
141
+
142
+ `MAJOR.MINOR.PATCH` with an optional numeric prerelease, matching the
143
+ shape of Atomic's own releases:
144
+
145
+ | Example | Parses | Notes |
146
+ |---|---|---|
147
+ | `"0.6.0"` | ✅ | Standard release |
148
+ | `"1.2.3"` | ✅ | Standard release |
149
+ | `"0.6.0-0"` | ✅ | Prerelease; ranks below the equivalent stable release (semver-compliant) |
150
+ | `"0.6"` | ❌ | Missing patch; treated as unparseable and ignored |
151
+ | `"latest"` | ❌ | Unparseable; ignored |
152
+
153
+ Unparseable strings are silently accepted (the workflow loads as if
154
+ `minSDKVersion` were unset) so a typo never blocks a workflow —
155
+ the visible load error path is friendlier than a hard refusal with no
156
+ context.
157
+
158
+ ### What happens when the gate trips
159
+
160
+ A workflow whose `minSDKVersion` exceeds the installed CLI is kept in
161
+ discovery but marked **incompatible** — it never silently vanishes:
162
+
163
+ | Surface | Behaviour |
164
+ |---|---|
165
+ | `WorkflowLoader.loadWorkflow()` | Returns `{ ok: false, stage: "load", error: IncompatibleSDKError }` carrying `requiredVersion` + `currentVersion` |
166
+ | `loadWorkflowsMetadata()` | Yields an entry with `status: { kind: "incompatible", requiredVersion, currentVersion, message }` |
167
+ | `atomic workflow -l` | Row is dimmed, with an inline `⚠ needs v<X> (installed v<Y>)` badge after the name |
168
+ | `atomic workflow -a <agent>` picker | Row shows a `⚠` gutter glyph; preview pane explains the version gap and remediation; Enter does not advance to the prompt phase; bottom hint dims `↵ select` to `↵ unavailable` |
169
+ | `atomic workflow -n <name> -a <agent>` | Exits non-zero, prints the `IncompatibleSDKError` message (`requires Atomic SDK v<X>, but v<Y> is installed. Update Atomic, or re-save the workflow against the current SDK.`) |
170
+
171
+ Load failures that aren't version-related (syntax error, missing
172
+ `.compile()`, invalid default export) follow the same visible-entry
173
+ contract but surface as `status: { kind: "error", stage, message }`
174
+ with a `✗ broken` badge.
175
+
176
+ ### Why this exists
177
+
178
+ The previous default was to silently drop any workflow that failed to
179
+ load. That turned the "I bumped `@bastani/atomic` and a user/global
180
+ workflow quietly stopped showing up" scenario into a ghost bug — the
181
+ user had no breadcrumb to follow. The `minSDKVersion` field lets
182
+ workflow authors opt in to a clear upgrade path, and the visible
183
+ diagnostic rows make the failure discoverable even for workflows that
184
+ never declared the field.
185
+
111
186
  ## TypeScript configuration
112
187
 
113
188
  Standard module resolution handles all imports. The project's `tsconfig.json` should use `"moduleResolution": "bundler"` (Bun's default).
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-picker-panel.d.ts","sourceRoot":"","sources":["../../../src/sdk/components/workflow-picker-panel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow-picker-panel.d.ts","sourceRoot":"","sources":["../../../src/sdk/components/workflow-picker-panel.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"define-workflow.d.ts","sourceRoot":"","sources":["../../src/sdk/define-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACd,MAAM,YAAY,CAAC;AAsCpB;;;GAGG;AACH,qBAAa,eAAe,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM;IACrF,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAG,iBAAiB,CAAU;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,KAAK,CAAgE;gBAEjE,OAAO,EAAE,eAAe;IAIpC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,GAAG,CAAC,CAAC,SAAS,SAAS,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;IAIjD;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAW5D;;;;;OAKG;IACH,OAAO,IAAI,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC;CAmCpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAC5B,KAAK,CAAC,CAAC,SAAS,SAAS,aAAa,EAAE,GAAG,SAAS,aAAa,EAAE,EAEnE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAC1B,eAAe,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAK/C"}
1
+ {"version":3,"file":"define-workflow.d.ts","sourceRoot":"","sources":["../../src/sdk/define-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACd,MAAM,YAAY,CAAC;AAsCpB;;;GAGG;AACH,qBAAa,eAAe,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM;IACrF,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAG,iBAAiB,CAAU;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,KAAK,CAAgE;gBAEjE,OAAO,EAAE,eAAe;IAIpC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,GAAG,CAAC,CAAC,SAAS,SAAS,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;IAIjD;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAW5D;;;;;OAKG;IACH,OAAO,IAAI,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC;CAoCpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAC5B,KAAK,CAAC,CAAC,SAAS,SAAS,aAAa,EAAE,GAAG,SAAS,aAAa,EAAE,EAEnE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAC1B,eAAe,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAK/C"}
@@ -19,6 +19,18 @@ export declare class InvalidWorkflowError extends Error {
19
19
  readonly path: string;
20
20
  constructor(path: string);
21
21
  }
22
+ /**
23
+ * Thrown when a workflow declares a `minSDKVersion` newer than the
24
+ * bundled CLI. Carries both versions so the CLI can render an
25
+ * actionable "update atomic or re-save the workflow" hint rather than
26
+ * a generic load error.
27
+ */
28
+ export declare class IncompatibleSDKError extends Error {
29
+ readonly path: string;
30
+ readonly requiredVersion: string;
31
+ readonly currentVersion: string;
32
+ constructor(path: string, requiredVersion: string, currentVersion: string);
33
+ }
22
34
  /** Extract a human-readable message from an unknown thrown value. */
23
35
  export declare function errorMessage(error: unknown): string;
24
36
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/sdk/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qEAAqE;AACrE,qBAAa,sBAAuB,SAAQ,KAAK;aACnB,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK;gBAApC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK;CAIjE;AAED,qEAAqE;AACrE,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAUzC;AAED,8EAA8E;AAC9E,qBAAa,oBAAqB,SAAQ,KAAK;aACjB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAOzC;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/sdk/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qEAAqE;AACrE,qBAAa,sBAAuB,SAAQ,KAAK;aACnB,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK;gBAApC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK;CAIjE;AAED,qEAAqE;AACrE,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAUzC;AAED,8EAA8E;AAC9E,qBAAa,oBAAqB,SAAQ,KAAK;aACjB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAOzC;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,IAAI,EAAE,MAAM;aACZ,eAAe,EAAE,MAAM;aACvB,cAAc,EAAE,MAAM;gBAFtB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM;CAQzC;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD"}
@@ -61,29 +61,72 @@ export declare function discoverWorkflows(projectRoot?: string, agentFilter?: Ag
61
61
  * Find a specific workflow by name and agent.
62
62
  */
63
63
  export declare function findWorkflow(name: string, agent: AgentType, projectRoot?: string): Promise<DiscoveredWorkflow | null>;
64
+ /**
65
+ * Load status for a {@link WorkflowWithMetadata} entry.
66
+ *
67
+ * - `ok` — the workflow compiled cleanly and is ready to run.
68
+ * - `incompatible` — the workflow declared a `minSDKVersion` newer
69
+ * than the bundled CLI. The CLI renders it with an
70
+ * "update required" badge so users see the mismatch
71
+ * rather than a silent disappearance.
72
+ * - `error` — any other load failure (syntax error, missing
73
+ * `.compile()`, invalid default export, etc.).
74
+ * Rendered with a "failed to load" badge plus the
75
+ * underlying message.
76
+ */
77
+ export type WorkflowMetadataStatus = {
78
+ kind: "ok";
79
+ } | {
80
+ kind: "incompatible";
81
+ requiredVersion: string;
82
+ currentVersion: string;
83
+ message: string;
84
+ } | {
85
+ kind: "error";
86
+ stage: "resolve" | "validate" | "load";
87
+ message: string;
88
+ };
64
89
  /**
65
90
  * A discovered workflow enriched with the metadata the picker needs to
66
- * render it: the human description and the declared input schema.
91
+ * render it: the human description, the declared input schema, and the
92
+ * load status.
67
93
  *
68
94
  * Populated by {@link loadWorkflowsMetadata}, which runs each discovered
69
- * workflow through {@link WorkflowLoader.loadWorkflow} and extracts just
70
- * the display-relevant fields — the full compiled definition is
71
- * discarded after extraction so re-imports during execution are cheap.
95
+ * workflow through {@link WorkflowLoader.loadWorkflow} and extracts the
96
+ * display-relevant fields — the full compiled definition is discarded
97
+ * after extraction so re-imports during execution are cheap.
98
+ *
99
+ * Broken entries still materialise with empty `description` / `inputs`
100
+ * and a non-`ok` {@link status}, so the picker can render them as
101
+ * visible "update required" / "failed to load" rows instead of
102
+ * silently omitting them (the previous behaviour, which made user and
103
+ * global workflows vanish whenever the base SDK shape drifted between
104
+ * releases).
72
105
  */
73
106
  export interface WorkflowWithMetadata extends DiscoveredWorkflow {
74
- /** Workflow description, empty string when none was declared. */
107
+ /** Workflow description, empty string when none was declared or the workflow failed to load. */
75
108
  description: string;
76
- /** Picker-ready input schema; free-form workflows materialize a prompt field. */
109
+ /** Picker-ready input schema; empty for free-form or failed-to-load workflows. */
77
110
  inputs: readonly WorkflowInput[];
111
+ /** Load outcome — non-`ok` entries are rendered as visible diagnostics in the picker/list. */
112
+ status: WorkflowMetadataStatus;
78
113
  }
79
114
  /**
80
- * Load metadata (description + picker-ready inputs) for a batch of discovered workflows.
115
+ * Load metadata (description + picker-ready inputs + status) for a batch
116
+ * of discovered workflows.
117
+ *
118
+ * **Failed workflows are kept in the returned list**, not dropped. Each
119
+ * broken entry carries a {@link WorkflowMetadataStatus} explaining the
120
+ * failure so the picker and `atomic workflow -l` can surface it as an
121
+ * actionable diagnostic. This is the only way end users discover that a
122
+ * workflow from an older SDK release has gone incompatible after an
123
+ * `atomic` upgrade — silent filtering would leave them with a missing
124
+ * entry and no breadcrumb.
81
125
  *
82
- * Workflows that fail to import are **skipped silently** so one broken
83
- * entry can never prevent the picker from rendering. Callers that need
84
- * to surface load errors (e.g. `atomic workflow -n broken`) should use
85
- * {@link WorkflowLoader.loadWorkflow} directly — that path produces
86
- * structured error reports.
126
+ * Callers that want to execute a workflow should still route through
127
+ * {@link WorkflowLoader.loadWorkflow} this function throws away the
128
+ * compiled definition so re-running the loader on a confirmed pick is
129
+ * unavoidable.
87
130
  */
88
131
  export declare function loadWorkflowsMetadata(discovered: DiscoveredWorkflow[]): Promise<WorkflowWithMetadata[]>;
89
132
  //# sourceMappingURL=discovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;CACxC;AAUD,eAAO,MAAM,MAAM,EAAE,SAAS,EAAsC,CAAC;AAGrE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QASpB,CAAC;AAkGb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,GAAE,MAAsB,EACnC,WAAW,CAAC,EAAE,SAAS,EACvB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAoD/B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,EAChB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAGpC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAAE,GAC/B,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAejC"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;CACxC;AAUD,eAAO,MAAM,MAAM,EAAE,SAAS,EAAsC,CAAC;AAGrE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QASpB,CAAC;AAkGb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,GAAE,MAAsB,EACnC,WAAW,CAAC,EAAE,SAAS,EACvB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAoD/B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,EAChB,WAAW,GAAE,MAAsB,GAClC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAGpC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IACE,IAAI,EAAE,cAAc,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,gGAAgG;IAChG,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IACjC,8FAA8F;IAC9F,MAAM,EAAE,sBAAsB,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAAE,GAC/B,OAAO,CAAC,oBAAoB,EAAE,CAAC,CA2CjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAa,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAMzD,yBAAiB,cAAc,CAAC;IAK9B,kCAAkC;IAClC,KAAY,EAAE,CAAC,CAAC,IAAI;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,CAAC;IAE3C,2DAA2D;IAC3D,KAAY,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI;QACzC,EAAE,EAAE,KAAK,CAAC;QACV,KAAK,EAAE,CAAC,CAAC;QACT,KAAK,EAAE,OAAO,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,KAAY,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAMrE,+DAA+D;IAC/D,KAAY,IAAI,GAAG,kBAAkB,CAAC;IAEtC,mCAAmC;IACnC,KAAY,QAAQ,GAAG,IAAI,CAAC;IAE5B,6EAA6E;IAC7E,KAAY,iBAAiB,GAAG,OAAO,aAAa,EAAE,iBAAiB,CAAC;IAExE,oCAAoC;IACpC,KAAY,SAAS,GAAG,QAAQ,GAAG;QACjC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;KAC/B,CAAC;IAEF,mDAAmD;IACnD,KAAY,MAAM,GAAG,SAAS,GAAG;QAC/B,UAAU,EAAE,kBAAkB,CAAC;KAChC,CAAC;IAMF,UAAiB,MAAM;QACrB,kCAAkC;QAClC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,KAAK,IAAI,CAAC;QACzD,uDAAuD;QACvD,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;QAC/C,iCAAiC;QACjC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;KAC3F;IAMD,uCAAuC;IACvC,SAAsB,OAAO,CAC3B,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAoB3C;IAsBD;;;OAGG;IACH,SAAsB,QAAQ,CAC5B,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAiB7C;IAMD;;;OAGG;IACH,SAAsB,IAAI,CACxB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqCtC;IAMD;;;;;OAKG;IACH,SAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC,CA6B/D;CACF"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAa,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAazD,yBAAiB,cAAc,CAAC;IAK9B,kCAAkC;IAClC,KAAY,EAAE,CAAC,CAAC,IAAI;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,CAAC;IAE3C,2DAA2D;IAC3D,KAAY,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI;QACzC,EAAE,EAAE,KAAK,CAAC;QACV,KAAK,EAAE,CAAC,CAAC;QACT,KAAK,EAAE,OAAO,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,KAAY,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAMrE,+DAA+D;IAC/D,KAAY,IAAI,GAAG,kBAAkB,CAAC;IAEtC,mCAAmC;IACnC,KAAY,QAAQ,GAAG,IAAI,CAAC;IAE5B,6EAA6E;IAC7E,KAAY,iBAAiB,GAAG,OAAO,aAAa,EAAE,iBAAiB,CAAC;IAExE,oCAAoC;IACpC,KAAY,SAAS,GAAG,QAAQ,GAAG;QACjC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;KAC/B,CAAC;IAEF,mDAAmD;IACnD,KAAY,MAAM,GAAG,SAAS,GAAG;QAC/B,UAAU,EAAE,kBAAkB,CAAC;KAChC,CAAC;IAMF,UAAiB,MAAM;QACrB,kCAAkC;QAClC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,KAAK,IAAI,CAAC;QACzD,uDAAuD;QACvD,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;QAC/C,iCAAiC;QACjC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;KAC3F;IAMD,uCAAuC;IACvC,SAAsB,OAAO,CAC3B,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAoB3C;IAsBD;;;OAGG;IACH,SAAsB,QAAQ,CAC5B,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAiB7C;IAMD;;;OAGG;IACH,SAAsB,IAAI,CACxB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAyDtC;IAMD;;;;;OAKG;IACH,SAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC,CA6B/D;CACF"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Tiny semver comparator used to check a workflow's declared
3
+ * `minSDKVersion` against the bundled CLI {@link VERSION}.
4
+ *
5
+ * Accepts the subset of semver we actually ship: `MAJOR.MINOR.PATCH`
6
+ * with an optional numeric prerelease (e.g. `0.5.21`, `0.5.21-0`).
7
+ * Anything more exotic (build metadata, alpha tags) is treated as a
8
+ * plain string and compared lexicographically on the prerelease tail,
9
+ * which is good enough for "is the installed CLI new enough?".
10
+ *
11
+ * Isolated from the `semver` npm package so the workflow loader stays
12
+ * dependency-free — this check runs for every discovered workflow on
13
+ * every CLI launch.
14
+ */
15
+ /**
16
+ * Return a negative number if `a < b`, positive if `a > b`, 0 if equal.
17
+ * Unparseable inputs compare as equal so we never block a workflow over
18
+ * a typo in its `minSDKVersion` — the visible load error is friendlier
19
+ * than a hard refusal.
20
+ */
21
+ export declare function compareVersions(a: string, b: string): number;
22
+ /**
23
+ * True when the current CLI is new enough to run a workflow that
24
+ * declared `minRequired`. A null/undefined requirement always
25
+ * satisfies — workflows that don't opt in are treated as compatible.
26
+ */
27
+ export declare function satisfiesMinVersion(current: string, minRequired: string | null | undefined): boolean;
28
+ //# sourceMappingURL=version-compat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-compat.d.ts","sourceRoot":"","sources":["../../../src/sdk/runtime/version-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAoBH;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAe5D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAGT"}
@@ -293,6 +293,22 @@ export interface WorkflowOptions<I extends readonly WorkflowInput[] = readonly W
293
293
  * and enforce them on `ctx.inputs`.
294
294
  */
295
295
  inputs?: I;
296
+ /**
297
+ * Minimum Atomic CLI version this workflow is known to work with.
298
+ *
299
+ * When set, the CLI refuses to load the workflow on an older install
300
+ * and surfaces an actionable "update required" entry in the picker
301
+ * and `atomic workflow -l` output instead of silently dropping it.
302
+ *
303
+ * Leave unset (the default) to opt out entirely — the workflow will
304
+ * be treated as compatible with every CLI version. Use this when you
305
+ * consume a new SDK feature (new provider API, a new field on the
306
+ * stage options, etc.) that older installs can't honour.
307
+ *
308
+ * Accepts `MAJOR.MINOR.PATCH` with an optional numeric prerelease
309
+ * (`0.6.0`, `0.6.0-0`). Invalid strings are ignored.
310
+ */
311
+ minSDKVersion?: string;
296
312
  }
297
313
  /**
298
314
  * A compiled workflow definition — the sealed output of defineWorkflow().compile().
@@ -303,6 +319,11 @@ export interface WorkflowDefinition<A extends AgentType = AgentType, N extends s
303
319
  readonly description: string;
304
320
  /** Declared input schema — empty array for free-form workflows. */
305
321
  readonly inputs: readonly WorkflowInput[];
322
+ /**
323
+ * Minimum Atomic SDK version required. `null` when the workflow
324
+ * declared no requirement — treated as compatible with every CLI.
325
+ */
326
+ readonly minSDKVersion: string | null;
306
327
  /** The workflow's entry point. Called by the executor with a WorkflowContext. */
307
328
  readonly run: (ctx: WorkflowContext<A, N>) => Promise<void>;
308
329
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sdk/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sdk/types.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ export { validateOpenCodeWorkflow } from "../providers/opencode.ts";
17
17
  export type { TmuxResult, TmuxSession, SessionType } from "../runtime/tmux.ts";
18
18
  export { SOCKET_NAME, isTmuxInstalled, getMuxBinary, resetMuxBinaryCache, isInsideTmux, isInsideAtomicSocket, createSession, createWindow, createPane, sendLiteralText, sendSpecialKey, sendKeysAndSubmit, capturePane, capturePaneVisible, capturePaneScrollback, killSession, killWindow, sessionExists, listSessions, attachSession, spawnMuxAttach, switchClient, getCurrentSession, attachOrSwitch, detachAndAttachAtomic, selectWindow, setSessionEnv, getSessionEnv, parseSessionName, waitForOutput, tmuxRun, normalizeTmuxCapture, normalizeTmuxLines, paneLooksReady, paneHasActiveTask, paneIsIdle, waitForPaneReady, attemptSubmitRounds, } from "../runtime/tmux.ts";
19
19
  export { AGENTS, discoverWorkflows, findWorkflow, loadWorkflowsMetadata, WORKFLOWS_GITIGNORE, } from "../runtime/discovery.ts";
20
- export type { DiscoveredWorkflow, WorkflowWithMetadata, } from "../runtime/discovery.ts";
20
+ export type { DiscoveredWorkflow, WorkflowWithMetadata, WorkflowMetadataStatus, } from "../runtime/discovery.ts";
21
21
  export { WorkflowLoader } from "../runtime/loader.ts";
22
22
  export { executeWorkflow } from "../runtime/executor.ts";
23
23
  export type { WorkflowRunOptions } from "../runtime/executor.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sdk/workflows/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExE,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,cAAc,EACd,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,YAAY,EAAE,cAAc,IAAI,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAG7F,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC5I,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACL,WAAW,EACX,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,OAAO,EACP,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sdk/workflows/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExE,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,cAAc,EACd,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,qBAAqB,IAAI,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,YAAY,EAAE,cAAc,IAAI,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAG7F,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC5I,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACL,WAAW,EACX,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,UAAU,EACV,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,OAAO,EACP,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,QAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/atomic",
3
- "version": "0.5.21-0",
3
+ "version": "0.5.21",
4
4
  "description": "Configuration management CLI and SDK for coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -300,7 +300,11 @@ describe("workflowCommand --list", () => {
300
300
  expect(cap.stdout).not.toContain("copilot-only");
301
301
  });
302
302
 
303
- test("excludes workflows missing .compile() from the list", async () => {
303
+ test("shows workflows missing .compile() with a broken marker", async () => {
304
+ // Broken workflows used to vanish from the list silently. Surfacing
305
+ // them with a visible "✗ broken" badge is the remediation for the
306
+ // "my workflow disappeared after upgrading" class of bug reports —
307
+ // the user can now see the file still exists and needs a fix.
304
308
  await writeCompiledWorkflow({ name: "good", agent: "copilot" });
305
309
  await writeCompiledWorkflow({
306
310
  name: "not-compiled",
@@ -324,10 +328,11 @@ export default defineWorkflow({ name: "not-compiled" })
324
328
 
325
329
  expect(code).toBe(0);
326
330
  expect(cap.stdout).toContain("good");
327
- expect(cap.stdout).not.toContain("not-compiled");
331
+ expect(cap.stdout).toContain("not-compiled");
332
+ expect(cap.stdout).toContain("✗ broken");
328
333
  });
329
334
 
330
- test("excludes workflows with type errors from the list", async () => {
335
+ test("shows workflows with type errors with a broken marker", async () => {
331
336
  await writeCompiledWorkflow({ name: "valid", agent: "copilot" });
332
337
  await writeCompiledWorkflow({
333
338
  name: "broken-syntax",
@@ -345,7 +350,8 @@ export default defineWorkflow({ name: "not-compiled" })
345
350
 
346
351
  expect(code).toBe(0);
347
352
  expect(cap.stdout).toContain("valid");
348
- expect(cap.stdout).not.toContain("broken-syntax");
353
+ expect(cap.stdout).toContain("broken-syntax");
354
+ expect(cap.stdout).toContain("✗ broken");
349
355
  });
350
356
 
351
357
  test("renders the empty state when no workflows exist and no agent filter is set", async () => {
@@ -172,6 +172,7 @@ function fakeDefinition(
172
172
  name,
173
173
  description,
174
174
  inputs,
175
+ minSDKVersion: null,
175
176
  run: async () => {},
176
177
  } as WorkflowDefinition;
177
178
  }
@@ -6,7 +6,10 @@ import {
6
6
  renderWorkflowList,
7
7
  } from "./workflow.ts";
8
8
  import type { WorkflowInput } from "../../sdk/workflows/index.ts";
9
- import type { DiscoveredWorkflow } from "../../sdk/workflows/index.ts";
9
+ import type {
10
+ DiscoveredWorkflow,
11
+ WorkflowWithMetadata,
12
+ } from "../../sdk/workflows/index.ts";
10
13
 
11
14
  // ─── Colour handling ────────────────────────────────────────────────────────
12
15
  // The renderer emits ANSI sequences when the host terminal claims truecolor
@@ -190,12 +193,16 @@ function wf(
190
193
  name: string,
191
194
  agent: DiscoveredWorkflow["agent"],
192
195
  source: DiscoveredWorkflow["source"],
193
- ): DiscoveredWorkflow {
196
+ status: WorkflowWithMetadata["status"] = { kind: "ok" },
197
+ ): WorkflowWithMetadata {
194
198
  return {
195
199
  name,
196
200
  agent,
197
201
  source,
198
202
  path: `/tmp/fake/${source}/${name}/${agent}/index.ts`,
203
+ description: "",
204
+ inputs: [],
205
+ status,
199
206
  };
200
207
  }
201
208
 
@@ -216,7 +223,7 @@ describe("renderWorkflowList", () => {
216
223
  });
217
224
 
218
225
  test("groups entries by source → provider and sorts names", () => {
219
- const workflows: DiscoveredWorkflow[] = [
226
+ const workflows: WorkflowWithMetadata[] = [
220
227
  wf("zebra", "claude", "local"),
221
228
  wf("apple", "claude", "local"),
222
229
  wf("middle", "opencode", "local"),
@@ -27,6 +27,7 @@ import type {
27
27
  AgentType,
28
28
  DiscoveredWorkflow,
29
29
  WorkflowInput,
30
+ WorkflowMetadataStatus,
30
31
  WorkflowWithMetadata,
31
32
  } from "../../sdk/workflows/index.ts";
32
33
  import { WorkflowPickerPanel } from "../../sdk/components/workflow-picker-panel.tsx";
@@ -227,8 +228,11 @@ export async function workflowCommand(options: {
227
228
  options.agent as AgentType | undefined,
228
229
  { merge: false },
229
230
  );
230
- // Filter out workflows that fail to load (type errors, missing
231
- // .compile(), etc.) so the list only shows workflows ready to run.
231
+ // Keep workflows that failed to load in the list — their status is
232
+ // surfaced inline as a "needs update" or "broken" tag so the user
233
+ // can see that a workflow still exists on disk even after an SDK
234
+ // bump invalidated it. Silent filtering was the original cause of
235
+ // the "workflow vanished after upgrade" report.
232
236
  const workflows = await loadWorkflowsMetadata(discovered);
233
237
  process.stdout.write(renderWorkflowList(workflows));
234
238
  return 0;
@@ -477,9 +481,13 @@ async function runNamedMode(
477
481
  ` ~/.atomic/workflows/${name}/${agent}/index.ts ${COLORS.dim}(global)${COLORS.reset}`,
478
482
  );
479
483
 
480
- const available = await loadWorkflowsMetadata(
481
- await discoverWorkflows(cwd, agent),
482
- );
484
+ // Only suggest runnable alternatives — broken/incompatible workflows
485
+ // are visible via `atomic workflow -l` where their status is surfaced;
486
+ // listing them here would mask the real problem (the name the user
487
+ // typed does not exist) behind a dead-end suggestion.
488
+ const available = (
489
+ await loadWorkflowsMetadata(await discoverWorkflows(cwd, agent))
490
+ ).filter((w) => w.status.kind === "ok");
483
491
  if (available.length > 0) {
484
492
  console.error(`\nAvailable ${agent} workflows:`);
485
493
  for (const wf of available) {
@@ -608,6 +616,29 @@ const SOURCE_COLORS: Record<DiscoveredWorkflow["source"], PaletteKey> = {
608
616
  builtin: "info", // sky — ships with atomic, foundational
609
617
  };
610
618
 
619
+ /**
620
+ * Per-row status badge shown in `atomic workflow -l` output. `ok` rows
621
+ * render with no badge (the list is already dense; flagging only
622
+ * non-ok rows keeps the happy path untouched). Incompatible rows
623
+ * include the required version so the user can compare at a glance;
624
+ * error rows stay terse and defer detail to `atomic workflow -n
625
+ * <name>` which surfaces the structured loader message.
626
+ */
627
+ function renderStatusBadge(
628
+ paint: ReturnType<typeof createPainter>,
629
+ status: WorkflowMetadataStatus,
630
+ ): string {
631
+ if (status.kind === "ok") return "";
632
+ if (status.kind === "incompatible") {
633
+ return (
634
+ " " +
635
+ paint("warning", "⚠ needs v" + status.requiredVersion) +
636
+ paint("dim", ` (installed v${status.currentVersion})`)
637
+ );
638
+ }
639
+ return " " + paint("error", "✗ broken");
640
+ }
641
+
611
642
  /**
612
643
  * Render `atomic workflow --list` output as a printable string.
613
644
  *
@@ -635,7 +666,7 @@ const SOURCE_COLORS: Record<DiscoveredWorkflow["source"], PaletteKey> = {
635
666
  * Exported for testing — the pure-function shape makes coverage for the
636
667
  * renderer trivial without spinning up a full CLI invocation.
637
668
  */
638
- export function renderWorkflowList(workflows: DiscoveredWorkflow[]): string {
669
+ export function renderWorkflowList(workflows: WorkflowWithMetadata[]): string {
639
670
  const paint = createPainter();
640
671
  const lines: string[] = [];
641
672
 
@@ -653,9 +684,11 @@ export function renderWorkflowList(workflows: DiscoveredWorkflow[]): string {
653
684
  return lines.join("\n") + "\n";
654
685
  }
655
686
 
656
- // Group by source → agent → sorted names. This gives the renderer O(1)
657
- // lookups at both nesting levels and keeps the output deterministic.
658
- type ByAgent = Map<AgentType, string[]>;
687
+ // Group by source → agent → sorted entries. Entries carry the full
688
+ // metadata (name + status) so the row renderer can append a status
689
+ // badge to non-ok rows without another lookup.
690
+ type EntrySummary = { name: string; status: WorkflowMetadataStatus };
691
+ type ByAgent = Map<AgentType, EntrySummary[]>;
659
692
  const bySource = new Map<DiscoveredWorkflow["source"], ByAgent>();
660
693
  for (const wf of workflows) {
661
694
  let byAgent = bySource.get(wf.source);
@@ -663,13 +696,13 @@ export function renderWorkflowList(workflows: DiscoveredWorkflow[]): string {
663
696
  byAgent = new Map();
664
697
  bySource.set(wf.source, byAgent);
665
698
  }
666
- const names = byAgent.get(wf.agent) ?? [];
667
- names.push(wf.name);
668
- byAgent.set(wf.agent, names);
699
+ const entries = byAgent.get(wf.agent) ?? [];
700
+ entries.push({ name: wf.name, status: wf.status });
701
+ byAgent.set(wf.agent, entries);
669
702
  }
670
703
  for (const byAgent of bySource.values()) {
671
- for (const names of byAgent.values()) {
672
- names.sort((a, b) => a.localeCompare(b));
704
+ for (const entries of byAgent.values()) {
705
+ entries.sort((a, b) => a.name.localeCompare(b.name));
673
706
  }
674
707
  }
675
708
 
@@ -702,8 +735,8 @@ export function renderWorkflowList(workflows: DiscoveredWorkflow[]): string {
702
735
  );
703
736
 
704
737
  for (const agent of AGENT_ORDER) {
705
- const names = byAgent.get(agent);
706
- if (!names || names.length === 0) continue;
738
+ const entries = byAgent.get(agent);
739
+ if (!entries || entries.length === 0) continue;
707
740
 
708
741
  // Provider heading: bold accent blue — a clearly different layer from
709
742
  // both the semantic source heading above and the neutral entries below.
@@ -712,8 +745,14 @@ export function renderWorkflowList(workflows: DiscoveredWorkflow[]): string {
712
745
  " " + paint("accent", AGENT_DISPLAY_NAMES[agent], { bold: true }),
713
746
  );
714
747
 
715
- for (const name of names) {
716
- lines.push(" " + paint("text", name));
748
+ for (const entry of entries) {
749
+ // Dim the name on non-ok rows so the eye lands on the status
750
+ // badge rather than the workflow name — the badge is where the
751
+ // actionable info lives, and the name is already unrunnable.
752
+ const nameCol: PaletteKey = entry.status.kind === "ok" ? "text" : "dim";
753
+ lines.push(
754
+ " " + paint(nameCol, entry.name) + renderStatusBadge(paint, entry.status),
755
+ );
717
756
  }
718
757
  }
719
758
  }
@@ -42,7 +42,10 @@ import { useState, useEffect, useMemo, useRef, useCallback, useContext, createCo
42
42
  import { useLatest } from "./hooks.ts";
43
43
  import { resolveTheme, type TerminalTheme } from "../runtime/theme.ts";
44
44
  import type { AgentType, WorkflowInput } from "../types.ts";
45
- import type { WorkflowWithMetadata } from "../runtime/discovery.ts";
45
+ import type {
46
+ WorkflowWithMetadata,
47
+ WorkflowMetadataStatus,
48
+ } from "../runtime/discovery.ts";
46
49
  import { ErrorBoundary } from "./error-boundary.tsx";
47
50
 
48
51
  // ─── Theme ──────────────────────────────────────
@@ -258,6 +261,38 @@ export function buildRows(entries: ListEntry[], query: string): ListRow[] {
258
261
  return rows;
259
262
  }
260
263
 
264
+ // ─── Status helpers ─────────────────────────────
265
+ // Non-ok entries stay visible in the picker so the user sees that a
266
+ // workflow from an older SDK release (or one with a load error) still
267
+ // exists on disk — the previous behaviour silently dropped them, which
268
+ // made user/global workflows appear to vanish after an atomic upgrade.
269
+
270
+ /** Unicode glyph that prefixes a non-ok entry and heads its preview. */
271
+ const STATUS_ICON: Record<WorkflowMetadataStatus["kind"], string> = {
272
+ ok: " ",
273
+ incompatible: "⚠",
274
+ error: "✗",
275
+ };
276
+
277
+ /** Compact single-word label used in list rows and the bottom hint. */
278
+ const STATUS_LABEL: Record<WorkflowMetadataStatus["kind"], string> = {
279
+ ok: "",
280
+ incompatible: "update",
281
+ error: "broken",
282
+ };
283
+
284
+ /** Map each status kind to its semantic palette slot. */
285
+ const STATUS_COLOR: Record<WorkflowMetadataStatus["kind"], keyof PickerTheme> = {
286
+ ok: "success",
287
+ incompatible: "warning",
288
+ error: "error",
289
+ };
290
+
291
+ /** Non-ok rows are inert — Enter / run commands must not transition the picker. */
292
+ function isRunnable(wf: WorkflowWithMetadata): boolean {
293
+ return wf.status.kind === "ok";
294
+ }
295
+
261
296
  // ─── Validation ─────────────────────────────────
262
297
 
263
298
  export function isFieldValid(field: WorkflowInput, value: string): boolean {
@@ -385,6 +420,24 @@ const WorkflowList = memo(function WorkflowList({
385
420
  const entryIdx = entryIndexByRow.get(i) ?? -1;
386
421
  const isFocused = entryIdx === focusedEntryIdx;
387
422
  const wf = row.entry.workflow;
423
+ const statusKind = wf.status.kind;
424
+ const runnable = statusKind === "ok";
425
+ // Status indicator sits between the focus marker and the name so
426
+ // every row shares a 4-character gutter — ok rows render a blank
427
+ // gutter, so the list stays visually flush while non-ok rows
428
+ // always occupy a fixed slot (no layout jitter when filtering).
429
+ const statusIcon = STATUS_ICON[statusKind];
430
+ const statusCol = theme[STATUS_COLOR[statusKind]];
431
+ // Non-ok rows fade the name so the "diagnostic, not selectable"
432
+ // read is immediate even when the user hasn't reached the row
433
+ // yet — the eye catches the warning glyph + dim text together.
434
+ const nameCol = runnable
435
+ ? isFocused
436
+ ? theme.text
437
+ : theme.textMuted
438
+ : isFocused
439
+ ? theme.textMuted
440
+ : theme.textDim;
388
441
 
389
442
  return (
390
443
  <box
@@ -399,7 +452,10 @@ const WorkflowList = memo(function WorkflowList({
399
452
  <span fg={isFocused ? theme.primary : theme.textDim}>
400
453
  {isFocused ? "▸ " : " "}
401
454
  </span>
402
- <span fg={isFocused ? theme.text : theme.textMuted}>
455
+ <span fg={statusCol}>
456
+ {statusIcon + " "}
457
+ </span>
458
+ <span fg={nameCol}>
403
459
  {wf.name}
404
460
  </span>
405
461
  </text>
@@ -459,6 +515,59 @@ const ArgumentRow = memo(function ArgumentRow({
459
515
  );
460
516
  });
461
517
 
518
+ /**
519
+ * Diagnostic block for non-ok workflows. Replaces the description +
520
+ * arguments sections in the preview pane so the user sees *why* a row
521
+ * is inert and what to do about it, instead of an empty-looking panel.
522
+ */
523
+ const StatusDiagnostic = memo(function StatusDiagnostic({
524
+ status,
525
+ }: {
526
+ status: Exclude<WorkflowMetadataStatus, { kind: "ok" }>;
527
+ }) {
528
+ const theme = usePickerTheme();
529
+ const color = theme[STATUS_COLOR[status.kind]];
530
+ const icon = STATUS_ICON[status.kind];
531
+
532
+ // Headline + sub-copy split: the headline is terse (three words) so
533
+ // it reads at a glance even on a narrow right pane; the sub-copy
534
+ // explains *why* and the third paragraph tells the user what to do.
535
+ const headline =
536
+ status.kind === "incompatible"
537
+ ? "update required"
538
+ : "failed to load";
539
+ const detail =
540
+ status.kind === "incompatible"
541
+ ? `Needs Atomic v${status.requiredVersion}. Installed: v${status.currentVersion}.`
542
+ : status.message;
543
+ const remediation =
544
+ status.kind === "incompatible"
545
+ ? "Update Atomic, or re-save the workflow against the current SDK."
546
+ : "Open the workflow file and fix the error above.";
547
+
548
+ return (
549
+ <box flexDirection="column">
550
+ <text>
551
+ <span fg={color}>
552
+ <strong>{icon + " " + headline}</strong>
553
+ </span>
554
+ </text>
555
+
556
+ <box height={1} />
557
+
558
+ <text>
559
+ <span fg={theme.textMuted}>{detail}</span>
560
+ </text>
561
+
562
+ <box height={1} />
563
+
564
+ <text>
565
+ <span fg={theme.textDim}>{remediation}</span>
566
+ </text>
567
+ </box>
568
+ );
569
+ });
570
+
462
571
  const Preview = memo(function Preview({
463
572
  wf,
464
573
  }: {
@@ -466,6 +575,7 @@ const Preview = memo(function Preview({
466
575
  }) {
467
576
  const theme = usePickerTheme();
468
577
  const args = wf.inputs;
578
+ const status = wf.status;
469
579
 
470
580
  return (
471
581
  <box
@@ -493,21 +603,27 @@ const Preview = memo(function Preview({
493
603
 
494
604
  <box height={2} />
495
605
 
496
- <text>
497
- <span fg={theme.textMuted}>
498
- {wf.description || "(no description)"}
499
- </span>
500
- </text>
501
-
502
- {args.length > 0 && (
606
+ {status.kind === "ok" ? (
503
607
  <>
504
- <box height={2} />
505
- <SectionLabel label="ARGUMENTS" />
506
- <box height={1} />
507
- {args.map((f) => (
508
- <ArgumentRow key={f.name} field={f} />
509
- ))}
608
+ <text>
609
+ <span fg={theme.textMuted}>
610
+ {wf.description || "(no description)"}
611
+ </span>
612
+ </text>
613
+
614
+ {args.length > 0 && (
615
+ <>
616
+ <box height={2} />
617
+ <SectionLabel label="ARGUMENTS" />
618
+ <box height={1} />
619
+ {args.map((f) => (
620
+ <ArgumentRow key={f.name} field={f} />
621
+ ))}
622
+ </>
623
+ )}
510
624
  </>
625
+ ) : (
626
+ <StatusDiagnostic status={status} />
511
627
  )}
512
628
  </box>
513
629
  );
@@ -1022,6 +1138,14 @@ const PICK_HINTS: Hint[] = [
1022
1138
  { key: "↵", label: "select" },
1023
1139
  { key: "esc", label: "quit" },
1024
1140
  ];
1141
+ // Shown instead of PICK_HINTS when the focused row is non-ok — the dim
1142
+ // `↵ unavailable` reads immediately as "this row is navigable but not
1143
+ // runnable", which matches the muted row colour and preview diagnostic.
1144
+ const PICK_HINTS_UNAVAILABLE: Hint[] = [
1145
+ { key: "↑↓", label: "navigate" },
1146
+ { key: "↵", label: "unavailable", dim: true },
1147
+ { key: "esc", label: "quit" },
1148
+ ];
1025
1149
  const CONFIRM_HINTS: Hint[] = [
1026
1150
  { key: "y", label: "submit" },
1027
1151
  { key: "n", label: "cancel" },
@@ -1134,7 +1258,26 @@ const Statusline = memo(function Statusline({
1134
1258
  {focusedWf ? (
1135
1259
  <box paddingLeft={1} paddingRight={1} alignItems="center">
1136
1260
  <text>
1137
- <span fg={theme.text}>{focusedWf.name}</span>
1261
+ {focusedWf.status.kind !== "ok" ? (
1262
+ <span fg={theme[STATUS_COLOR[focusedWf.status.kind]]}>
1263
+ {STATUS_ICON[focusedWf.status.kind] + " "}
1264
+ </span>
1265
+ ) : null}
1266
+ <span
1267
+ fg={
1268
+ focusedWf.status.kind === "ok" ? theme.text : theme.textMuted
1269
+ }
1270
+ >
1271
+ {focusedWf.name}
1272
+ </span>
1273
+ {focusedWf.status.kind !== "ok" ? (
1274
+ <>
1275
+ <span fg={theme.textDim}>{" · "}</span>
1276
+ <span fg={theme[STATUS_COLOR[focusedWf.status.kind]]}>
1277
+ {STATUS_LABEL[focusedWf.status.kind]}
1278
+ </span>
1279
+ </>
1280
+ ) : null}
1138
1281
  </text>
1139
1282
  </box>
1140
1283
  ) : null}
@@ -1247,7 +1390,10 @@ function usePickerKeyboard(state: PickerKeyboardState): void {
1247
1390
  if (key.name === "return") {
1248
1391
  key.stopPropagation();
1249
1392
  const wf = focusedWfRef.current;
1250
- if (wf) {
1393
+ // Silently swallow Enter on incompatible / broken entries — the
1394
+ // preview pane already explains the failure; advancing into the
1395
+ // prompt phase would be misleading since the workflow can't run.
1396
+ if (wf && isRunnable(wf)) {
1251
1397
  const initial: Record<string, string> = {};
1252
1398
  for (const f of wf.inputs) {
1253
1399
  initial[f.name] =
@@ -1408,10 +1554,13 @@ export function WorkflowPicker({
1408
1554
  setConfirmOpen,
1409
1555
  });
1410
1556
 
1557
+ const focusedIsRunnable = focusedWf ? isRunnable(focusedWf) : true;
1411
1558
  const hints = confirmOpen
1412
1559
  ? CONFIRM_HINTS
1413
1560
  : phase === "pick"
1414
- ? PICK_HINTS
1561
+ ? focusedIsRunnable
1562
+ ? PICK_HINTS
1563
+ : PICK_HINTS_UNAVAILABLE
1415
1564
  : isFormValid
1416
1565
  ? PROMPT_HINTS_VALID
1417
1566
  : PROMPT_HINTS_INVALID;
@@ -152,6 +152,7 @@ export class WorkflowBuilder<A extends AgentType = AgentType, N extends string =
152
152
  name: this.options.name,
153
153
  description: this.options.description ?? "",
154
154
  inputs,
155
+ minSDKVersion: this.options.minSDKVersion ?? null,
155
156
  run: runFn,
156
157
  };
157
158
  }
package/src/sdk/errors.ts CHANGED
@@ -38,6 +38,26 @@ export class InvalidWorkflowError extends Error {
38
38
  }
39
39
  }
40
40
 
41
+ /**
42
+ * Thrown when a workflow declares a `minSDKVersion` newer than the
43
+ * bundled CLI. Carries both versions so the CLI can render an
44
+ * actionable "update atomic or re-save the workflow" hint rather than
45
+ * a generic load error.
46
+ */
47
+ export class IncompatibleSDKError extends Error {
48
+ constructor(
49
+ public readonly path: string,
50
+ public readonly requiredVersion: string,
51
+ public readonly currentVersion: string,
52
+ ) {
53
+ super(
54
+ `${path} requires Atomic SDK v${requiredVersion}, but v${currentVersion} is installed.\n` +
55
+ ` Update Atomic, or re-save the workflow against the current SDK.`,
56
+ );
57
+ this.name = "IncompatibleSDKError";
58
+ }
59
+ }
60
+
41
61
  /** Extract a human-readable message from an unknown thrown value. */
42
62
  export function errorMessage(error: unknown): string {
43
63
  return error instanceof Error ? error.message : String(error);
@@ -17,6 +17,7 @@ import { homedir } from "node:os";
17
17
  import ignore from "ignore";
18
18
  import type { AgentType, WorkflowInput } from "../types.ts";
19
19
  import { WorkflowLoader } from "./loader.ts";
20
+ import { IncompatibleSDKError } from "../errors.ts";
20
21
 
21
22
  export interface DiscoveredWorkflow {
22
23
  name: string;
@@ -248,47 +249,120 @@ export async function findWorkflow(
248
249
  return all.find((w) => w.name === name) ?? null;
249
250
  }
250
251
 
252
+ /**
253
+ * Load status for a {@link WorkflowWithMetadata} entry.
254
+ *
255
+ * - `ok` — the workflow compiled cleanly and is ready to run.
256
+ * - `incompatible` — the workflow declared a `minSDKVersion` newer
257
+ * than the bundled CLI. The CLI renders it with an
258
+ * "update required" badge so users see the mismatch
259
+ * rather than a silent disappearance.
260
+ * - `error` — any other load failure (syntax error, missing
261
+ * `.compile()`, invalid default export, etc.).
262
+ * Rendered with a "failed to load" badge plus the
263
+ * underlying message.
264
+ */
265
+ export type WorkflowMetadataStatus =
266
+ | { kind: "ok" }
267
+ | {
268
+ kind: "incompatible";
269
+ requiredVersion: string;
270
+ currentVersion: string;
271
+ message: string;
272
+ }
273
+ | {
274
+ kind: "error";
275
+ stage: "resolve" | "validate" | "load";
276
+ message: string;
277
+ };
278
+
251
279
  /**
252
280
  * A discovered workflow enriched with the metadata the picker needs to
253
- * render it: the human description and the declared input schema.
281
+ * render it: the human description, the declared input schema, and the
282
+ * load status.
254
283
  *
255
284
  * Populated by {@link loadWorkflowsMetadata}, which runs each discovered
256
- * workflow through {@link WorkflowLoader.loadWorkflow} and extracts just
257
- * the display-relevant fields — the full compiled definition is
258
- * discarded after extraction so re-imports during execution are cheap.
285
+ * workflow through {@link WorkflowLoader.loadWorkflow} and extracts the
286
+ * display-relevant fields — the full compiled definition is discarded
287
+ * after extraction so re-imports during execution are cheap.
288
+ *
289
+ * Broken entries still materialise with empty `description` / `inputs`
290
+ * and a non-`ok` {@link status}, so the picker can render them as
291
+ * visible "update required" / "failed to load" rows instead of
292
+ * silently omitting them (the previous behaviour, which made user and
293
+ * global workflows vanish whenever the base SDK shape drifted between
294
+ * releases).
259
295
  */
260
296
  export interface WorkflowWithMetadata extends DiscoveredWorkflow {
261
- /** Workflow description, empty string when none was declared. */
297
+ /** Workflow description, empty string when none was declared or the workflow failed to load. */
262
298
  description: string;
263
- /** Picker-ready input schema; free-form workflows materialize a prompt field. */
299
+ /** Picker-ready input schema; empty for free-form or failed-to-load workflows. */
264
300
  inputs: readonly WorkflowInput[];
301
+ /** Load outcome — non-`ok` entries are rendered as visible diagnostics in the picker/list. */
302
+ status: WorkflowMetadataStatus;
265
303
  }
266
304
 
267
305
  /**
268
- * Load metadata (description + picker-ready inputs) for a batch of discovered workflows.
306
+ * Load metadata (description + picker-ready inputs + status) for a batch
307
+ * of discovered workflows.
269
308
  *
270
- * Workflows that fail to import are **skipped silently** so one broken
271
- * entry can never prevent the picker from rendering. Callers that need
272
- * to surface load errors (e.g. `atomic workflow -n broken`) should use
273
- * {@link WorkflowLoader.loadWorkflow} directly that path produces
274
- * structured error reports.
309
+ * **Failed workflows are kept in the returned list**, not dropped. Each
310
+ * broken entry carries a {@link WorkflowMetadataStatus} explaining the
311
+ * failure so the picker and `atomic workflow -l` can surface it as an
312
+ * actionable diagnostic. This is the only way end users discover that a
313
+ * workflow from an older SDK release has gone incompatible after an
314
+ * `atomic` upgrade — silent filtering would leave them with a missing
315
+ * entry and no breadcrumb.
316
+ *
317
+ * Callers that want to execute a workflow should still route through
318
+ * {@link WorkflowLoader.loadWorkflow} — this function throws away the
319
+ * compiled definition so re-running the loader on a confirmed pick is
320
+ * unavoidable.
275
321
  */
276
322
  export async function loadWorkflowsMetadata(
277
323
  discovered: DiscoveredWorkflow[],
278
324
  ): Promise<WorkflowWithMetadata[]> {
279
- const results = await Promise.all(
280
- discovered.map(async (wf): Promise<WorkflowWithMetadata | null> => {
325
+ return Promise.all(
326
+ discovered.map(async (wf): Promise<WorkflowWithMetadata> => {
281
327
  const loaded = await WorkflowLoader.loadWorkflow(wf);
282
- if (!loaded.ok) return null;
328
+ if (loaded.ok) {
329
+ return {
330
+ ...wf,
331
+ description: loaded.value.definition.description,
332
+ inputs: loaded.value.definition.inputs,
333
+ status: { kind: "ok" },
334
+ };
335
+ }
336
+
337
+ // Incompatible SDK version is a first-class status so the UI can
338
+ // show a dedicated "update required" hint. Every other failure
339
+ // maps to a generic `error` variant — the picker renders the
340
+ // message but doesn't try to interpret it further.
341
+ if (loaded.error instanceof IncompatibleSDKError) {
342
+ return {
343
+ ...wf,
344
+ description: "",
345
+ inputs: [],
346
+ status: {
347
+ kind: "incompatible",
348
+ requiredVersion: loaded.error.requiredVersion,
349
+ currentVersion: loaded.error.currentVersion,
350
+ message: loaded.message,
351
+ },
352
+ };
353
+ }
354
+
283
355
  return {
284
356
  ...wf,
285
- description: loaded.value.definition.description,
286
- inputs: loaded.value.definition.inputs,
357
+ description: "",
358
+ inputs: [],
359
+ status: {
360
+ kind: "error",
361
+ stage: loaded.stage,
362
+ message: loaded.message,
363
+ },
287
364
  };
288
365
  }),
289
366
  );
290
- return results.filter(
291
- (r): r is WorkflowWithMetadata => r !== null,
292
- );
293
367
  }
294
368
 
@@ -12,10 +12,17 @@
12
12
 
13
13
  import type { WorkflowDefinition, AgentType } from "../types.ts";
14
14
  import type { DiscoveredWorkflow } from "./discovery.ts";
15
- import { errorMessage, WorkflowNotCompiledError, InvalidWorkflowError } from "../errors.ts";
15
+ import {
16
+ errorMessage,
17
+ WorkflowNotCompiledError,
18
+ InvalidWorkflowError,
19
+ IncompatibleSDKError,
20
+ } from "../errors.ts";
16
21
  import { validateCopilotWorkflow } from "../providers/copilot.ts";
17
22
  import { validateOpenCodeWorkflow } from "../providers/opencode.ts";
18
23
  import { validateClaudeWorkflow } from "../providers/claude.ts";
24
+ import { satisfiesMinVersion } from "./version-compat.ts";
25
+ import { VERSION } from "../../version.ts";
19
26
 
20
27
  export namespace WorkflowLoader {
21
28
  // ---------------------------------------------------------------------------
@@ -180,9 +187,29 @@ export namespace WorkflowLoader {
180
187
  };
181
188
  }
182
189
 
190
+ const def = definition as WorkflowDefinition;
191
+
192
+ // Refuse workflows whose declared minSDKVersion is newer than the
193
+ // bundled CLI — the workflow author opted in to a version gate
194
+ // exactly so the loader could surface a clear upgrade hint
195
+ // instead of letting a shape-drift error bubble up at run time.
196
+ if (!satisfiesMinVersion(VERSION, def.minSDKVersion)) {
197
+ const err = new IncompatibleSDKError(
198
+ validated.path,
199
+ def.minSDKVersion ?? "",
200
+ VERSION,
201
+ );
202
+ return {
203
+ ok: false,
204
+ stage: "load",
205
+ error: err,
206
+ message: err.message,
207
+ };
208
+ }
209
+
183
210
  return {
184
211
  ok: true,
185
- value: { ...validated, definition: definition as WorkflowDefinition },
212
+ value: { ...validated, definition: def },
186
213
  };
187
214
  } catch (error) {
188
215
  return {
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Tiny semver comparator used to check a workflow's declared
3
+ * `minSDKVersion` against the bundled CLI {@link VERSION}.
4
+ *
5
+ * Accepts the subset of semver we actually ship: `MAJOR.MINOR.PATCH`
6
+ * with an optional numeric prerelease (e.g. `0.5.21`, `0.5.21-0`).
7
+ * Anything more exotic (build metadata, alpha tags) is treated as a
8
+ * plain string and compared lexicographically on the prerelease tail,
9
+ * which is good enough for "is the installed CLI new enough?".
10
+ *
11
+ * Isolated from the `semver` npm package so the workflow loader stays
12
+ * dependency-free — this check runs for every discovered workflow on
13
+ * every CLI launch.
14
+ */
15
+
16
+ interface ParsedVersion {
17
+ major: number;
18
+ minor: number;
19
+ patch: number;
20
+ prerelease: string;
21
+ }
22
+
23
+ function parseVersion(v: string): ParsedVersion | null {
24
+ const match = /^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/.exec(v.trim());
25
+ if (!match) return null;
26
+ return {
27
+ major: Number(match[1]),
28
+ minor: Number(match[2]),
29
+ patch: Number(match[3]),
30
+ prerelease: match[4] ?? "",
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Return a negative number if `a < b`, positive if `a > b`, 0 if equal.
36
+ * Unparseable inputs compare as equal so we never block a workflow over
37
+ * a typo in its `minSDKVersion` — the visible load error is friendlier
38
+ * than a hard refusal.
39
+ */
40
+ export function compareVersions(a: string, b: string): number {
41
+ const pa = parseVersion(a);
42
+ const pb = parseVersion(b);
43
+ if (!pa || !pb) return 0;
44
+
45
+ if (pa.major !== pb.major) return pa.major - pb.major;
46
+ if (pa.minor !== pb.minor) return pa.minor - pb.minor;
47
+ if (pa.patch !== pb.patch) return pa.patch - pb.patch;
48
+
49
+ // Per semver, a version without a prerelease outranks one with a
50
+ // prerelease at the same MAJOR.MINOR.PATCH (1.0.0 > 1.0.0-0).
51
+ if (pa.prerelease === "" && pb.prerelease !== "") return 1;
52
+ if (pa.prerelease !== "" && pb.prerelease === "") return -1;
53
+ if (pa.prerelease === pb.prerelease) return 0;
54
+ return pa.prerelease < pb.prerelease ? -1 : 1;
55
+ }
56
+
57
+ /**
58
+ * True when the current CLI is new enough to run a workflow that
59
+ * declared `minRequired`. A null/undefined requirement always
60
+ * satisfies — workflows that don't opt in are treated as compatible.
61
+ */
62
+ export function satisfiesMinVersion(
63
+ current: string,
64
+ minRequired: string | null | undefined,
65
+ ): boolean {
66
+ if (!minRequired) return true;
67
+ return compareVersions(current, minRequired) >= 0;
68
+ }
package/src/sdk/types.ts CHANGED
@@ -366,6 +366,22 @@ export interface WorkflowOptions<
366
366
  * and enforce them on `ctx.inputs`.
367
367
  */
368
368
  inputs?: I;
369
+ /**
370
+ * Minimum Atomic CLI version this workflow is known to work with.
371
+ *
372
+ * When set, the CLI refuses to load the workflow on an older install
373
+ * and surfaces an actionable "update required" entry in the picker
374
+ * and `atomic workflow -l` output instead of silently dropping it.
375
+ *
376
+ * Leave unset (the default) to opt out entirely — the workflow will
377
+ * be treated as compatible with every CLI version. Use this when you
378
+ * consume a new SDK feature (new provider API, a new field on the
379
+ * stage options, etc.) that older installs can't honour.
380
+ *
381
+ * Accepts `MAJOR.MINOR.PATCH` with an optional numeric prerelease
382
+ * (`0.6.0`, `0.6.0-0`). Invalid strings are ignored.
383
+ */
384
+ minSDKVersion?: string;
369
385
  }
370
386
 
371
387
  /**
@@ -377,6 +393,11 @@ export interface WorkflowDefinition<A extends AgentType = AgentType, N extends s
377
393
  readonly description: string;
378
394
  /** Declared input schema — empty array for free-form workflows. */
379
395
  readonly inputs: readonly WorkflowInput[];
396
+ /**
397
+ * Minimum Atomic SDK version required. `null` when the workflow
398
+ * declared no requirement — treated as compatible with every CLI.
399
+ */
400
+ readonly minSDKVersion: string | null;
380
401
  /** The workflow's entry point. Called by the executor with a WorkflowContext. */
381
402
  readonly run: (ctx: WorkflowContext<A, N>) => Promise<void>;
382
403
  }
@@ -105,6 +105,7 @@ export {
105
105
  export type {
106
106
  DiscoveredWorkflow,
107
107
  WorkflowWithMetadata,
108
+ WorkflowMetadataStatus,
108
109
  } from "../runtime/discovery.ts";
109
110
 
110
111
  // Runtime — workflow loader pipeline