@openspecui/core 2.3.7 → 3.0.1

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";
@@ -1326,8 +1326,11 @@ declare function createFileChangeObservable(watcher: OpenSpecWatcher): {
1326
1326
  //#endregion
1327
1327
  //#region src/config.d.ts
1328
1328
  declare const CODE_EDITOR_THEME_VALUES: readonly ["github", "material", "vscode", "tokyo", "gruvbox", "monokai", "nord"];
1329
+ declare const OPSX_AGENT_INVOCATION_MODE_VALUES: readonly ["compose", "command"];
1329
1330
  declare const TerminalRendererEngineSchema: z.ZodEnum<["xterm", "ghostty"]>;
1330
1331
  type TerminalRendererEngine = z.infer<typeof TerminalRendererEngineSchema>;
1332
+ declare const OpsxAgentInvocationModeSchema: z.ZodEnum<["compose", "command"]>;
1333
+ type OpsxAgentInvocationMode = z.infer<typeof OpsxAgentInvocationModeSchema>;
1331
1334
  declare const CodeEditorThemeSchema: z.ZodEnum<["github", "material", "vscode", "tokyo", "gruvbox", "monokai", "nord"]>;
1332
1335
  type CodeEditorTheme = z.infer<typeof CodeEditorThemeSchema>;
1333
1336
  declare function isTerminalRendererEngine(value: string): value is TerminalRendererEngine;
@@ -1436,6 +1439,14 @@ declare const GitConfigSchema: z.ZodObject<{
1436
1439
  diffEagerLineBudget?: number | undefined;
1437
1440
  }>;
1438
1441
  type GitConfig = z.infer<typeof GitConfigSchema>;
1442
+ declare const OpsxConfigSchema: z.ZodObject<{
1443
+ agentInvocationMode: z.ZodDefault<z.ZodEnum<["compose", "command"]>>;
1444
+ }, "strip", z.ZodTypeAny, {
1445
+ agentInvocationMode: "command" | "compose";
1446
+ }, {
1447
+ agentInvocationMode?: "command" | "compose" | undefined;
1448
+ }>;
1449
+ type OpsxConfig = z.infer<typeof OpsxConfigSchema>;
1439
1450
  /**
1440
1451
  * OpenSpecUI 配置 Schema
1441
1452
  *
@@ -1467,6 +1478,14 @@ declare const OpenSpecUIConfigSchema: z.ZodObject<{
1467
1478
  }>>;
1468
1479
  /** Hosted app 基础 URL(空字符串表示使用官方默认值) */
1469
1480
  appBaseUrl: z.ZodDefault<z.ZodString>;
1481
+ /** OPSX workflow invocation preferences */
1482
+ opsx: z.ZodDefault<z.ZodObject<{
1483
+ agentInvocationMode: z.ZodDefault<z.ZodEnum<["compose", "command"]>>;
1484
+ }, "strip", z.ZodTypeAny, {
1485
+ agentInvocationMode: "command" | "compose";
1486
+ }, {
1487
+ agentInvocationMode?: "command" | "compose" | undefined;
1488
+ }>>;
1470
1489
  /** 终端配置 */
1471
1490
  terminal: z.ZodDefault<z.ZodObject<{
1472
1491
  fontSize: z.ZodDefault<z.ZodNumber>;
@@ -1516,6 +1535,9 @@ declare const OpenSpecUIConfigSchema: z.ZodObject<{
1516
1535
  theme: "github" | "material" | "vscode" | "tokyo" | "gruvbox" | "monokai" | "nord";
1517
1536
  };
1518
1537
  appBaseUrl: string;
1538
+ opsx: {
1539
+ agentInvocationMode: "command" | "compose";
1540
+ };
1519
1541
  terminal: {
1520
1542
  fontSize: number;
1521
1543
  fontFamily: string;
@@ -1540,6 +1562,9 @@ declare const OpenSpecUIConfigSchema: z.ZodObject<{
1540
1562
  theme?: "github" | "material" | "vscode" | "tokyo" | "gruvbox" | "monokai" | "nord" | undefined;
1541
1563
  } | undefined;
1542
1564
  appBaseUrl?: string | undefined;
1565
+ opsx?: {
1566
+ agentInvocationMode?: "command" | "compose" | undefined;
1567
+ } | undefined;
1543
1568
  terminal?: {
1544
1569
  fontSize?: number | undefined;
1545
1570
  fontFamily?: string | undefined;
@@ -1564,6 +1589,7 @@ type OpenSpecUIConfigUpdate = {
1564
1589
  theme?: OpenSpecUIConfig['theme'];
1565
1590
  codeEditor?: Partial<OpenSpecUIConfig['codeEditor']>;
1566
1591
  appBaseUrl?: OpenSpecUIConfig['appBaseUrl'];
1592
+ opsx?: Partial<OpsxConfig>;
1567
1593
  terminal?: Partial<TerminalConfig>;
1568
1594
  dashboard?: Partial<DashboardConfig>;
1569
1595
  git?: Partial<GitConfig>;
@@ -1763,6 +1789,8 @@ interface AIToolOption {
1763
1789
  successLabel?: string;
1764
1790
  /** 技能目录(相对项目根目录) */
1765
1791
  skillsDir?: string;
1792
+ /** 自动检测路径;存在任一路径即表示项目已有该工具配置 */
1793
+ detectionPaths?: string[];
1766
1794
  }
1767
1795
  /**
1768
1796
  * 完整的工具配置(元信息 + skills 目录)
@@ -1841,6 +1869,7 @@ interface ToolInitState {
1841
1869
  missingCommandWorkflows: ToolWorkflowId[];
1842
1870
  unexpectedSkillWorkflows: ToolWorkflowId[];
1843
1871
  unexpectedCommandWorkflows: ToolWorkflowId[];
1872
+ legacyCommandWorkflows: ToolWorkflowId[];
1844
1873
  }
1845
1874
  declare function getToolInitStates(projectDir: string, options: {
1846
1875
  delivery: ToolInitDelivery;
@@ -2048,11 +2077,12 @@ declare const ApplyTaskSchema: z.ZodObject<{
2048
2077
  done: boolean;
2049
2078
  }>;
2050
2079
  type ApplyTask = z.infer<typeof ApplyTaskSchema>;
2080
+ declare const ApplyInstructionsContextFilesSchema: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, string[], string | string[]>>;
2051
2081
  declare const ApplyInstructionsSchema: z.ZodObject<{
2052
2082
  changeName: z.ZodString;
2053
2083
  changeDir: z.ZodString;
2054
2084
  schemaName: z.ZodString;
2055
- contextFiles: z.ZodRecord<z.ZodString, z.ZodString>;
2085
+ contextFiles: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, string[], string | string[]>>;
2056
2086
  progress: z.ZodObject<{
2057
2087
  total: z.ZodNumber;
2058
2088
  complete: z.ZodNumber;
@@ -2096,7 +2126,7 @@ declare const ApplyInstructionsSchema: z.ZodObject<{
2096
2126
  changeName: string;
2097
2127
  schemaName: string;
2098
2128
  changeDir: string;
2099
- contextFiles: Record<string, string>;
2129
+ contextFiles: Record<string, string[]>;
2100
2130
  state: "ready" | "blocked" | "all_done";
2101
2131
  instruction: string;
2102
2132
  missingArtifacts?: string[] | undefined;
@@ -2114,7 +2144,7 @@ declare const ApplyInstructionsSchema: z.ZodObject<{
2114
2144
  changeName: string;
2115
2145
  schemaName: string;
2116
2146
  changeDir: string;
2117
- contextFiles: Record<string, string>;
2147
+ contextFiles: Record<string, string | string[]>;
2118
2148
  state: "ready" | "blocked" | "all_done";
2119
2149
  instruction: string;
2120
2150
  missingArtifacts?: string[] | undefined;
@@ -3145,4 +3175,4 @@ type PtyServerMessage = z.infer<typeof PtyServerMessageSchema>;
3145
3175
  type PtySessionInfo = z.infer<typeof PtySessionInfoSchema>;
3146
3176
  type PtyPlatform = z.infer<typeof PtyPlatformSchema>;
3147
3177
  //#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 };
3178
+ 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, OPSX_AGENT_INVOCATION_MODE_VALUES, OpenSpecAdapter, type OpenSpecUIConfig, OpenSpecUIConfigSchema, type OpenSpecUIConfigUpdate, OpenSpecWatcher, type OpsxAgentInvocationMode, OpsxAgentInvocationModeSchema, type OpsxConfig, OpsxConfigSchema, 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";
@@ -2117,7 +2117,9 @@ const CODE_EDITOR_THEME_VALUES = [
2117
2117
  "nord"
2118
2118
  ];
2119
2119
  const TERMINAL_RENDERER_ENGINE_VALUES = ["xterm", "ghostty"];
2120
+ const OPSX_AGENT_INVOCATION_MODE_VALUES = ["compose", "command"];
2120
2121
  const TerminalRendererEngineSchema = z.enum(TERMINAL_RENDERER_ENGINE_VALUES);
2122
+ const OpsxAgentInvocationModeSchema = z.enum(OPSX_AGENT_INVOCATION_MODE_VALUES);
2121
2123
  const CodeEditorThemeSchema = z.enum(CODE_EDITOR_THEME_VALUES);
2122
2124
  function isTerminalRendererEngine(value) {
2123
2125
  return TERMINAL_RENDERER_ENGINE_VALUES.includes(value);
@@ -2495,6 +2497,7 @@ const DashboardConfigSchema = z.object({ trendPointLimit: z.number().int().min(2
2495
2497
  const DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET = 1e3;
2496
2498
  const GitConfigSchema = z.object({ diffEagerLineBudget: z.number().int().min(0).max(2e5).default(DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET) });
2497
2499
  const CodeEditorConfigSchema = z.object({ theme: CodeEditorThemeSchema.default("github") });
2500
+ const OpsxConfigSchema = z.object({ agentInvocationMode: OpsxAgentInvocationModeSchema.default("compose") });
2498
2501
  /**
2499
2502
  * OpenSpecUI 配置 Schema
2500
2503
  *
@@ -2508,6 +2511,7 @@ const OpenSpecUIConfigSchema = z.object({
2508
2511
  theme: z.enum(THEME_VALUES).default("system"),
2509
2512
  codeEditor: CodeEditorConfigSchema.default(CodeEditorConfigSchema.parse({})),
2510
2513
  appBaseUrl: z.string().default(""),
2514
+ opsx: OpsxConfigSchema.default(OpsxConfigSchema.parse({})),
2511
2515
  terminal: TerminalConfigSchema.default(TerminalConfigSchema.parse({})),
2512
2516
  dashboard: DashboardConfigSchema.default(DashboardConfigSchema.parse({})),
2513
2517
  git: GitConfigSchema.default(GitConfigSchema.parse({}))
@@ -2518,6 +2522,7 @@ const DEFAULT_CONFIG = {
2518
2522
  theme: "system",
2519
2523
  codeEditor: CodeEditorConfigSchema.parse({}),
2520
2524
  appBaseUrl: "",
2525
+ opsx: OpsxConfigSchema.parse({}),
2521
2526
  terminal: TerminalConfigSchema.parse({}),
2522
2527
  dashboard: DashboardConfigSchema.parse({}),
2523
2528
  git: GitConfigSchema.parse({})
@@ -2560,6 +2565,9 @@ function toPersistedConfig(config, options = {}) {
2560
2565
  if (config.codeEditor.theme !== DEFAULT_CONFIG.codeEditor.theme) codeEditor.theme = config.codeEditor.theme;
2561
2566
  if (hasOwnEntries(codeEditor)) persisted.codeEditor = codeEditor;
2562
2567
  if (config.appBaseUrl !== DEFAULT_CONFIG.appBaseUrl) persisted.appBaseUrl = config.appBaseUrl;
2568
+ const opsx = {};
2569
+ if (config.opsx.agentInvocationMode !== DEFAULT_CONFIG.opsx.agentInvocationMode) opsx.agentInvocationMode = config.opsx.agentInvocationMode;
2570
+ if (hasOwnEntries(opsx)) persisted.opsx = opsx;
2563
2571
  const terminal = {};
2564
2572
  if (config.terminal.fontSize !== DEFAULT_CONFIG.terminal.fontSize) terminal.fontSize = config.terminal.fontSize;
2565
2573
  if (config.terminal.fontFamily !== DEFAULT_CONFIG.terminal.fontFamily) terminal.fontFamily = config.terminal.fontFamily;
@@ -2653,6 +2661,10 @@ var ConfigManager = class {
2653
2661
  ...config.codeEditor
2654
2662
  },
2655
2663
  appBaseUrl: config.appBaseUrl ?? current.appBaseUrl,
2664
+ opsx: {
2665
+ ...current.opsx,
2666
+ ...config.opsx
2667
+ },
2656
2668
  terminal: {
2657
2669
  ...current.terminal,
2658
2670
  ...config.terminal
@@ -3213,6 +3225,13 @@ const AI_TOOLS = [
3213
3225
  successLabel: "Auggie",
3214
3226
  skillsDir: ".augment"
3215
3227
  },
3228
+ {
3229
+ name: "Bob Shell",
3230
+ value: "bob",
3231
+ available: true,
3232
+ successLabel: "Bob Shell",
3233
+ skillsDir: ".bob"
3234
+ },
3216
3235
  {
3217
3236
  name: "Claude Code",
3218
3237
  value: "claude",
@@ -3234,6 +3253,13 @@ const AI_TOOLS = [
3234
3253
  successLabel: "Codex",
3235
3254
  skillsDir: ".codex"
3236
3255
  },
3256
+ {
3257
+ name: "ForgeCode",
3258
+ value: "forgecode",
3259
+ available: true,
3260
+ successLabel: "ForgeCode",
3261
+ skillsDir: ".forge"
3262
+ },
3237
3263
  {
3238
3264
  name: "CodeBuddy Code (CLI)",
3239
3265
  value: "codebuddy",
@@ -3288,7 +3314,16 @@ const AI_TOOLS = [
3288
3314
  value: "github-copilot",
3289
3315
  available: true,
3290
3316
  successLabel: "GitHub Copilot",
3291
- skillsDir: ".github"
3317
+ skillsDir: ".github",
3318
+ detectionPaths: [
3319
+ ".github/copilot-instructions.md",
3320
+ ".github/instructions",
3321
+ ".github/workflows/copilot-setup-steps.yml",
3322
+ ".github/prompts",
3323
+ ".github/agents",
3324
+ ".github/skills",
3325
+ ".github/.mcp.json"
3326
+ ]
3292
3327
  },
3293
3328
  {
3294
3329
  name: "iFlow",
@@ -3297,6 +3332,13 @@ const AI_TOOLS = [
3297
3332
  successLabel: "iFlow",
3298
3333
  skillsDir: ".iflow"
3299
3334
  },
3335
+ {
3336
+ name: "Junie",
3337
+ value: "junie",
3338
+ available: true,
3339
+ successLabel: "Junie",
3340
+ skillsDir: ".junie"
3341
+ },
3300
3342
  {
3301
3343
  name: "Kilo Code",
3302
3344
  value: "kilocode",
@@ -3332,6 +3374,13 @@ const AI_TOOLS = [
3332
3374
  successLabel: "Qoder",
3333
3375
  skillsDir: ".qoder"
3334
3376
  },
3377
+ {
3378
+ name: "Lingma",
3379
+ value: "lingma",
3380
+ available: true,
3381
+ successLabel: "Lingma",
3382
+ skillsDir: ".lingma"
3383
+ },
3335
3384
  {
3336
3385
  name: "Qwen Code",
3337
3386
  value: "qwen",
@@ -3388,7 +3437,8 @@ function getAllTools() {
3388
3437
  async function getDetectedProjectTools(projectDir) {
3389
3438
  return (await Promise.all(AI_TOOLS.map(async (tool) => {
3390
3439
  if (!tool.skillsDir) return null;
3391
- return await reactiveExists(join$1(projectDir, tool.skillsDir)) ? tool : null;
3440
+ const detectionPaths = tool.detectionPaths && tool.detectionPaths.length > 0 ? tool.detectionPaths : [tool.skillsDir];
3441
+ return (await Promise.all(detectionPaths.map((path) => reactiveExists(join$1(projectDir, path))))).some(Boolean) ? tool : null;
3392
3442
  }))).filter((tool) => tool !== null);
3393
3443
  }
3394
3444
  /**
@@ -3494,33 +3544,45 @@ function resolveCodexHome() {
3494
3544
  const configuredHome = process.env.CODEX_HOME?.trim();
3495
3545
  return resolve(configuredHome ? configuredHome : join$1(homedir(), ".codex"));
3496
3546
  }
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
- }
3547
+ const TOOL_COMMAND_PATHS = {
3548
+ "amazon-q": { primary: (projectDir, workflow) => resolve(projectDir, ".amazonq", "prompts", `opsx-${workflow}.md`) },
3549
+ antigravity: { primary: (projectDir, workflow) => resolve(projectDir, ".agent", "workflows", `opsx-${workflow}.md`) },
3550
+ auggie: { primary: (projectDir, workflow) => resolve(projectDir, ".augment", "commands", `opsx-${workflow}.md`) },
3551
+ bob: { primary: (projectDir, workflow) => resolve(projectDir, ".bob", "commands", `opsx-${workflow}.md`) },
3552
+ claude: { primary: (projectDir, workflow) => resolve(projectDir, ".claude", "commands", "opsx", `${workflow}.md`) },
3553
+ cline: { primary: (projectDir, workflow) => resolve(projectDir, ".clinerules", "workflows", `opsx-${workflow}.md`) },
3554
+ codebuddy: { primary: (projectDir, workflow) => resolve(projectDir, ".codebuddy", "commands", "opsx", `${workflow}.md`) },
3555
+ codex: { primary: (_projectDir, workflow) => resolve(resolveCodexHome(), "prompts", `opsx-${workflow}.md`) },
3556
+ continue: { primary: (projectDir, workflow) => resolve(projectDir, ".continue", "prompts", `opsx-${workflow}.prompt`) },
3557
+ costrict: { primary: (projectDir, workflow) => resolve(projectDir, ".cospec", "openspec", "commands", `opsx-${workflow}.md`) },
3558
+ crush: { primary: (projectDir, workflow) => resolve(projectDir, ".crush", "commands", "opsx", `${workflow}.md`) },
3559
+ cursor: { primary: (projectDir, workflow) => resolve(projectDir, ".cursor", "commands", `opsx-${workflow}.md`) },
3560
+ factory: { primary: (projectDir, workflow) => resolve(projectDir, ".factory", "commands", `opsx-${workflow}.md`) },
3561
+ gemini: { primary: (projectDir, workflow) => resolve(projectDir, ".gemini", "commands", "opsx", `${workflow}.toml`) },
3562
+ "github-copilot": { primary: (projectDir, workflow) => resolve(projectDir, ".github", "prompts", `opsx-${workflow}.prompt.md`) },
3563
+ iflow: { primary: (projectDir, workflow) => resolve(projectDir, ".iflow", "commands", `opsx-${workflow}.md`) },
3564
+ junie: { primary: (projectDir, workflow) => resolve(projectDir, ".junie", "commands", `opsx-${workflow}.md`) },
3565
+ kilocode: { primary: (projectDir, workflow) => resolve(projectDir, ".kilocode", "workflows", `opsx-${workflow}.md`) },
3566
+ kiro: { primary: (projectDir, workflow) => resolve(projectDir, ".kiro", "prompts", `opsx-${workflow}.prompt.md`) },
3567
+ lingma: { primary: (projectDir, workflow) => resolve(projectDir, ".lingma", "commands", "opsx", `${workflow}.md`) },
3568
+ opencode: {
3569
+ primary: (projectDir, workflow) => resolve(projectDir, ".opencode", "commands", `opsx-${workflow}.md`),
3570
+ legacy: [(projectDir, workflow) => resolve(projectDir, ".opencode", "command", `opsx-${workflow}.md`)]
3571
+ },
3572
+ pi: { primary: (projectDir, workflow) => resolve(projectDir, ".pi", "prompts", `opsx-${workflow}.md`) },
3573
+ qoder: { primary: (projectDir, workflow) => resolve(projectDir, ".qoder", "commands", "opsx", `${workflow}.md`) },
3574
+ qwen: { primary: (projectDir, workflow) => resolve(projectDir, ".qwen", "commands", `opsx-${workflow}.toml`) },
3575
+ roocode: { primary: (projectDir, workflow) => resolve(projectDir, ".roo", "commands", `opsx-${workflow}.md`) },
3576
+ windsurf: { primary: (projectDir, workflow) => resolve(projectDir, ".windsurf", "workflows", `opsx-${workflow}.md`) }
3577
+ };
3578
+ function resolveToolCommandArtifact(projectDir, toolId, workflow) {
3579
+ const config = TOOL_COMMAND_PATHS[toolId];
3580
+ if (!config) return null;
3581
+ return {
3582
+ workflow,
3583
+ path: config.primary(projectDir, workflow),
3584
+ legacyPaths: config.legacy?.map((resolvePath) => resolvePath(projectDir, workflow))
3585
+ };
3524
3586
  }
3525
3587
  function getSkillArtifacts(projectDir, skillsDir) {
3526
3588
  return ALL_TOOL_WORKFLOWS.map((workflow) => ({
@@ -3530,39 +3592,46 @@ function getSkillArtifacts(projectDir, skillsDir) {
3530
3592
  }
3531
3593
  function getCommandArtifacts(projectDir, toolId) {
3532
3594
  return ALL_TOOL_WORKFLOWS.flatMap((workflow) => {
3533
- const path = resolveToolCommandPath(projectDir, toolId, workflow);
3534
- return path ? [{
3535
- workflow,
3536
- path
3537
- }] : [];
3595
+ const artifact = resolveToolCommandArtifact(projectDir, toolId, workflow);
3596
+ return artifact ? [artifact] : [];
3538
3597
  });
3539
3598
  }
3540
3599
  function invalidateToolInitCaches(projectDir) {
3541
3600
  const cacheRoots = /* @__PURE__ */ new Set();
3542
3601
  for (const tool of AI_TOOLS) {
3543
3602
  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));
3603
+ for (const commandArtifact of getCommandArtifacts(projectDir, tool.value)) {
3604
+ cacheRoots.add(dirname$1(commandArtifact.path));
3605
+ for (const legacyPath of commandArtifact.legacyPaths ?? []) cacheRoots.add(dirname$1(legacyPath));
3547
3606
  }
3548
3607
  }
3549
3608
  for (const root of cacheRoots) clearCache(root);
3550
3609
  }
3551
3610
  async function getExistingArtifactPaths(entries) {
3552
- const presence = await Promise.all(entries.map(async (entry) => ({
3553
- path: entry.path,
3554
- exists: await reactiveExists(entry.path)
3611
+ const paths = entries.flatMap((entry) => [entry.path, ...entry.legacyPaths ?? []]);
3612
+ const presence = await Promise.all(paths.map(async (path) => ({
3613
+ path,
3614
+ exists: await reactiveExists(path)
3555
3615
  })));
3556
3616
  return new Set(presence.filter((entry) => entry.exists).map((entry) => entry.path));
3557
3617
  }
3618
+ function hasExistingArtifact(entry, existingPaths) {
3619
+ return existingPaths.has(entry.path) || (entry.legacyPaths?.some((legacyPath) => existingPaths.has(legacyPath)) ?? false);
3620
+ }
3621
+ function hasLegacyArtifact(entry, existingPaths) {
3622
+ return entry.legacyPaths?.some((legacyPath) => existingPaths.has(legacyPath)) ?? false;
3623
+ }
3558
3624
  function countExisting(entries, existingPaths) {
3559
- return entries.reduce((count, entry) => count + (existingPaths.has(entry.path) ? 1 : 0), 0);
3625
+ return entries.reduce((count, entry) => count + (hasExistingArtifact(entry, existingPaths) ? 1 : 0), 0);
3560
3626
  }
3561
3627
  function collectMissingWorkflows(entries, existingPaths) {
3562
- return entries.filter((entry) => !existingPaths.has(entry.path)).map((entry) => entry.workflow);
3628
+ return entries.filter((entry) => !hasExistingArtifact(entry, existingPaths)).map((entry) => entry.workflow);
3563
3629
  }
3564
3630
  function collectUnexpectedWorkflows(entries, desiredWorkflowSet, existingPaths) {
3565
- return entries.filter((entry) => !desiredWorkflowSet.has(entry.workflow) && existingPaths.has(entry.path)).map((entry) => entry.workflow);
3631
+ return entries.filter((entry) => !desiredWorkflowSet.has(entry.workflow) && hasExistingArtifact(entry, existingPaths)).map((entry) => entry.workflow);
3632
+ }
3633
+ function collectLegacyWorkflows(entries, existingPaths) {
3634
+ return entries.filter((entry) => hasLegacyArtifact(entry, existingPaths)).map((entry) => entry.workflow);
3566
3635
  }
3567
3636
  async function getToolInitStates(projectDir, options) {
3568
3637
  invalidateToolInitCaches(projectDir);
@@ -3581,6 +3650,7 @@ async function getToolInitStates(projectDir, options) {
3581
3650
  const missingCommandWorkflows = collectMissingWorkflows(expectedCommandArtifacts, existingCommandPaths);
3582
3651
  const unexpectedSkillWorkflows = collectUnexpectedWorkflows(shouldGenerateSkills ? skillArtifacts : skillArtifacts, shouldGenerateSkills ? desiredWorkflowSet : /* @__PURE__ */ new Set(), existingSkillPaths);
3583
3652
  const unexpectedCommandWorkflows = collectUnexpectedWorkflows(shouldGenerateCommands ? commandArtifacts : commandArtifacts, shouldGenerateCommands ? desiredWorkflowSet : /* @__PURE__ */ new Set(), existingCommandPaths);
3653
+ const legacyCommandWorkflows = collectLegacyWorkflows(commandArtifacts, existingCommandPaths);
3584
3654
  const expectedSkillCount = expectedSkillArtifacts.length;
3585
3655
  const presentExpectedSkillCount = expectedSkillCount - missingSkillWorkflows.length;
3586
3656
  const detectedSkillCount = countExisting(skillArtifacts, existingSkillPaths);
@@ -3603,7 +3673,8 @@ async function getToolInitStates(projectDir, options) {
3603
3673
  missingSkillWorkflows,
3604
3674
  missingCommandWorkflows,
3605
3675
  unexpectedSkillWorkflows,
3606
- unexpectedCommandWorkflows
3676
+ unexpectedCommandWorkflows,
3677
+ legacyCommandWorkflows
3607
3678
  };
3608
3679
  }));
3609
3680
  }
@@ -3654,11 +3725,13 @@ const ApplyTaskSchema = z.object({
3654
3725
  description: z.string(),
3655
3726
  done: z.boolean()
3656
3727
  });
3728
+ const ApplyInstructionsContextFilePathsSchema = z.union([z.string(), z.array(z.string())]).transform((paths) => Array.isArray(paths) ? paths : [paths]);
3729
+ const ApplyInstructionsContextFilesSchema = z.record(ApplyInstructionsContextFilePathsSchema);
3657
3730
  const ApplyInstructionsSchema = z.object({
3658
3731
  changeName: z.string(),
3659
3732
  changeDir: z.string(),
3660
3733
  schemaName: z.string(),
3661
- contextFiles: z.record(z.string()),
3734
+ contextFiles: ApplyInstructionsContextFilesSchema,
3662
3735
  progress: z.object({
3663
3736
  total: z.number(),
3664
3737
  complete: z.number(),
@@ -4514,4 +4587,4 @@ const PtyServerMessageSchema = z.discriminatedUnion("type", [
4514
4587
  ]);
4515
4588
 
4516
4589
  //#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 };
4590
+ 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, OPSX_AGENT_INVOCATION_MODE_VALUES, OpenSpecAdapter, OpenSpecUIConfigSchema, OpenSpecWatcher, OpsxAgentInvocationModeSchema, OpsxConfigSchema, 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.7",
3
+ "version": "3.0.1",
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"