@openspecui/core 2.3.6 → 3.0.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.
@@ -1,2 +1,2 @@
1
- import { a as HostedBackendHealthResponse, c as buildHostedVersionManifestUrl, d as normalizeHostedAppBaseUrl, f as resolveHostedAppBaseUrl, i as HostedAppVersionManifest, l as isHostedAppVersionManifest, n as HostedAppChannelManifest, o as OFFICIAL_APP_BASE_URL, p as resolveHostedChannelForVersion, r as HostedAppCompatibilityEntry, s as buildHostedLaunchUrl, t as HostedAppChannelKind, u as isHostedBackendHealthResponse } from "./hosted-app-BP6Xje0B.mjs";
1
+ import { a as HostedBackendHealthResponse, c as buildHostedVersionManifestUrl, d as normalizeHostedAppBaseUrl, f as resolveHostedAppBaseUrl, i as HostedAppVersionManifest, l as isHostedAppVersionManifest, n as HostedAppChannelManifest, o as OFFICIAL_APP_BASE_URL, p as resolveHostedChannelForVersion, r as HostedAppCompatibilityEntry, s as buildHostedLaunchUrl, t as HostedAppChannelKind, u as isHostedBackendHealthResponse } from "./hosted-app-Dy4D7wV9.mjs";
2
2
  export { HostedAppChannelKind, HostedAppChannelManifest, HostedAppCompatibilityEntry, HostedAppVersionManifest, HostedBackendHealthResponse, OFFICIAL_APP_BASE_URL, buildHostedLaunchUrl, buildHostedVersionManifestUrl, isHostedAppVersionManifest, isHostedBackendHealthResponse, normalizeHostedAppBaseUrl, resolveHostedAppBaseUrl, resolveHostedChannelForVersion };
@@ -1,3 +1,3 @@
1
- import { a as isHostedBackendHealthResponse, c as resolveHostedChannelForVersion, i as isHostedAppVersionManifest, n as buildHostedLaunchUrl, o as normalizeHostedAppBaseUrl, r as buildHostedVersionManifestUrl, s as resolveHostedAppBaseUrl, t as OFFICIAL_APP_BASE_URL } from "./hosted-app-C1JDznip.mjs";
1
+ import { a as isHostedBackendHealthResponse, c as resolveHostedChannelForVersion, i as isHostedAppVersionManifest, n as buildHostedLaunchUrl, o as normalizeHostedAppBaseUrl, r as buildHostedVersionManifestUrl, s as resolveHostedAppBaseUrl, t as OFFICIAL_APP_BASE_URL } from "./hosted-app-Bv10mEdq.mjs";
2
2
 
3
3
  export { OFFICIAL_APP_BASE_URL, buildHostedLaunchUrl, buildHostedVersionManifestUrl, isHostedAppVersionManifest, isHostedBackendHealthResponse, normalizeHostedAppBaseUrl, resolveHostedAppBaseUrl, resolveHostedChannelForVersion };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as HostedBackendHealthResponse, c as buildHostedVersionManifestUrl, d as normalizeHostedAppBaseUrl, f as resolveHostedAppBaseUrl, i as HostedAppVersionManifest, l as isHostedAppVersionManifest, n as HostedAppChannelManifest, o as OFFICIAL_APP_BASE_URL, p as resolveHostedChannelForVersion, r as HostedAppCompatibilityEntry, s as buildHostedLaunchUrl, t as HostedAppChannelKind, u as isHostedBackendHealthResponse } from "./hosted-app-BP6Xje0B.mjs";
2
- import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-Cb-CVa6h.mjs";
1
+ import { a as HostedBackendHealthResponse, c as buildHostedVersionManifestUrl, d as normalizeHostedAppBaseUrl, f as resolveHostedAppBaseUrl, i as HostedAppVersionManifest, l as isHostedAppVersionManifest, n as HostedAppChannelManifest, o as OFFICIAL_APP_BASE_URL, p as resolveHostedChannelForVersion, r as HostedAppCompatibilityEntry, s as buildHostedLaunchUrl, t as HostedAppChannelKind, u as isHostedBackendHealthResponse } from "./hosted-app-Dy4D7wV9.mjs";
2
+ import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-C1H1ryBL.mjs";
3
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
4
  import { z } from "zod";
5
5
  import { EventEmitter } from "events";
@@ -1763,6 +1763,8 @@ interface AIToolOption {
1763
1763
  successLabel?: string;
1764
1764
  /** 技能目录(相对项目根目录) */
1765
1765
  skillsDir?: string;
1766
+ /** 自动检测路径;存在任一路径即表示项目已有该工具配置 */
1767
+ detectionPaths?: string[];
1766
1768
  }
1767
1769
  /**
1768
1770
  * 完整的工具配置(元信息 + skills 目录)
@@ -1841,6 +1843,7 @@ interface ToolInitState {
1841
1843
  missingCommandWorkflows: ToolWorkflowId[];
1842
1844
  unexpectedSkillWorkflows: ToolWorkflowId[];
1843
1845
  unexpectedCommandWorkflows: ToolWorkflowId[];
1846
+ legacyCommandWorkflows: ToolWorkflowId[];
1844
1847
  }
1845
1848
  declare function getToolInitStates(projectDir: string, options: {
1846
1849
  delivery: ToolInitDelivery;
@@ -2048,11 +2051,12 @@ declare const ApplyTaskSchema: z.ZodObject<{
2048
2051
  done: boolean;
2049
2052
  }>;
2050
2053
  type ApplyTask = z.infer<typeof ApplyTaskSchema>;
2054
+ declare const ApplyInstructionsContextFilesSchema: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, string[], string | string[]>>;
2051
2055
  declare const ApplyInstructionsSchema: z.ZodObject<{
2052
2056
  changeName: z.ZodString;
2053
2057
  changeDir: z.ZodString;
2054
2058
  schemaName: z.ZodString;
2055
- contextFiles: z.ZodRecord<z.ZodString, z.ZodString>;
2059
+ contextFiles: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, string[], string | string[]>>;
2056
2060
  progress: z.ZodObject<{
2057
2061
  total: z.ZodNumber;
2058
2062
  complete: z.ZodNumber;
@@ -2096,7 +2100,7 @@ declare const ApplyInstructionsSchema: z.ZodObject<{
2096
2100
  changeName: string;
2097
2101
  schemaName: string;
2098
2102
  changeDir: string;
2099
- contextFiles: Record<string, string>;
2103
+ contextFiles: Record<string, string[]>;
2100
2104
  state: "ready" | "blocked" | "all_done";
2101
2105
  instruction: string;
2102
2106
  missingArtifacts?: string[] | undefined;
@@ -2114,7 +2118,7 @@ declare const ApplyInstructionsSchema: z.ZodObject<{
2114
2118
  changeName: string;
2115
2119
  schemaName: string;
2116
2120
  changeDir: string;
2117
- contextFiles: Record<string, string>;
2121
+ contextFiles: Record<string, string | string[]>;
2118
2122
  state: "ready" | "blocked" | "all_done";
2119
2123
  instruction: string;
2120
2124
  missingArtifacts?: string[] | undefined;
@@ -3145,4 +3149,4 @@ type PtyServerMessage = z.infer<typeof PtyServerMessageSchema>;
3145
3149
  type PtySessionInfo = z.infer<typeof PtySessionInfoSchema>;
3146
3150
  type PtyPlatform = z.infer<typeof PtyPlatformSchema>;
3147
3151
  //#endregion
3148
- export { type AIToolOption, AI_TOOLS, type ApplyInstructions, ApplyInstructionsSchema, type ApplyTask, ApplyTaskSchema, type ArchiveMeta, type ArtifactInstructions, ArtifactInstructionsSchema, type ArtifactStatus, ArtifactStatusSchema, CODE_EDITOR_THEME_VALUES, type Change, type ChangeFile, ChangeFileSchema, type ChangeMeta, ChangeSchema, type ChangeStatus, ChangeStatusSchema, CliExecutor, type CliResult, type CliRunnerAttempt, type CliSniffResult, type CliStreamEvent, type CodeEditorTheme, CodeEditorThemeSchema, ConfigManager, DASHBOARD_METRIC_KEYS, DEFAULT_CONFIG, DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET, type DashboardCardAvailability, type DashboardConfig, DashboardConfigSchema, type DashboardGitCommitEntry, type DashboardGitDiffStats, type DashboardGitEntry, type DashboardGitSnapshot, type DashboardGitUncommittedEntry, type DashboardGitWorktree, type DashboardMetricKey, type DashboardOverview, type DashboardSummary, type DashboardTrendKind, type DashboardTrendMeta, type DashboardTrendPoint, type DashboardTriColorTrendPoint, type Delta, type DeltaOperation, DeltaOperationType, DeltaSchema, type DeltaSpec, DeltaSpecSchema, type DependencyInfo, DependencyInfoSchema, type ExportSnapshot, type FileChangeEvent, type FileChangeType, type GitConfig, GitConfigSchema, type GitEntriesPage, type GitEntryCursor, type GitEntryDetail, type GitEntryFileDiff, type GitEntryFilePatch, type GitEntryFileSource, type GitEntryFileSummary, type GitEntryFiles, type GitEntryPatch, type GitEntrySelector, type GitEntryShell, type GitFileChangeType, type GitPatchFile, type GitPatchState, type GitWorktreeHandoff, type GitWorktreeOverview, type GitWorktreeSummary, type HostedAppChannelKind, type HostedAppChannelManifest, type HostedAppCompatibilityEntry, type HostedAppVersionManifest, type HostedBackendHealthResponse, MarkdownParser, OFFICIAL_APP_BASE_URL, OpenSpecAdapter, type OpenSpecUIConfig, OpenSpecUIConfigSchema, type OpenSpecUIConfigUpdate, OpenSpecWatcher, OpsxKernel, type PathCallback, type ProjectRecoveryStatus, type ProjectResidencyEvictionReason, type ProjectResidencyStatus, ProjectWatcher, type ProjectWatcherReinitializeReason, type ProjectWatcherRuntimeStatus, type ProjectWatcherRuntimeStatusListener, PtyAttachMessageSchema, PtyBufferResponseSchema, type PtyClientMessage, PtyClientMessageSchema, PtyCloseMessageSchema, PtyCreateMessageSchema, PtyCreatedResponseSchema, PtyErrorCodeSchema, PtyErrorResponseSchema, PtyExitResponseSchema, PtyInputMessageSchema, PtyListMessageSchema, PtyListResponseSchema, PtyOutputResponseSchema, type PtyPlatform, PtyPlatformSchema, PtyResizeMessageSchema, type PtyServerMessage, PtyServerMessageSchema, type PtySessionInfo, PtyTitleResponseSchema, ReactiveContext, ReactiveState, type ReactiveStateOptions, type Requirement, RequirementSchema, type ResolvedCliRunner, type SchemaArtifact, SchemaArtifactSchema, type SchemaDetail, SchemaDetailSchema, type SchemaInfo, SchemaInfoSchema, type SchemaResolution, SchemaResolutionSchema, type Spec, type SpecMeta, SpecSchema, TOOL_WORKFLOW_TO_SKILL_DIR, type Task, TaskSchema, type TemplateContentMap, type TemplatesMap, TemplatesSchema, type TerminalConfig, TerminalConfigSchema, type TerminalRendererEngine, TerminalRendererEngineSchema, type ToolConfig, type ToolInitDelivery, type ToolInitState, type ToolInitStatus, type ToolWorkflowId, VIRTUAL_PROJECT_DIRNAME, type ValidationIssue, type ValidationResult, Validator, type WatchEvent, type WatchEventType, type WatcherRuntimeStatus, acquireWatcher, buildCliRunnerCandidates, buildHostedLaunchUrl, buildHostedVersionManifestUrl, clearCache, closeAllProjectWatchers, closeAllWatchers, contextStorage, createCleanCliEnv, createFileChangeObservable, getActiveWatcherCount, getAllToolIds, getAllTools, getAvailableToolIds, getAvailableTools, getCacheSize, getConfiguredTools, getDefaultCliCommand, getDefaultCliCommandString, getDetectedProjectTools, getProjectWatcher, getToolById, getToolInitStates, getWatchedProjectDir, getWatcherRuntimeStatus, initWatcherPool, isGlobPattern, isHostedAppVersionManifest, isHostedBackendHealthResponse, isTerminalRendererEngine, isToolConfigured, isWatcherPoolInitialized, normalizeHostedAppBaseUrl, parseCliCommand, reactiveExists, reactiveReadDir, reactiveReadFile, reactiveStat, resolveHostedAppBaseUrl, resolveHostedChannelForVersion, sniffGlobalCli, subscribeWatcherRuntimeStatus, toOpsxDisplayPath };
3152
+ export { type AIToolOption, AI_TOOLS, type ApplyInstructions, ApplyInstructionsContextFilesSchema, ApplyInstructionsSchema, type ApplyTask, ApplyTaskSchema, type ArchiveMeta, type ArtifactInstructions, ArtifactInstructionsSchema, type ArtifactStatus, ArtifactStatusSchema, CODE_EDITOR_THEME_VALUES, type Change, type ChangeFile, ChangeFileSchema, type ChangeMeta, ChangeSchema, type ChangeStatus, ChangeStatusSchema, CliExecutor, type CliResult, type CliRunnerAttempt, type CliSniffResult, type CliStreamEvent, type CodeEditorTheme, CodeEditorThemeSchema, ConfigManager, DASHBOARD_METRIC_KEYS, DEFAULT_CONFIG, DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET, type DashboardCardAvailability, type DashboardConfig, DashboardConfigSchema, type DashboardGitCommitEntry, type DashboardGitDiffStats, type DashboardGitEntry, type DashboardGitSnapshot, type DashboardGitUncommittedEntry, type DashboardGitWorktree, type DashboardMetricKey, type DashboardOverview, type DashboardSummary, type DashboardTrendKind, type DashboardTrendMeta, type DashboardTrendPoint, type DashboardTriColorTrendPoint, type Delta, type DeltaOperation, DeltaOperationType, DeltaSchema, type DeltaSpec, DeltaSpecSchema, type DependencyInfo, DependencyInfoSchema, type ExportSnapshot, type FileChangeEvent, type FileChangeType, type GitConfig, GitConfigSchema, type GitEntriesPage, type GitEntryCursor, type GitEntryDetail, type GitEntryFileDiff, type GitEntryFilePatch, type GitEntryFileSource, type GitEntryFileSummary, type GitEntryFiles, type GitEntryPatch, type GitEntrySelector, type GitEntryShell, type GitFileChangeType, type GitPatchFile, type GitPatchState, type GitWorktreeHandoff, type GitWorktreeOverview, type GitWorktreeSummary, type HostedAppChannelKind, type HostedAppChannelManifest, type HostedAppCompatibilityEntry, type HostedAppVersionManifest, type HostedBackendHealthResponse, MarkdownParser, OFFICIAL_APP_BASE_URL, OpenSpecAdapter, type OpenSpecUIConfig, OpenSpecUIConfigSchema, type OpenSpecUIConfigUpdate, OpenSpecWatcher, OpsxKernel, type PathCallback, type ProjectRecoveryStatus, type ProjectResidencyEvictionReason, type ProjectResidencyStatus, ProjectWatcher, type ProjectWatcherReinitializeReason, type ProjectWatcherRuntimeStatus, type ProjectWatcherRuntimeStatusListener, PtyAttachMessageSchema, PtyBufferResponseSchema, type PtyClientMessage, PtyClientMessageSchema, PtyCloseMessageSchema, PtyCreateMessageSchema, PtyCreatedResponseSchema, PtyErrorCodeSchema, PtyErrorResponseSchema, PtyExitResponseSchema, PtyInputMessageSchema, PtyListMessageSchema, PtyListResponseSchema, PtyOutputResponseSchema, type PtyPlatform, PtyPlatformSchema, PtyResizeMessageSchema, type PtyServerMessage, PtyServerMessageSchema, type PtySessionInfo, PtyTitleResponseSchema, ReactiveContext, ReactiveState, type ReactiveStateOptions, type Requirement, RequirementSchema, type ResolvedCliRunner, type SchemaArtifact, SchemaArtifactSchema, type SchemaDetail, SchemaDetailSchema, type SchemaInfo, SchemaInfoSchema, type SchemaResolution, SchemaResolutionSchema, type Spec, type SpecMeta, SpecSchema, TOOL_WORKFLOW_TO_SKILL_DIR, type Task, TaskSchema, type TemplateContentMap, type TemplatesMap, TemplatesSchema, type TerminalConfig, TerminalConfigSchema, type TerminalRendererEngine, TerminalRendererEngineSchema, type ToolConfig, type ToolInitDelivery, type ToolInitState, type ToolInitStatus, type ToolWorkflowId, VIRTUAL_PROJECT_DIRNAME, type ValidationIssue, type ValidationResult, Validator, type WatchEvent, type WatchEventType, type WatcherRuntimeStatus, acquireWatcher, buildCliRunnerCandidates, buildHostedLaunchUrl, buildHostedVersionManifestUrl, clearCache, closeAllProjectWatchers, closeAllWatchers, contextStorage, createCleanCliEnv, createFileChangeObservable, getActiveWatcherCount, getAllToolIds, getAllTools, getAvailableToolIds, getAvailableTools, getCacheSize, getConfiguredTools, getDefaultCliCommand, getDefaultCliCommandString, getDetectedProjectTools, getProjectWatcher, getToolById, getToolInitStates, getWatchedProjectDir, getWatcherRuntimeStatus, initWatcherPool, isGlobPattern, isHostedAppVersionManifest, isHostedBackendHealthResponse, isTerminalRendererEngine, isToolConfigured, isWatcherPoolInitialized, normalizeHostedAppBaseUrl, parseCliCommand, reactiveExists, reactiveReadDir, reactiveReadFile, reactiveStat, resolveHostedAppBaseUrl, resolveHostedChannelForVersion, sniffGlobalCli, subscribeWatcherRuntimeStatus, toOpsxDisplayPath };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { a as isHostedBackendHealthResponse, c as resolveHostedChannelForVersion, i as isHostedAppVersionManifest, n as buildHostedLaunchUrl, o as normalizeHostedAppBaseUrl, r as buildHostedVersionManifestUrl, s as resolveHostedAppBaseUrl, t as OFFICIAL_APP_BASE_URL } from "./hosted-app-C1JDznip.mjs";
2
- import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-DDK7QA5y.mjs";
1
+ import { a as isHostedBackendHealthResponse, c as resolveHostedChannelForVersion, i as isHostedAppVersionManifest, n as buildHostedLaunchUrl, o as normalizeHostedAppBaseUrl, r as buildHostedVersionManifestUrl, s as resolveHostedAppBaseUrl, t as OFFICIAL_APP_BASE_URL } from "./hosted-app-Bv10mEdq.mjs";
2
+ import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-Cja3Bt1P.mjs";
3
3
  import { mkdir, readFile, rename, writeFile } from "fs/promises";
4
4
  import { dirname, join } from "path";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -3213,6 +3213,13 @@ const AI_TOOLS = [
3213
3213
  successLabel: "Auggie",
3214
3214
  skillsDir: ".augment"
3215
3215
  },
3216
+ {
3217
+ name: "Bob Shell",
3218
+ value: "bob",
3219
+ available: true,
3220
+ successLabel: "Bob Shell",
3221
+ skillsDir: ".bob"
3222
+ },
3216
3223
  {
3217
3224
  name: "Claude Code",
3218
3225
  value: "claude",
@@ -3234,6 +3241,13 @@ const AI_TOOLS = [
3234
3241
  successLabel: "Codex",
3235
3242
  skillsDir: ".codex"
3236
3243
  },
3244
+ {
3245
+ name: "ForgeCode",
3246
+ value: "forgecode",
3247
+ available: true,
3248
+ successLabel: "ForgeCode",
3249
+ skillsDir: ".forge"
3250
+ },
3237
3251
  {
3238
3252
  name: "CodeBuddy Code (CLI)",
3239
3253
  value: "codebuddy",
@@ -3288,7 +3302,16 @@ const AI_TOOLS = [
3288
3302
  value: "github-copilot",
3289
3303
  available: true,
3290
3304
  successLabel: "GitHub Copilot",
3291
- skillsDir: ".github"
3305
+ skillsDir: ".github",
3306
+ detectionPaths: [
3307
+ ".github/copilot-instructions.md",
3308
+ ".github/instructions",
3309
+ ".github/workflows/copilot-setup-steps.yml",
3310
+ ".github/prompts",
3311
+ ".github/agents",
3312
+ ".github/skills",
3313
+ ".github/.mcp.json"
3314
+ ]
3292
3315
  },
3293
3316
  {
3294
3317
  name: "iFlow",
@@ -3297,6 +3320,13 @@ const AI_TOOLS = [
3297
3320
  successLabel: "iFlow",
3298
3321
  skillsDir: ".iflow"
3299
3322
  },
3323
+ {
3324
+ name: "Junie",
3325
+ value: "junie",
3326
+ available: true,
3327
+ successLabel: "Junie",
3328
+ skillsDir: ".junie"
3329
+ },
3300
3330
  {
3301
3331
  name: "Kilo Code",
3302
3332
  value: "kilocode",
@@ -3332,6 +3362,13 @@ const AI_TOOLS = [
3332
3362
  successLabel: "Qoder",
3333
3363
  skillsDir: ".qoder"
3334
3364
  },
3365
+ {
3366
+ name: "Lingma",
3367
+ value: "lingma",
3368
+ available: true,
3369
+ successLabel: "Lingma",
3370
+ skillsDir: ".lingma"
3371
+ },
3335
3372
  {
3336
3373
  name: "Qwen Code",
3337
3374
  value: "qwen",
@@ -3388,7 +3425,8 @@ function getAllTools() {
3388
3425
  async function getDetectedProjectTools(projectDir) {
3389
3426
  return (await Promise.all(AI_TOOLS.map(async (tool) => {
3390
3427
  if (!tool.skillsDir) return null;
3391
- return await reactiveExists(join$1(projectDir, tool.skillsDir)) ? tool : null;
3428
+ const detectionPaths = tool.detectionPaths && tool.detectionPaths.length > 0 ? tool.detectionPaths : [tool.skillsDir];
3429
+ return (await Promise.all(detectionPaths.map((path) => reactiveExists(join$1(projectDir, path))))).some(Boolean) ? tool : null;
3392
3430
  }))).filter((tool) => tool !== null);
3393
3431
  }
3394
3432
  /**
@@ -3494,33 +3532,45 @@ function resolveCodexHome() {
3494
3532
  const configuredHome = process.env.CODEX_HOME?.trim();
3495
3533
  return resolve(configuredHome ? configuredHome : join$1(homedir(), ".codex"));
3496
3534
  }
3497
- function resolveToolCommandPath(projectDir, toolId, workflow) {
3498
- switch (toolId) {
3499
- case "amazon-q": return resolve(projectDir, ".amazonq", "prompts", `opsx-${workflow}.md`);
3500
- case "antigravity": return resolve(projectDir, ".agent", "workflows", `opsx-${workflow}.md`);
3501
- case "auggie": return resolve(projectDir, ".augment", "commands", `opsx-${workflow}.md`);
3502
- case "claude": return resolve(projectDir, ".claude", "commands", "opsx", `${workflow}.md`);
3503
- case "cline": return resolve(projectDir, ".clinerules", "workflows", `opsx-${workflow}.md`);
3504
- case "codebuddy": return resolve(projectDir, ".codebuddy", "commands", "opsx", `${workflow}.md`);
3505
- case "codex": return resolve(resolveCodexHome(), "prompts", `opsx-${workflow}.md`);
3506
- case "continue": return resolve(projectDir, ".continue", "prompts", `opsx-${workflow}.prompt`);
3507
- case "costrict": return resolve(projectDir, ".cospec", "openspec", "commands", `opsx-${workflow}.md`);
3508
- case "crush": return resolve(projectDir, ".crush", "commands", "opsx", `${workflow}.md`);
3509
- case "cursor": return resolve(projectDir, ".cursor", "commands", `opsx-${workflow}.md`);
3510
- case "factory": return resolve(projectDir, ".factory", "commands", `opsx-${workflow}.md`);
3511
- case "gemini": return resolve(projectDir, ".gemini", "commands", "opsx", `${workflow}.toml`);
3512
- case "github-copilot": return resolve(projectDir, ".github", "prompts", `opsx-${workflow}.prompt.md`);
3513
- case "iflow": return resolve(projectDir, ".iflow", "commands", `opsx-${workflow}.md`);
3514
- case "kilocode": return resolve(projectDir, ".kilocode", "workflows", `opsx-${workflow}.md`);
3515
- case "kiro": return resolve(projectDir, ".kiro", "prompts", `opsx-${workflow}.prompt.md`);
3516
- case "opencode": return resolve(projectDir, ".opencode", "command", `opsx-${workflow}.md`);
3517
- case "pi": return resolve(projectDir, ".pi", "prompts", `opsx-${workflow}.md`);
3518
- case "qoder": return resolve(projectDir, ".qoder", "commands", "opsx", `${workflow}.md`);
3519
- case "qwen": return resolve(projectDir, ".qwen", "commands", `opsx-${workflow}.toml`);
3520
- case "roocode": return resolve(projectDir, ".roo", "commands", `opsx-${workflow}.md`);
3521
- case "windsurf": return resolve(projectDir, ".windsurf", "workflows", `opsx-${workflow}.md`);
3522
- default: return null;
3523
- }
3535
+ const TOOL_COMMAND_PATHS = {
3536
+ "amazon-q": { primary: (projectDir, workflow) => resolve(projectDir, ".amazonq", "prompts", `opsx-${workflow}.md`) },
3537
+ antigravity: { primary: (projectDir, workflow) => resolve(projectDir, ".agent", "workflows", `opsx-${workflow}.md`) },
3538
+ auggie: { primary: (projectDir, workflow) => resolve(projectDir, ".augment", "commands", `opsx-${workflow}.md`) },
3539
+ bob: { primary: (projectDir, workflow) => resolve(projectDir, ".bob", "commands", `opsx-${workflow}.md`) },
3540
+ claude: { primary: (projectDir, workflow) => resolve(projectDir, ".claude", "commands", "opsx", `${workflow}.md`) },
3541
+ cline: { primary: (projectDir, workflow) => resolve(projectDir, ".clinerules", "workflows", `opsx-${workflow}.md`) },
3542
+ codebuddy: { primary: (projectDir, workflow) => resolve(projectDir, ".codebuddy", "commands", "opsx", `${workflow}.md`) },
3543
+ codex: { primary: (_projectDir, workflow) => resolve(resolveCodexHome(), "prompts", `opsx-${workflow}.md`) },
3544
+ continue: { primary: (projectDir, workflow) => resolve(projectDir, ".continue", "prompts", `opsx-${workflow}.prompt`) },
3545
+ costrict: { primary: (projectDir, workflow) => resolve(projectDir, ".cospec", "openspec", "commands", `opsx-${workflow}.md`) },
3546
+ crush: { primary: (projectDir, workflow) => resolve(projectDir, ".crush", "commands", "opsx", `${workflow}.md`) },
3547
+ cursor: { primary: (projectDir, workflow) => resolve(projectDir, ".cursor", "commands", `opsx-${workflow}.md`) },
3548
+ factory: { primary: (projectDir, workflow) => resolve(projectDir, ".factory", "commands", `opsx-${workflow}.md`) },
3549
+ gemini: { primary: (projectDir, workflow) => resolve(projectDir, ".gemini", "commands", "opsx", `${workflow}.toml`) },
3550
+ "github-copilot": { primary: (projectDir, workflow) => resolve(projectDir, ".github", "prompts", `opsx-${workflow}.prompt.md`) },
3551
+ iflow: { primary: (projectDir, workflow) => resolve(projectDir, ".iflow", "commands", `opsx-${workflow}.md`) },
3552
+ junie: { primary: (projectDir, workflow) => resolve(projectDir, ".junie", "commands", `opsx-${workflow}.md`) },
3553
+ kilocode: { primary: (projectDir, workflow) => resolve(projectDir, ".kilocode", "workflows", `opsx-${workflow}.md`) },
3554
+ kiro: { primary: (projectDir, workflow) => resolve(projectDir, ".kiro", "prompts", `opsx-${workflow}.prompt.md`) },
3555
+ lingma: { primary: (projectDir, workflow) => resolve(projectDir, ".lingma", "commands", "opsx", `${workflow}.md`) },
3556
+ opencode: {
3557
+ primary: (projectDir, workflow) => resolve(projectDir, ".opencode", "commands", `opsx-${workflow}.md`),
3558
+ legacy: [(projectDir, workflow) => resolve(projectDir, ".opencode", "command", `opsx-${workflow}.md`)]
3559
+ },
3560
+ pi: { primary: (projectDir, workflow) => resolve(projectDir, ".pi", "prompts", `opsx-${workflow}.md`) },
3561
+ qoder: { primary: (projectDir, workflow) => resolve(projectDir, ".qoder", "commands", "opsx", `${workflow}.md`) },
3562
+ qwen: { primary: (projectDir, workflow) => resolve(projectDir, ".qwen", "commands", `opsx-${workflow}.toml`) },
3563
+ roocode: { primary: (projectDir, workflow) => resolve(projectDir, ".roo", "commands", `opsx-${workflow}.md`) },
3564
+ windsurf: { primary: (projectDir, workflow) => resolve(projectDir, ".windsurf", "workflows", `opsx-${workflow}.md`) }
3565
+ };
3566
+ function resolveToolCommandArtifact(projectDir, toolId, workflow) {
3567
+ const config = TOOL_COMMAND_PATHS[toolId];
3568
+ if (!config) return null;
3569
+ return {
3570
+ workflow,
3571
+ path: config.primary(projectDir, workflow),
3572
+ legacyPaths: config.legacy?.map((resolvePath) => resolvePath(projectDir, workflow))
3573
+ };
3524
3574
  }
3525
3575
  function getSkillArtifacts(projectDir, skillsDir) {
3526
3576
  return ALL_TOOL_WORKFLOWS.map((workflow) => ({
@@ -3530,39 +3580,46 @@ function getSkillArtifacts(projectDir, skillsDir) {
3530
3580
  }
3531
3581
  function getCommandArtifacts(projectDir, toolId) {
3532
3582
  return ALL_TOOL_WORKFLOWS.flatMap((workflow) => {
3533
- const path = resolveToolCommandPath(projectDir, toolId, workflow);
3534
- return path ? [{
3535
- workflow,
3536
- path
3537
- }] : [];
3583
+ const artifact = resolveToolCommandArtifact(projectDir, toolId, workflow);
3584
+ return artifact ? [artifact] : [];
3538
3585
  });
3539
3586
  }
3540
3587
  function invalidateToolInitCaches(projectDir) {
3541
3588
  const cacheRoots = /* @__PURE__ */ new Set();
3542
3589
  for (const tool of AI_TOOLS) {
3543
3590
  if (tool.skillsDir) cacheRoots.add(resolve(projectDir, tool.skillsDir));
3544
- for (const workflow of ALL_TOOL_WORKFLOWS) {
3545
- const commandPath = resolveToolCommandPath(projectDir, tool.value, workflow);
3546
- if (commandPath) cacheRoots.add(dirname$1(commandPath));
3591
+ for (const commandArtifact of getCommandArtifacts(projectDir, tool.value)) {
3592
+ cacheRoots.add(dirname$1(commandArtifact.path));
3593
+ for (const legacyPath of commandArtifact.legacyPaths ?? []) cacheRoots.add(dirname$1(legacyPath));
3547
3594
  }
3548
3595
  }
3549
3596
  for (const root of cacheRoots) clearCache(root);
3550
3597
  }
3551
3598
  async function getExistingArtifactPaths(entries) {
3552
- const presence = await Promise.all(entries.map(async (entry) => ({
3553
- path: entry.path,
3554
- exists: await reactiveExists(entry.path)
3599
+ const paths = entries.flatMap((entry) => [entry.path, ...entry.legacyPaths ?? []]);
3600
+ const presence = await Promise.all(paths.map(async (path) => ({
3601
+ path,
3602
+ exists: await reactiveExists(path)
3555
3603
  })));
3556
3604
  return new Set(presence.filter((entry) => entry.exists).map((entry) => entry.path));
3557
3605
  }
3606
+ function hasExistingArtifact(entry, existingPaths) {
3607
+ return existingPaths.has(entry.path) || (entry.legacyPaths?.some((legacyPath) => existingPaths.has(legacyPath)) ?? false);
3608
+ }
3609
+ function hasLegacyArtifact(entry, existingPaths) {
3610
+ return entry.legacyPaths?.some((legacyPath) => existingPaths.has(legacyPath)) ?? false;
3611
+ }
3558
3612
  function countExisting(entries, existingPaths) {
3559
- return entries.reduce((count, entry) => count + (existingPaths.has(entry.path) ? 1 : 0), 0);
3613
+ return entries.reduce((count, entry) => count + (hasExistingArtifact(entry, existingPaths) ? 1 : 0), 0);
3560
3614
  }
3561
3615
  function collectMissingWorkflows(entries, existingPaths) {
3562
- return entries.filter((entry) => !existingPaths.has(entry.path)).map((entry) => entry.workflow);
3616
+ return entries.filter((entry) => !hasExistingArtifact(entry, existingPaths)).map((entry) => entry.workflow);
3563
3617
  }
3564
3618
  function collectUnexpectedWorkflows(entries, desiredWorkflowSet, existingPaths) {
3565
- return entries.filter((entry) => !desiredWorkflowSet.has(entry.workflow) && existingPaths.has(entry.path)).map((entry) => entry.workflow);
3619
+ return entries.filter((entry) => !desiredWorkflowSet.has(entry.workflow) && hasExistingArtifact(entry, existingPaths)).map((entry) => entry.workflow);
3620
+ }
3621
+ function collectLegacyWorkflows(entries, existingPaths) {
3622
+ return entries.filter((entry) => hasLegacyArtifact(entry, existingPaths)).map((entry) => entry.workflow);
3566
3623
  }
3567
3624
  async function getToolInitStates(projectDir, options) {
3568
3625
  invalidateToolInitCaches(projectDir);
@@ -3581,6 +3638,7 @@ async function getToolInitStates(projectDir, options) {
3581
3638
  const missingCommandWorkflows = collectMissingWorkflows(expectedCommandArtifacts, existingCommandPaths);
3582
3639
  const unexpectedSkillWorkflows = collectUnexpectedWorkflows(shouldGenerateSkills ? skillArtifacts : skillArtifacts, shouldGenerateSkills ? desiredWorkflowSet : /* @__PURE__ */ new Set(), existingSkillPaths);
3583
3640
  const unexpectedCommandWorkflows = collectUnexpectedWorkflows(shouldGenerateCommands ? commandArtifacts : commandArtifacts, shouldGenerateCommands ? desiredWorkflowSet : /* @__PURE__ */ new Set(), existingCommandPaths);
3641
+ const legacyCommandWorkflows = collectLegacyWorkflows(commandArtifacts, existingCommandPaths);
3584
3642
  const expectedSkillCount = expectedSkillArtifacts.length;
3585
3643
  const presentExpectedSkillCount = expectedSkillCount - missingSkillWorkflows.length;
3586
3644
  const detectedSkillCount = countExisting(skillArtifacts, existingSkillPaths);
@@ -3603,7 +3661,8 @@ async function getToolInitStates(projectDir, options) {
3603
3661
  missingSkillWorkflows,
3604
3662
  missingCommandWorkflows,
3605
3663
  unexpectedSkillWorkflows,
3606
- unexpectedCommandWorkflows
3664
+ unexpectedCommandWorkflows,
3665
+ legacyCommandWorkflows
3607
3666
  };
3608
3667
  }));
3609
3668
  }
@@ -3654,11 +3713,13 @@ const ApplyTaskSchema = z.object({
3654
3713
  description: z.string(),
3655
3714
  done: z.boolean()
3656
3715
  });
3716
+ const ApplyInstructionsContextFilePathsSchema = z.union([z.string(), z.array(z.string())]).transform((paths) => Array.isArray(paths) ? paths : [paths]);
3717
+ const ApplyInstructionsContextFilesSchema = z.record(ApplyInstructionsContextFilePathsSchema);
3657
3718
  const ApplyInstructionsSchema = z.object({
3658
3719
  changeName: z.string(),
3659
3720
  changeDir: z.string(),
3660
3721
  schemaName: z.string(),
3661
- contextFiles: z.record(z.string()),
3722
+ contextFiles: ApplyInstructionsContextFilesSchema,
3662
3723
  progress: z.object({
3663
3724
  total: z.number(),
3664
3725
  complete: z.number(),
@@ -4514,4 +4575,4 @@ const PtyServerMessageSchema = z.discriminatedUnion("type", [
4514
4575
  ]);
4515
4576
 
4516
4577
  //#endregion
4517
- export { AI_TOOLS, ApplyInstructionsSchema, ApplyTaskSchema, ArtifactInstructionsSchema, ArtifactStatusSchema, CODE_EDITOR_THEME_VALUES, ChangeFileSchema, ChangeSchema, ChangeStatusSchema, CliExecutor, CodeEditorThemeSchema, ConfigManager, DASHBOARD_METRIC_KEYS, DEFAULT_CONFIG, DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET, DashboardConfigSchema, DeltaOperationType, DeltaSchema, DeltaSpecSchema, DependencyInfoSchema, GitConfigSchema, MarkdownParser, OFFICIAL_APP_BASE_URL, OpenSpecAdapter, OpenSpecUIConfigSchema, OpenSpecWatcher, OpsxKernel, ProjectWatcher, PtyAttachMessageSchema, PtyBufferResponseSchema, PtyClientMessageSchema, PtyCloseMessageSchema, PtyCreateMessageSchema, PtyCreatedResponseSchema, PtyErrorCodeSchema, PtyErrorResponseSchema, PtyExitResponseSchema, PtyInputMessageSchema, PtyListMessageSchema, PtyListResponseSchema, PtyOutputResponseSchema, PtyPlatformSchema, PtyResizeMessageSchema, PtyServerMessageSchema, PtyTitleResponseSchema, ReactiveContext, ReactiveState, RequirementSchema, SchemaArtifactSchema, SchemaDetailSchema, SchemaInfoSchema, SchemaResolutionSchema, SpecSchema, TOOL_WORKFLOW_TO_SKILL_DIR, TaskSchema, TemplatesSchema, TerminalConfigSchema, TerminalRendererEngineSchema, VIRTUAL_PROJECT_DIRNAME, Validator, acquireWatcher, buildCliRunnerCandidates, buildHostedLaunchUrl, buildHostedVersionManifestUrl, clearCache, closeAllProjectWatchers, closeAllWatchers, contextStorage, createCleanCliEnv, createFileChangeObservable, getActiveWatcherCount, getAllToolIds, getAllTools, getAvailableToolIds, getAvailableTools, getCacheSize, getConfiguredTools, getDefaultCliCommand, getDefaultCliCommandString, getDetectedProjectTools, getProjectWatcher, getToolById, getToolInitStates, getWatchedProjectDir, getWatcherRuntimeStatus, initWatcherPool, isGlobPattern, isHostedAppVersionManifest, isHostedBackendHealthResponse, isTerminalRendererEngine, isToolConfigured, isWatcherPoolInitialized, normalizeHostedAppBaseUrl, parseCliCommand, reactiveExists, reactiveReadDir, reactiveReadFile, reactiveStat, resolveHostedAppBaseUrl, resolveHostedChannelForVersion, sniffGlobalCli, subscribeWatcherRuntimeStatus, toOpsxDisplayPath };
4578
+ export { AI_TOOLS, ApplyInstructionsContextFilesSchema, ApplyInstructionsSchema, ApplyTaskSchema, ArtifactInstructionsSchema, ArtifactStatusSchema, CODE_EDITOR_THEME_VALUES, ChangeFileSchema, ChangeSchema, ChangeStatusSchema, CliExecutor, CodeEditorThemeSchema, ConfigManager, DASHBOARD_METRIC_KEYS, DEFAULT_CONFIG, DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET, DashboardConfigSchema, DeltaOperationType, DeltaSchema, DeltaSpecSchema, DependencyInfoSchema, GitConfigSchema, MarkdownParser, OFFICIAL_APP_BASE_URL, OpenSpecAdapter, OpenSpecUIConfigSchema, OpenSpecWatcher, OpsxKernel, ProjectWatcher, PtyAttachMessageSchema, PtyBufferResponseSchema, PtyClientMessageSchema, PtyCloseMessageSchema, PtyCreateMessageSchema, PtyCreatedResponseSchema, PtyErrorCodeSchema, PtyErrorResponseSchema, PtyExitResponseSchema, PtyInputMessageSchema, PtyListMessageSchema, PtyListResponseSchema, PtyOutputResponseSchema, PtyPlatformSchema, PtyResizeMessageSchema, PtyServerMessageSchema, PtyTitleResponseSchema, ReactiveContext, ReactiveState, RequirementSchema, SchemaArtifactSchema, SchemaDetailSchema, SchemaInfoSchema, SchemaResolutionSchema, SpecSchema, TOOL_WORKFLOW_TO_SKILL_DIR, TaskSchema, TemplatesSchema, TerminalConfigSchema, TerminalRendererEngineSchema, VIRTUAL_PROJECT_DIRNAME, Validator, acquireWatcher, buildCliRunnerCandidates, buildHostedLaunchUrl, buildHostedVersionManifestUrl, clearCache, closeAllProjectWatchers, closeAllWatchers, contextStorage, createCleanCliEnv, createFileChangeObservable, getActiveWatcherCount, getAllToolIds, getAllTools, getAvailableToolIds, getAvailableTools, getCacheSize, getConfiguredTools, getDefaultCliCommand, getDefaultCliCommandString, getDetectedProjectTools, getProjectWatcher, getToolById, getToolInitStates, getWatchedProjectDir, getWatcherRuntimeStatus, initWatcherPool, isGlobPattern, isHostedAppVersionManifest, isHostedBackendHealthResponse, isTerminalRendererEngine, isToolConfigured, isWatcherPoolInitialized, normalizeHostedAppBaseUrl, parseCliCommand, reactiveExists, reactiveReadDir, reactiveReadFile, reactiveStat, resolveHostedAppBaseUrl, resolveHostedChannelForVersion, sniffGlobalCli, subscribeWatcherRuntimeStatus, toOpsxDisplayPath };
@@ -0,0 +1,32 @@
1
+ //#region src/openspec-compat.d.ts
2
+ declare const OPENSPECUI_TARGET_MAJOR = 3;
3
+ declare const OPENSPEC_CLI_TARGET_SERIES = "1.3";
4
+ declare const OPENSPEC_CLI_LEGACY_SERIES = "1.2";
5
+ declare const OPENSPEC_CLI_MIN_VERSION = "1.2.0";
6
+ declare const OPENSPEC_CLI_TARGET_MIN_VERSION = "1.3.0";
7
+ declare const OPENSPEC_CLI_NEXT_SERIES_MIN_VERSION = "1.4.0";
8
+ declare const OPENSPEC_CLI_ACCEPTED_RANGE = ">=1.2.0 <1.4.0";
9
+ declare const OPENSPEC_CLI_RECOMMENDED_RANGE = ">=1.3.0 <1.4.0";
10
+ declare const OPENSPEC_CLI_LEGACY_RANGE = ">=1.2.0 <1.3.0";
11
+ declare const OPENSPEC_CLI_REFERENCE_TAG_PATTERN = "v1.3.*";
12
+ interface OpenSpecCliVersion {
13
+ major: number;
14
+ minor: number;
15
+ patch: number;
16
+ }
17
+ type OpenSpecCliCompatibilityStatus = 'current' | 'legacy-compatible' | 'unsupported' | 'unknown';
18
+ interface OpenSpecCliCompatibility {
19
+ rawVersion: string | undefined;
20
+ version: OpenSpecCliVersion | null;
21
+ status: OpenSpecCliCompatibilityStatus;
22
+ supported: boolean;
23
+ recommended: boolean;
24
+ blocksCoreInteractions: boolean;
25
+ message: string;
26
+ }
27
+ declare function parseOpenSpecCliVersion(raw: string | undefined): OpenSpecCliVersion | null;
28
+ declare function formatOpenSpecCliVersion(version: OpenSpecCliVersion): string;
29
+ declare function compareOpenSpecCliVersions(left: OpenSpecCliVersion, right: OpenSpecCliVersion): number;
30
+ declare function classifyOpenSpecCliVersion(rawVersion: string | undefined): OpenSpecCliCompatibility;
31
+ //#endregion
32
+ export { OPENSPECUI_TARGET_MAJOR, OPENSPEC_CLI_ACCEPTED_RANGE, OPENSPEC_CLI_LEGACY_RANGE, OPENSPEC_CLI_LEGACY_SERIES, OPENSPEC_CLI_MIN_VERSION, OPENSPEC_CLI_NEXT_SERIES_MIN_VERSION, OPENSPEC_CLI_RECOMMENDED_RANGE, OPENSPEC_CLI_REFERENCE_TAG_PATTERN, OPENSPEC_CLI_TARGET_MIN_VERSION, OPENSPEC_CLI_TARGET_SERIES, OpenSpecCliCompatibility, OpenSpecCliCompatibilityStatus, OpenSpecCliVersion, classifyOpenSpecCliVersion, compareOpenSpecCliVersions, formatOpenSpecCliVersion, parseOpenSpecCliVersion };
@@ -0,0 +1,75 @@
1
+ //#region src/openspec-compat.ts
2
+ const OPENSPECUI_TARGET_MAJOR = 3;
3
+ const OPENSPEC_CLI_TARGET_SERIES = "1.3";
4
+ const OPENSPEC_CLI_LEGACY_SERIES = "1.2";
5
+ const OPENSPEC_CLI_MIN_VERSION = "1.2.0";
6
+ const OPENSPEC_CLI_TARGET_MIN_VERSION = "1.3.0";
7
+ const OPENSPEC_CLI_NEXT_SERIES_MIN_VERSION = "1.4.0";
8
+ const OPENSPEC_CLI_ACCEPTED_RANGE = ">=1.2.0 <1.4.0";
9
+ const OPENSPEC_CLI_RECOMMENDED_RANGE = ">=1.3.0 <1.4.0";
10
+ const OPENSPEC_CLI_LEGACY_RANGE = ">=1.2.0 <1.3.0";
11
+ const OPENSPEC_CLI_REFERENCE_TAG_PATTERN = "v1.3.*";
12
+ function parseOpenSpecCliVersion(raw) {
13
+ if (!raw) return null;
14
+ const match = raw.match(/(\d+)\.(\d+)\.(\d+)/);
15
+ if (!match) return null;
16
+ return {
17
+ major: Number(match[1]),
18
+ minor: Number(match[2]),
19
+ patch: Number(match[3])
20
+ };
21
+ }
22
+ function formatOpenSpecCliVersion(version) {
23
+ return `${version.major}.${version.minor}.${version.patch}`;
24
+ }
25
+ function compareOpenSpecCliVersions(left, right) {
26
+ if (left.major !== right.major) return left.major - right.major;
27
+ if (left.minor !== right.minor) return left.minor - right.minor;
28
+ return left.patch - right.patch;
29
+ }
30
+ function isSeries(version, series) {
31
+ const [major, minor] = series.split(".").map((part) => Number(part));
32
+ return version.major === major && version.minor === minor;
33
+ }
34
+ function classifyOpenSpecCliVersion(rawVersion) {
35
+ const version = parseOpenSpecCliVersion(rawVersion);
36
+ if (!version) return {
37
+ rawVersion,
38
+ version: null,
39
+ status: "unknown",
40
+ supported: false,
41
+ recommended: false,
42
+ blocksCoreInteractions: true,
43
+ message: "Unable to parse OpenSpec CLI version."
44
+ };
45
+ if (isSeries(version, OPENSPEC_CLI_TARGET_SERIES)) return {
46
+ rawVersion,
47
+ version,
48
+ status: "current",
49
+ supported: true,
50
+ recommended: true,
51
+ blocksCoreInteractions: false,
52
+ message: `OpenSpec CLI ${formatOpenSpecCliVersion(version)} matches the OpenSpecUI ${OPENSPECUI_TARGET_MAJOR}.x target line.`
53
+ };
54
+ if (isSeries(version, OPENSPEC_CLI_LEGACY_SERIES)) return {
55
+ rawVersion,
56
+ version,
57
+ status: "legacy-compatible",
58
+ supported: true,
59
+ recommended: false,
60
+ blocksCoreInteractions: false,
61
+ message: `OpenSpec CLI ${formatOpenSpecCliVersion(version)} is legacy-compatible with OpenSpecUI ${OPENSPECUI_TARGET_MAJOR}.x. Upgrade to ${OPENSPEC_CLI_RECOMMENDED_RANGE} for the current line.`
62
+ };
63
+ return {
64
+ rawVersion,
65
+ version,
66
+ status: "unsupported",
67
+ supported: false,
68
+ recommended: false,
69
+ blocksCoreInteractions: true,
70
+ message: `Detected OpenSpec CLI ${formatOpenSpecCliVersion(version)}, but OpenSpecUI ${OPENSPECUI_TARGET_MAJOR}.x accepts ${OPENSPEC_CLI_ACCEPTED_RANGE}.`
71
+ };
72
+ }
73
+
74
+ //#endregion
75
+ export { OPENSPECUI_TARGET_MAJOR, OPENSPEC_CLI_ACCEPTED_RANGE, OPENSPEC_CLI_LEGACY_RANGE, OPENSPEC_CLI_LEGACY_SERIES, OPENSPEC_CLI_MIN_VERSION, OPENSPEC_CLI_NEXT_SERIES_MIN_VERSION, OPENSPEC_CLI_RECOMMENDED_RANGE, OPENSPEC_CLI_REFERENCE_TAG_PATTERN, OPENSPEC_CLI_TARGET_MIN_VERSION, OPENSPEC_CLI_TARGET_SERIES, classifyOpenSpecCliVersion, compareOpenSpecCliVersions, formatOpenSpecCliVersion, parseOpenSpecCliVersion };
@@ -1,2 +1,2 @@
1
- import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-Cb-CVa6h.mjs";
1
+ import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-C1H1ryBL.mjs";
2
2
  export { VIRTUAL_PROJECT_DIRNAME, toOpsxDisplayPath };
@@ -1,3 +1,3 @@
1
- import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-DDK7QA5y.mjs";
1
+ import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-Cja3Bt1P.mjs";
2
2
 
3
3
  export { VIRTUAL_PROJECT_DIRNAME, toOpsxDisplayPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openspecui/core",
3
- "version": "2.3.6",
3
+ "version": "3.0.0",
4
4
  "description": "Core OpenSpec adapter and parser",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",
@@ -18,6 +18,10 @@
18
18
  "import": "./dist/hosted-app.mjs",
19
19
  "types": "./dist/hosted-app.d.mts"
20
20
  },
21
+ "./openspec-compat": {
22
+ "import": "./dist/openspec-compat.mjs",
23
+ "types": "./dist/openspec-compat.d.mts"
24
+ },
21
25
  "./opsx-display-path": {
22
26
  "import": "./dist/opsx-display-path.mjs",
23
27
  "types": "./dist/opsx-display-path.d.mts"
@@ -27,8 +31,8 @@
27
31
  "dist"
28
32
  ],
29
33
  "scripts": {
30
- "build": "tsdown src/index.ts src/dashboard-display.ts src/opsx-display-path.ts src/hosted-app.ts --format esm --dts",
31
- "dev": "tsdown src/index.ts src/dashboard-display.ts src/opsx-display-path.ts src/hosted-app.ts --format esm --dts --watch",
34
+ "build": "tsdown src/index.ts src/dashboard-display.ts src/opsx-display-path.ts src/hosted-app.ts src/openspec-compat.ts --format esm --dts",
35
+ "dev": "tsdown src/index.ts src/dashboard-display.ts src/opsx-display-path.ts src/hosted-app.ts src/openspec-compat.ts --format esm --dts --watch",
32
36
  "test": "vitest run",
33
37
  "test:watch": "vitest",
34
38
  "typecheck": "tsc --noEmit"