@openspecui/core 6.2.0 → 7.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.
- package/dist/active-root-config-BXb2HeOF.d.mts +668 -0
- package/dist/active-root-config-L5QaMb3A.mjs +333 -0
- package/dist/active-root-config.d.mts +6 -0
- package/dist/active-root-config.mjs +3 -0
- package/dist/app-daemon-control.d.mts +10 -10
- package/dist/{cli-projection-CvRCkCyI.d.mts → cli-projection-CBwRFPMi.d.mts} +13 -13
- package/dist/{cli-projection-BHfqvlpA.mjs → cli-projection-CKRwTvwf.mjs} +1 -1
- package/dist/cli-projection.d.mts +5 -5
- package/dist/cli-projection.mjs +2 -2
- package/dist/{common-BpgNUOOT.mjs → common-BRL_34xt.mjs} +2 -1
- package/dist/{dashboard-summary-transport-iutogi2N.d.mts → dashboard-summary-transport-BCaB0LKb.d.mts} +3979 -3187
- package/dist/{dashboard-summary-transport-BMtZ0q12.mjs → dashboard-summary-transport-ILCfZD_I.mjs} +2 -2
- package/dist/dashboard-summary-transport.d.mts +26 -25
- package/dist/dashboard-summary-transport.mjs +4 -4
- package/dist/{document-translation-CUkkxnYV.mjs → document-translation-B3xaP0dJ.mjs} +1 -1
- package/dist/{document-translation-DOcHp3o0.d.mts → document-translation-BNbM3fEj.d.mts} +2 -2
- package/dist/document-translation.d.mts +1 -1
- package/dist/document-translation.mjs +2 -2
- package/dist/{hosted-app-C3gBSvov.mjs → hosted-app-B_T_tTvO.mjs} +7 -2
- package/dist/hosted-app.d.mts +27 -26
- package/dist/hosted-app.mjs +7 -7
- package/dist/{hosted-contract-CaN2aw54.mjs → hosted-contract-BxUx6ksP.mjs} +5 -5
- package/dist/hosted-contract.d.mts +26 -25
- package/dist/hosted-contract.mjs +6 -6
- package/dist/{command-result-DPdfvbPT.d.mts → index-CF5niw80.d.mts} +8117 -7976
- package/dist/index.d.mts +27 -26
- package/dist/index.mjs +904 -332
- package/dist/{local-download-profiles-xAbDVjd6.d.mts → local-download-profiles-Bq0bQbTA.d.mts} +1 -1
- package/dist/local-download-profiles.d.mts +2 -2
- package/dist/local-download-profiles.mjs +1 -1
- package/dist/markdown-facts.d.mts +1 -1
- package/dist/markdown-facts.mjs +1 -1
- package/dist/{markdown-reading-w686Obnl.d.mts → markdown-reading--Sr6JAl5.d.mts} +1 -1
- package/dist/{markdown-reading-0L-mVBJp.mjs → markdown-reading-LtgFpB8E.mjs} +1 -1
- package/dist/markdown-reading.d.mts +2 -2
- package/dist/markdown-reading.mjs +2 -2
- package/dist/{notifications-BP_02fdj.d.mts → notifications-ClhEHZU3.d.mts} +11 -11
- package/dist/{notifications-E6_WBjQO.mjs → notifications-Cy74GVN7.mjs} +2 -2
- package/dist/notifications.d.mts +2 -2
- package/dist/notifications.mjs +3 -3
- package/dist/{openspec-annotations-DiHje5HD.mjs → openspec-annotations-BJ1BlVyo.mjs} +2 -2
- package/dist/{openspec-annotations-BXAqKLXc.d.mts → openspec-annotations-BylPW5rz.d.mts} +2 -2
- package/dist/openspec-annotations.d.mts +3 -3
- package/dist/openspec-annotations.mjs +3 -3
- package/dist/openspec-compat.d.mts +14 -14
- package/dist/openspec-compat.mjs +18 -32
- package/dist/{openspec-projection-DvJnsxLZ.mjs → openspec-projection-Cno7FlwE.mjs} +2 -2
- package/dist/{openspec-projection-CPKTjO43.d.mts → openspec-projection-EgTIZCfC.d.mts} +3 -3
- package/dist/openspec-projection.d.mts +5 -5
- package/dist/openspec-projection.mjs +4 -4
- package/dist/opsx-display-path.d.mts +1 -1
- package/dist/opsx-display-path.mjs +1 -1
- package/dist/{opsx-entity-BJz_BsKn.d.mts → opsx-entity-BNthD6Ks.d.mts} +2 -2
- package/dist/opsx-entity.d.mts +7 -7
- package/dist/opsx-entity.mjs +1 -1
- package/dist/{opsx-schema-detail-tkv6htQB.d.mts → opsx-schema-detail-B4li4BMU.d.mts} +2 -2
- package/dist/opsx-schema-detail.d.mts +8 -8
- package/dist/opsx-schema-detail.mjs +1 -1
- package/dist/{opsx-types-BNEqpP-B.d.mts → opsx-types-DP8JjGq0.d.mts} +544 -295
- package/dist/opsx-workflows.d.mts +1 -1
- package/dist/opsx-workflows.mjs +1 -1
- package/dist/{planning-cli-projection-DrkT18EI.mjs → planning-cli-projection-BreqsrYA.mjs} +51 -11
- package/dist/planning-cli-projection.d.mts +26 -25
- package/dist/planning-cli-projection.mjs +7 -7
- package/dist/{schemas-D4afES_m.d.mts → schemas-divIlNvA.d.mts} +128 -128
- package/dist/{sounds-CsPiQKxX.d.mts → sounds-qIKfPgxj.d.mts} +1 -1
- package/dist/sounds.d.mts +1 -1
- package/dist/sounds.mjs +1 -1
- package/dist/{spec-catalog-Dv2qolxy.mjs → spec-catalog-DEk_oHAx.mjs} +99 -18
- package/dist/spec-catalog.d.mts +27 -26
- package/dist/spec-catalog.mjs +5 -5
- package/dist/{store-content-projection-CiMcGZnG.mjs → store-content-projection-Bpdb7_d9.mjs} +1 -1
- package/dist/store-content-projection.d.mts +1 -1
- package/dist/store-content-projection.mjs +2 -2
- package/dist/{store-mutation-protocol-CLtYUSwC.mjs → store-mutation-protocol-CJGUWWI6.mjs} +1 -1
- package/dist/{store-mutation-protocol-Ckcv2-zs.d.mts → store-mutation-protocol-Cr4pWWbh.d.mts} +24 -24
- package/dist/store-mutation-protocol.d.mts +1 -1
- package/dist/store-mutation-protocol.mjs +2 -2
- package/dist/{store-types-DIws57FV.d.mts → store-types-DjWxHHvs.d.mts} +1 -1
- package/dist/store-types.d.mts +5 -5
- package/dist/store-types.mjs +1 -1
- package/dist/{task-progress-DpZak5xA.mjs → task-progress-Bvid_Ws8.mjs} +1 -1
- package/dist/task-progress.d.mts +6 -6
- package/dist/task-progress.mjs +2 -2
- package/dist/{terminal-audio-BXa1vpkF.d.mts → terminal-audio-CSUGxzx3.d.mts} +2 -2
- package/dist/{terminal-audio-punFQHXI.mjs → terminal-audio-DeubAfFC.mjs} +1 -1
- package/dist/terminal-audio.d.mts +2 -2
- package/dist/terminal-audio.mjs +2 -2
- package/dist/terminal-control.d.mts +2 -2
- package/dist/terminal-control.mjs +1 -1
- package/dist/{terminal-invocation-DFhNS_lc.d.mts → terminal-invocation-kFxUD_5T.d.mts} +96 -96
- package/dist/terminal-invocation.d.mts +1 -1
- package/dist/terminal-invocation.mjs +1 -1
- package/dist/terminal-theme.d.mts +1 -1
- package/dist/terminal-theme.mjs +1 -1
- package/dist/translation-language-pair.d.mts +1 -1
- package/dist/translation-language-pair.mjs +1 -1
- package/dist/{translator-B9j5lGVS.d.mts → translator-DgIIyl6v.d.mts} +141 -141
- package/dist/translator.d.mts +1 -1
- package/dist/translator.mjs +1 -1
- package/package.json +15 -5
- /package/dist/{local-download-profiles-DK4g6FRe.mjs → local-download-profiles-h9lUTXr-.mjs} +0 -0
- /package/dist/{markdown-facts-Dve6IAJP.mjs → markdown-facts-BIx47NNY.mjs} +0 -0
- /package/dist/{markdown-facts-C9yWB2I9.d.mts → markdown-facts-DLclHfpE.d.mts} +0 -0
- /package/dist/{opsx-display-path-eWJ4ve-O.d.mts → opsx-display-path-BD34M8QV.d.mts} +0 -0
- /package/dist/{opsx-display-path-DuPEvPV0.mjs → opsx-display-path-ocbNzMZj.mjs} +0 -0
- /package/dist/{opsx-entity-Br5S5N0o.mjs → opsx-entity-BnO3k48r.mjs} +0 -0
- /package/dist/{opsx-schema-detail-CckZIEVr.mjs → opsx-schema-detail-zk8ePaKK.mjs} +0 -0
- /package/dist/{opsx-workflows-Bhh_bI-e.d.mts → opsx-workflows-DX1r6e5j.d.mts} +0 -0
- /package/dist/{opsx-workflows-GPZSe1C_.mjs → opsx-workflows-byPfLlo8.mjs} +0 -0
- /package/dist/{schemas-BrS9qSB3.mjs → schemas-CMThmKx1.mjs} +0 -0
- /package/dist/{sounds-na4c8j0c.mjs → sounds-6prQvKXl.mjs} +0 -0
- /package/dist/{store-content-projection-BPDCma8v.d.mts → store-content-projection-R74MV_sD.d.mts} +0 -0
- /package/dist/{store-types-Cs40yohL.mjs → store-types-CvpEVNoE.mjs} +0 -0
- /package/dist/{terminal-control-BvoxwQ6m.mjs → terminal-control-c6oS-lFb.mjs} +0 -0
- /package/dist/{terminal-invocation-BexVY5E2.mjs → terminal-invocation-DIpoFYDo.mjs} +0 -0
- /package/dist/{terminal-theme-DIhzj5Si.mjs → terminal-theme-Byzxmnjm.mjs} +0 -0
- /package/dist/{terminal-theme-BzARb2Do.d.mts → terminal-theme-DX08Gci8.d.mts} +0 -0
- /package/dist/{translation-language-pair-DeAiww3_.d.mts → translation-language-pair-BR5uxGm-.d.mts} +0 -0
- /package/dist/{translation-language-pair-BV2cGjfv.mjs → translation-language-pair-DG9mOuFD.mjs} +0 -0
- /package/dist/{translator-DCCZeHt1.mjs → translator-CEGdRmKw.mjs} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,37 +1,39 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { a as
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { a as
|
|
7
|
-
import { a as
|
|
8
|
-
import { a as
|
|
9
|
-
import { a as
|
|
10
|
-
import {
|
|
11
|
-
import { a as CliProjectionInvalidationCauseSchema, d as toCliProjectionCommandEvidence, f as toCliProjectionFailure, i as CliProjectionFailureSchema, l as cliProjectionStates, n as CliProjectionCommandError, o as CliProjectionNoticeSchema, p as toCliProjectionNotice, r as CliProjectionCommandEvidenceSchema, s as CliProjectionStateNameSchema, t as CliJsonValueSchema, u as createCliProjectionStateSchema } from "./cli-projection-
|
|
12
|
-
import { $ as shouldShowTranslationEngineInstallGate, A as TranslationEngineIdSchema, B as TranslationLocalLlamaSettingsUpdateSchema, C as TranslationDownloadGroupPlanSchema, D as TranslationEngineDependencyStatusSchema, E as TranslationEngineDependencyStateSchema, F as TranslationEngineRuntimeStateSchema, G as createTranslationEngineLifecycleStatus, H as TranslationLocalSettingsUpdateSchema, I as TranslationEngineRuntimeStatusSchema, J as getTranslationEngineManifest, K as getManagedLocalTranslationEngineManifest, L as TranslationLocalCt2SettingsSchema, M as TranslationEngineInstallLogStreamSchema, N as TranslationEngineLifecycleEventSchema, O as TranslationEngineGlobalSettingsSchema, P as TranslationEngineLifecycleStatusSchema, Q as isTranslationEngineRuntimeReady, R as TranslationLocalCt2SettingsUpdateSchema, S as TranslationDownloadFilePlanSchema, T as TranslationEngineAssetStatusSchema, U as TranslationOpenAISettingsSchema, V as TranslationLocalSettingsSchema, W as TranslationOpenAISettingsUpdateSchema, X as isManagedLocalTranslationEngineId, Y as isDirectionalManagedLocalTranslationEngineId, Z as isTranslationEngineDependencyReady, _ as SERVICE_TRANSLATION_ENGINE_IDS, a as LocalModelAssetLogSchema, b as TRANSLATION_ENGINE_MANIFESTS, c as LocalModelDownloadStatusSchema, d as LocalModelProfileLoadStateSchema, et as isBatchTranslationAbort, f as LocalModelProfileManifestFileSchema, g as ManagedLocalCatalogSourceSchema, h as LocalModelProfileStatusSchema, i as DEFAULT_TRANSLATION_ENGINE_ID, j as TranslationEngineInstallLogEventSchema, k as TranslationEngineGlobalSettingsUpdateSchema, l as LocalModelLifecycleFileStateSchema, m as LocalModelProfileManifestSchema, n as BatchTranslateInputSchema, nt as runControlledTranslationTask, o as LocalModelAssetPlanSnapshotSchema, p as LocalModelProfileManifestGroupSchema, q as getTranslationEngineLifecycleMessage, s as LocalModelAssetStateSchema, t as BatchTranslateEventSchema, tt as normalizeBatchTranslationError, u as LocalModelLifecycleGroupStateSchema, v as ServiceTranslationEngineIdSchema, w as TranslationEngineAssetStateSchema, x as TRANSLATOR_CONTRACT_VERSION, y as TRANSLATION_ENGINE_IDS, z as TranslationLocalLlamaSettingsSchema } from "./translator-
|
|
13
|
-
import { a as
|
|
14
|
-
import {
|
|
15
|
-
import { n as
|
|
16
|
-
import {
|
|
17
|
-
import { n as
|
|
18
|
-
import {
|
|
19
|
-
import { i as
|
|
20
|
-
import { n as
|
|
21
|
-
import {
|
|
22
|
-
import { a as
|
|
23
|
-
import { a as
|
|
24
|
-
import { a as
|
|
25
|
-
import "./store-
|
|
26
|
-
import
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import { n as
|
|
30
|
-
import {
|
|
1
|
+
import { B as CliWorkflowStatusSuccessSchema, C as CliArchiveInstructionsSuccessSchema, E as CliArtifactInstructionsSuccessSchema, F as CliShowSpecSchema, G as CliStoreDoctorSchema, H as CliDoctorSchema, I as CliSpecListSchema, J as CliStoreSchema, K as CliStoreListSchema, N as CliSchemasSchema, O as CliChangeListSchema, P as CliShowSpecDocumentSchema, Q as requireOpenSpecEntityRelativePath, R as CliValidateSchema, S as CliArchiveInstructionsSchema, T as CliArtifactInstructionsSchema, U as CliStoreCleanupSchema, V as CliContextSchema, W as CliStoreDoctorEntrySchema, X as requireCanonicalOpenSpecEntityId, Y as parseCliCommandResult, Z as requireCanonicalOpenSpecSpecId, _ as specRoutePath, a as SpecDocumentProjectionSchema, b as CliApplyInstructionsSchema, c as createStaticSpecCatalogOwnedProjection, d as getSpecCatalogEntry, f as isReferencedSpecIdentity, g as specIdentityKey, h as specIdentityFromRoute, i as SpecCommandEvidenceSchema, l as createStaticSpecCatalogReferenceProjection, m as specDocumentDisplayPath, n as ReferencedSpecIdentitySchema, o as SpecIdentitySchema, p as mergeSpecCatalog, q as CliStoreMutationSchema, r as SpecCatalogSchema, s as buildSpecCatalog, t as OwnedSpecIdentitySchema, u as createStaticSpecCatalogReferenceSource, v as OpenSpecCliContractExecutor, w as CliArchiveSchema, x as CliApplyInstructionsSuccessSchema, z as CliWorkflowStatusSchema } from "./spec-catalog-DEk_oHAx.mjs";
|
|
2
|
+
import { _ as isTextLikeMime, a as DeltaSpecSchema, c as ScenarioStepSchema, d as TrackedTaskProgressSchema, f as FILE_PREVIEW_KINDS, g as isTextLikeFile, h as isPreviewableFile, i as DeltaSchema, l as SpecSchema, m as inferFilePreviewKind, n as ChangeSchema, o as RequirementSchema, p as inferFileMime, r as DeltaOperationType, s as ScenarioStepKeywordSchema, t as ChangeFileSchema, u as TaskSchema } from "./schemas-CMThmKx1.mjs";
|
|
3
|
+
import { a as normalizeOpsxEntityPath, c as parseOpsxEntityMetadata, i as isOpsxGlobPattern, n as getOpsxEntityMetadataPath, o as opsxGlobToRegex, r as getOpsxEntityRootRelativePath, s as opsxPathMatchesPattern, t as buildOpsxEntityDetail } from "./opsx-entity-BnO3k48r.mjs";
|
|
4
|
+
import { t as parseOpsxSchemaDetail } from "./opsx-schema-detail-zk8ePaKK.mjs";
|
|
5
|
+
import { n as toMarkdownFactKind, t as parseMarkdownFacts } from "./markdown-facts-BIx47NNY.mjs";
|
|
6
|
+
import { a as getMarkdownAnnotation, c as getMarkdownHeadingEnd, d as trimMarkdownSlice, i as createMarkdownReadingDocumentFromFacts, l as getMarkdownHeadingFacts, n as buildMarkdownParentMap, o as getMarkdownAnnotationsForFact, r as createMarkdownReadingDocument, s as getMarkdownFactSpan, t as MarkdownReadingPluginRegistry, u as sortMarkdownReadingPlugins } from "./markdown-reading-LtgFpB8E.mjs";
|
|
7
|
+
import { a as getOpenSpecAnnotationsForFact, i as getOpenSpecAnnotation, n as annotateOpenSpecMarkdown, o as openSpecAnnotationRules, r as builtinOpenSpecReadingPlugin, t as annotateOpenSpecFacts } from "./openspec-annotations-BJ1BlVyo.mjs";
|
|
8
|
+
import { a as getOpenSpecReadingSections, c as projectOpenSpecMarkdown, i as getOpenSpecProjectionAnnotation, n as OPEN_SPEC_SPEC_PROJECTION_ID, o as parseOpenSpecMarkdownToSpec, r as createOpenSpecReadingPlugin, s as projectAnnotatedOpenSpecToSpec, t as OPEN_SPEC_READING_SECTIONS_PROJECTION_ID } from "./openspec-projection-Cno7FlwE.mjs";
|
|
9
|
+
import { a as isMarkdownTaskSourcePath, c as toggleMarkdownTask, i as deriveTrackedTaskPhase, n as createDocumentChecklistSummary, o as parseMarkdownTasks, r as createTrackedTaskProgress, s as projectTaskProjectionsFromMarkdownFiles, t as createApplyInstructionProgress } from "./task-progress-Bvid_Ws8.mjs";
|
|
10
|
+
import { a as CliRootSchema, i as CliReferenceIndexEntrySchema, n as CliDiagnosticSchema, o as CliRootSourceSchema, r as CliDoctorReferenceEntrySchema, t as CliDiagnosticFailureSchema } from "./common-BRL_34xt.mjs";
|
|
11
|
+
import { a as CliProjectionInvalidationCauseSchema, d as toCliProjectionCommandEvidence, f as toCliProjectionFailure, i as CliProjectionFailureSchema, l as cliProjectionStates, n as CliProjectionCommandError, o as CliProjectionNoticeSchema, p as toCliProjectionNotice, r as CliProjectionCommandEvidenceSchema, s as CliProjectionStateNameSchema, t as CliJsonValueSchema, u as createCliProjectionStateSchema } from "./cli-projection-CKRwTvwf.mjs";
|
|
12
|
+
import { $ as shouldShowTranslationEngineInstallGate, A as TranslationEngineIdSchema, B as TranslationLocalLlamaSettingsUpdateSchema, C as TranslationDownloadGroupPlanSchema, D as TranslationEngineDependencyStatusSchema, E as TranslationEngineDependencyStateSchema, F as TranslationEngineRuntimeStateSchema, G as createTranslationEngineLifecycleStatus, H as TranslationLocalSettingsUpdateSchema, I as TranslationEngineRuntimeStatusSchema, J as getTranslationEngineManifest, K as getManagedLocalTranslationEngineManifest, L as TranslationLocalCt2SettingsSchema, M as TranslationEngineInstallLogStreamSchema, N as TranslationEngineLifecycleEventSchema, O as TranslationEngineGlobalSettingsSchema, P as TranslationEngineLifecycleStatusSchema, Q as isTranslationEngineRuntimeReady, R as TranslationLocalCt2SettingsUpdateSchema, S as TranslationDownloadFilePlanSchema, T as TranslationEngineAssetStatusSchema, U as TranslationOpenAISettingsSchema, V as TranslationLocalSettingsSchema, W as TranslationOpenAISettingsUpdateSchema, X as isManagedLocalTranslationEngineId, Y as isDirectionalManagedLocalTranslationEngineId, Z as isTranslationEngineDependencyReady, _ as SERVICE_TRANSLATION_ENGINE_IDS, a as LocalModelAssetLogSchema, b as TRANSLATION_ENGINE_MANIFESTS, c as LocalModelDownloadStatusSchema, d as LocalModelProfileLoadStateSchema, et as isBatchTranslationAbort, f as LocalModelProfileManifestFileSchema, g as ManagedLocalCatalogSourceSchema, h as LocalModelProfileStatusSchema, i as DEFAULT_TRANSLATION_ENGINE_ID, j as TranslationEngineInstallLogEventSchema, k as TranslationEngineGlobalSettingsUpdateSchema, l as LocalModelLifecycleFileStateSchema, m as LocalModelProfileManifestSchema, n as BatchTranslateInputSchema, nt as runControlledTranslationTask, o as LocalModelAssetPlanSnapshotSchema, p as LocalModelProfileManifestGroupSchema, q as getTranslationEngineLifecycleMessage, s as LocalModelAssetStateSchema, t as BatchTranslateEventSchema, tt as normalizeBatchTranslationError, u as LocalModelLifecycleGroupStateSchema, v as ServiceTranslationEngineIdSchema, w as TranslationEngineAssetStateSchema, x as TRANSLATOR_CONTRACT_VERSION, y as TRANSLATION_ENGINE_IDS, z as TranslationLocalLlamaSettingsSchema } from "./translator-CEGdRmKw.mjs";
|
|
13
|
+
import { a as ActiveRootOfficialConfigSchema, c as MAX_ACTIVE_ROOT_CONTEXT_BYTES, i as ActiveRootMutationSchema, n as patchActiveRootOfficialFields, o as ActiveRootRevisionSchema, r as validateActiveRootRawYaml, s as ActiveRootStructuredUpdateSchema, t as inspectActiveRootOfficialConfig } from "./active-root-config-L5QaMb3A.mjs";
|
|
14
|
+
import { a as DocumentTranslationDisplayModeSchema, c as TRANSLATION_CACHE_POLICY_VERSION, d as TranslationCacheSettingsSchema, f as TranslationCacheSettingsUpdateSchema, g as TranslationEngineProjectSettingsUpdateSchema, h as TranslationEngineProjectSettingsSchema, i as DocumentTranslationConfigUpdateSchema, l as TranslationCacheEntrySchema, m as TranslationCacheWriteInputSchema, n as DOCUMENT_TRANSLATION_DISPLAY_MODES, o as MAX_TRANSLATION_CACHE_ENTRY_LIMIT, p as TranslationCacheStatsSchema, r as DocumentTranslationConfigSchema, s as MIN_TRANSLATION_CACHE_ENTRY_LIMIT, t as DEFAULT_TRANSLATION_CACHE_ENTRY_LIMIT, u as TranslationCacheReadInputSchema } from "./document-translation-B3xaP0dJ.mjs";
|
|
15
|
+
import { _ as customHashFromSoundId, a as CustomSoundHashSchema, b as soundIdFromCustomHash, c as CustomSoundMetadataSchema, f as LEGACY_SOUND_ID_MAP, g as SoundVolumeSchema, h as SoundIdSchema, i as CUSTOM_SOUND_ADD_VALUE, l as DEFAULT_BELL_SOUND_ID, m as SoundConfigIdSchema, n as BUILTIN_SOUND_OPTIONS, o as CustomSoundIdSchema, p as SILENT_SOUND_ID, r as BuiltinSoundIdSchema, s as CustomSoundMetadataFileSchema, t as BUILTIN_SOUND_IDS, u as DEFAULT_NOTIFICATION_SOUND_ID, v as getBuiltinSoundUrl, y as normalizeLegacySoundId } from "./sounds-6prQvKXl.mjs";
|
|
16
|
+
import { n as terminalNotificationEventToPublishInput, t as TerminalControlParser } from "./terminal-control-c6oS-lFb.mjs";
|
|
17
|
+
import { a as NotificationPublishInputSchema, c as NotificationSoundSchema, h as groupNotifications, i as NotificationGroupKeySchema, l as NotificationSourceSchema, m as getNotificationGroupLabel, n as NOTIFICATION_SOUND_VALUES, o as NotificationRecordSchema, p as getNotificationGroupKey, r as NotificationActionSchema, s as NotificationSettingsSchema, t as NOTIFICATION_SOUND_OPTIONS, u as TerminalNotificationParser } from "./notifications-Cy74GVN7.mjs";
|
|
18
|
+
import { n as TERMINAL_BELL_SOUND_VALUES, r as TerminalBellSoundSchema, t as TERMINAL_BELL_SOUND_OPTIONS } from "./terminal-audio-DeubAfFC.mjs";
|
|
19
|
+
import { a as TERMINAL_THEME_VALUES, i as TERMINAL_THEME_MODE_VALUES, n as DEFAULT_TERMINAL_LIGHT_THEME, r as DEFAULT_TERMINAL_THEME_MODE, t as DEFAULT_TERMINAL_DARK_THEME } from "./terminal-theme-Byzxmnjm.mjs";
|
|
20
|
+
import { i as selectLocalDownloadGroup, n as buildLocalDownloadPlanFromRepositoryFiles, r as buildLocalDownloadPlanFromRuntimeProfileFiles, t as LOCAL_MODEL_PROFILE_DEFINITIONS } from "./local-download-profiles-h9lUTXr-.mjs";
|
|
21
|
+
import { n as inferLocalDirectionalModelLanguagePair, t as checkLocalDirectionalModelLanguagePair } from "./translation-language-pair-DG9mOuFD.mjs";
|
|
22
|
+
import { C as SchemaResolutionSchema, D as isGlobPattern, E as TemplatesSchema, S as SchemaInfoSchema, T as TemplateContentSchema, _ as OpsxCliEvidenceSchema, a as PlanningCliProjectionDataSchema, b as SchemaArtifactSchema, c as ApplyInstructionsContextFilesSchema, d as ApplyTaskSchema, f as ArchiveInstructionsSchema, g as DependencyInfoSchema, h as ChangeStatusSchema, i as EnvironmentGlobalProjectionStateSchema, l as ApplyInstructionsProjectionSchema, m as ArtifactStatusSchema, n as EnvironmentGlobalFileProjectionStateSchema, o as PlanningCliProjectionSelectorSchema, p as ArtifactInstructionsSchema, r as EnvironmentGlobalProjectionDataSchema, s as PlanningCliProjectionStateSchema, t as EnvironmentGlobalFileProjectionDataSchema, u as ApplyInstructionsSchema, v as OpsxConfigBundleSchema, w as TemplateContentMapSchema, x as SchemaDetailSchema, y as OpsxStatusEvidenceSchema } from "./planning-cli-projection-BreqsrYA.mjs";
|
|
23
|
+
import { a as OPSX_CORE_PROFILE_WORKFLOWS, c as OPSX_WORKFLOW_TO_SKILL_DIR, i as OPSX_COMMAND_CAPABLE_WORKFLOWS, l as isOpsxCoreWorkflowSelection, n as OPSX_ARTIFACT_INPUT_ACTIONS, o as OPSX_TEXT_INPUT_ACTIONS, r as OPSX_CHANGE_INPUT_ACTIONS, s as OPSX_WORKFLOW_LABELS, t as OPSX_ALL_WORKFLOWS } from "./opsx-workflows-byPfLlo8.mjs";
|
|
24
|
+
import { a as DASHBOARD_METRIC_KEYS, c as DashboardSummaryProjectionSchema, i as DashboardSummaryProjectionStateSchema, l as DashboardTrendsProjectionSchema, n as DashboardSummaryInvalidationCauseSchema, o as DashboardGitSnapshotSchema, r as DashboardSummaryInvalidationSchema, s as DashboardOverviewSchema, t as DashboardSummaryIdentitySchema } from "./dashboard-summary-transport-ILCfZD_I.mjs";
|
|
25
|
+
import { a as StoreListResultSchema, n as StoreDoctorResultSchema, o as classifyStoreCliResult, s as toStoreFeatureResult } from "./store-types-CvpEVNoE.mjs";
|
|
26
|
+
import "./store-content-projection-Bpdb7_d9.mjs";
|
|
27
|
+
import { i as StoreMutationStartResponseSchema, n as StoreMutationResultSchema, r as StoreMutationSchema, t as StoreMutationLifecycleEventSchema } from "./store-mutation-protocol-CJGUWWI6.mjs";
|
|
28
|
+
import { C as OPENSPECUI_RUNTIME_CAPABILITIES, D as isTerminalMutationStatus, E as hasCapability, T as asEnvUri, t as HOSTED_SHELL_PROTOCOL_VERSION } from "./hosted-contract-BxUx6ksP.mjs";
|
|
29
|
+
import { a as buildHostedLaunchUrl, c as isSupportedEmbeddedUiUrl, d as resolveHostedAppBaseUrl, i as buildEmbeddedUiLaunchUrl, l as normalizeEmbeddedUiUrl, n as OFFICIAL_APP_BASE_URL, o as isBackendHealthRuntimeMetadata, r as buildBackendHealthPayload, s as isHostedBackendHealthResponse, u as normalizeHostedAppBaseUrl } from "./hosted-app-B_T_tTvO.mjs";
|
|
30
|
+
import { n as toOpsxDisplayPath, t as VIRTUAL_PROJECT_DIRNAME } from "./opsx-display-path-ocbNzMZj.mjs";
|
|
31
|
+
import { a as TerminalInvocationSettingsSchema, c as TerminalSpawnCommandSchema, f as quoteTerminalShellArg, g as resolveTerminalShellDefaults, h as renderTerminalSpawnCommandLine, i as TerminalCommandFieldSchema, n as TERMINAL_COMMAND_FIELD_TYPE_VALUES, o as TerminalShellProfileSchema, p as renderTerminalCommandArgs, r as TERMINAL_SHELL_QUOTE_STYLE_VALUES, s as TerminalShellQuoteStyleSchema, t as BUILTIN_TERMINAL_SPAWN_COMMANDS, u as getTerminalCommandDefaultValues } from "./terminal-invocation-DIpoFYDo.mjs";
|
|
31
32
|
import { mkdir, writeFile } from "fs/promises";
|
|
32
33
|
import { dirname, join } from "path";
|
|
33
34
|
import { isMap, parseDocument } from "yaml";
|
|
34
|
-
import {
|
|
35
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
36
|
+
import { access, lstat, mkdir as mkdir$1, open, readFile, readdir, realpath, rename, rm, stat, writeFile as writeFile$1 } from "node:fs/promises";
|
|
35
37
|
import { basename, dirname as dirname$1, isAbsolute, join as join$1, matchesGlob, posix, relative, resolve, sep, win32 } from "node:path";
|
|
36
38
|
import { existsSync, lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
37
39
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -45,24 +47,8 @@ import { homedir, loadavg, platform } from "node:os";
|
|
|
45
47
|
import { context, trace } from "@opentelemetry/api";
|
|
46
48
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
47
49
|
import { Worker } from "node:worker_threads";
|
|
48
|
-
import {
|
|
50
|
+
import { pathToFileURL } from "node:url";
|
|
49
51
|
|
|
50
|
-
//#region src/entity-id.ts
|
|
51
|
-
/** Return one path-safe OpenSpec entity id or reject it before filesystem access. */
|
|
52
|
-
function requireCanonicalOpenSpecEntityId(value, field) {
|
|
53
|
-
if (value.length === 0 || value !== value.trim() || value === "." || value === ".." || value.includes("/") || value.includes("\\") || value.includes("\0")) throw new Error(`Invalid ${field}: expected one canonical path segment.`);
|
|
54
|
-
return value;
|
|
55
|
-
}
|
|
56
|
-
/** Return one normalized entity-relative path or glob without parent traversal. */
|
|
57
|
-
function requireOpenSpecEntityRelativePath(value, field) {
|
|
58
|
-
const normalizedSeparators = value.replace(/\\/g, "/");
|
|
59
|
-
if (normalizedSeparators.length === 0 || normalizedSeparators.includes("\0") || normalizedSeparators.startsWith("/") || /^[A-Za-z]:/.test(normalizedSeparators) || normalizedSeparators.split("/").includes("..")) throw new Error(`Invalid ${field}: expected an entity-relative path.`);
|
|
60
|
-
const normalizedPath = normalizedSeparators.split("/").filter((segment) => segment.length > 0 && segment !== ".").join("/");
|
|
61
|
-
if (!normalizedPath) throw new Error(`Invalid ${field}: expected an entity-relative path.`);
|
|
62
|
-
return normalizedPath;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
//#endregion
|
|
66
52
|
//#region src/parser.ts
|
|
67
53
|
const SCENARIO_STEP_PATTERN = new RegExp(`^\\s*[-*+]\\s+(?:\\*\\*)?(${[
|
|
68
54
|
"GIVEN",
|
|
@@ -1306,13 +1292,15 @@ var ReactiveContext = class {
|
|
|
1306
1292
|
//#endregion
|
|
1307
1293
|
//#region src/reactive-fs/reactive-fs.ts
|
|
1308
1294
|
/**
|
|
1309
|
-
* Orthogonal intents (updated 2026-
|
|
1295
|
+
* Orthogonal intents (updated 2026-08-01 Asia/Shanghai):
|
|
1310
1296
|
* 1. Cache reactive file, directory, existence, and stat reads.
|
|
1311
1297
|
* 2. Bind cached reads to shared watcher roots and missing-path fallback checks.
|
|
1312
1298
|
* 3. Settle overlapping cached projections as one coherent post-mutation snapshot.
|
|
1313
1299
|
* 4. Release watcher, polling, state, and refresh registrations together.
|
|
1300
|
+
* 5. Distinguish expected missing paths from integrity-relevant filesystem read failures.
|
|
1314
1301
|
*
|
|
1315
1302
|
* Original request (2026-07-16): "direct filesystem mutations update reactive state before returning."
|
|
1303
|
+
* Original request (2026-08-01): nested Spec discovery must not silently drop unreadable subtrees.
|
|
1316
1304
|
*/
|
|
1317
1305
|
/** 状态缓存:路径 -> ReactiveState */
|
|
1318
1306
|
const stateCache$1 = /* @__PURE__ */ new Map();
|
|
@@ -1452,7 +1440,8 @@ async function reactiveReadDir(dirpath, options = {}) {
|
|
|
1452
1440
|
if (options.filesOnly && !entry.isFile()) return false;
|
|
1453
1441
|
return true;
|
|
1454
1442
|
}).map((entry) => entry.name);
|
|
1455
|
-
} catch {
|
|
1443
|
+
} catch (error) {
|
|
1444
|
+
if (options.throwOnError === true && error?.code !== "ENOENT") throw error;
|
|
1456
1445
|
return [];
|
|
1457
1446
|
}
|
|
1458
1447
|
};
|
|
@@ -1628,14 +1617,15 @@ function getCacheSize() {
|
|
|
1628
1617
|
//#endregion
|
|
1629
1618
|
//#region src/physical-reactive-file-writer.ts
|
|
1630
1619
|
/**
|
|
1631
|
-
* Orthogonal intents (updated 2026-
|
|
1620
|
+
* Orthogonal intents (updated 2026-08-02 Asia/Shanghai):
|
|
1632
1621
|
* 1. Own lexical and existing-ancestor physical confinement for root-scoped mutations.
|
|
1633
|
-
* 2. Execute UTF-8 write, directory-create, remove, and guarded external mutations.
|
|
1622
|
+
* 2. Execute direct or atomic UTF-8 write, directory-create, remove, and guarded external mutations.
|
|
1634
1623
|
* 3. Settle overlapping reactive projections before returning any terminal outcome.
|
|
1635
1624
|
* 4. Keep TOCTOU and hard-link alias limitations explicit at the mutation seam.
|
|
1636
1625
|
*
|
|
1637
1626
|
* Original request (2026-07-16): "建立唯一的 physical/reactive entity-write owner。"
|
|
1638
1627
|
* Original request (2026-07-16): "Schema/Template mutations must reject symlink escape and settle reactive projections before success."
|
|
1628
|
+
* Derived requirement (2026-08-02): "Raw Active Root YAML uses same-directory atomic replacement before reactive settlement."
|
|
1639
1629
|
*/
|
|
1640
1630
|
function isMissingPath(error) {
|
|
1641
1631
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
@@ -1722,6 +1712,80 @@ async function writePhysicalReactiveFile(input) {
|
|
|
1722
1712
|
await writeFile$1(target.targetPath, input.content, "utf8");
|
|
1723
1713
|
}, (targetPath) => settleReactiveFileWrite(targetPath, input.content));
|
|
1724
1714
|
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Atomically replace one UTF-8 file inside an existing physical root, then settle reactive readers.
|
|
1717
|
+
*
|
|
1718
|
+
* The temporary file is created exclusively in the target directory, flushed, and renamed over the
|
|
1719
|
+
* destination. Existing permission bits are retained where available. Crash-durable directory fsync is
|
|
1720
|
+
* intentionally outside this cross-platform contract; successful callers observe one complete replacement.
|
|
1721
|
+
*/
|
|
1722
|
+
async function writeAtomicPhysicalReactiveFile(input) {
|
|
1723
|
+
await runResolvedPhysicalReactivePathMutation(input, async (target) => {
|
|
1724
|
+
const targetDirectory = dirname$1(target.targetPath);
|
|
1725
|
+
await mkdir$1(targetDirectory, { recursive: true });
|
|
1726
|
+
await assertMutationTarget(target);
|
|
1727
|
+
const targetInfo = await readLstat(target.targetPath);
|
|
1728
|
+
const temporaryPath = join$1(targetDirectory, `.${basename(target.targetPath)}.${randomUUID()}.tmp`);
|
|
1729
|
+
let temporaryFile = null;
|
|
1730
|
+
try {
|
|
1731
|
+
temporaryFile = await open(temporaryPath, "wx", targetInfo ? targetInfo.mode & 511 : 438);
|
|
1732
|
+
await temporaryFile.writeFile(input.content, "utf8");
|
|
1733
|
+
await temporaryFile.sync();
|
|
1734
|
+
await temporaryFile.close();
|
|
1735
|
+
temporaryFile = null;
|
|
1736
|
+
await assertMutationTarget(target);
|
|
1737
|
+
await rename(temporaryPath, target.targetPath);
|
|
1738
|
+
} finally {
|
|
1739
|
+
await temporaryFile?.close().catch(() => void 0);
|
|
1740
|
+
await rm(temporaryPath, { force: true }).catch(() => void 0);
|
|
1741
|
+
}
|
|
1742
|
+
}, (targetPath) => settleReactiveFileWrite(targetPath, input.content));
|
|
1743
|
+
}
|
|
1744
|
+
async function readPhysicalUtf8(path) {
|
|
1745
|
+
try {
|
|
1746
|
+
return await readFile(path, "utf8");
|
|
1747
|
+
} catch (error) {
|
|
1748
|
+
if (isMissingPath(error)) return null;
|
|
1749
|
+
throw error;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* Compare current physical bytes immediately before atomic replacement and settle either outcome.
|
|
1754
|
+
*
|
|
1755
|
+
* This closes stale in-process writers through their serialized caller and detects observed external
|
|
1756
|
+
* replacement after the temporary file is ready. Platforms expose no path-level atomic compare-and-swap,
|
|
1757
|
+
* so an external process can still race in the final compare-to-rename interval.
|
|
1758
|
+
*/
|
|
1759
|
+
async function compareAndWriteAtomicPhysicalReactiveFile(input) {
|
|
1760
|
+
let committed = false;
|
|
1761
|
+
return runResolvedPhysicalReactivePathMutation(input, async (target) => {
|
|
1762
|
+
const targetDirectory = dirname$1(target.targetPath);
|
|
1763
|
+
await mkdir$1(targetDirectory, { recursive: true });
|
|
1764
|
+
await assertMutationTarget(target);
|
|
1765
|
+
const targetInfo = await readLstat(target.targetPath);
|
|
1766
|
+
const temporaryPath = join$1(targetDirectory, `.${basename(target.targetPath)}.${randomUUID()}.tmp`);
|
|
1767
|
+
let temporaryFile = null;
|
|
1768
|
+
try {
|
|
1769
|
+
temporaryFile = await open(temporaryPath, "wx", targetInfo ? targetInfo.mode & 511 : 438);
|
|
1770
|
+
await temporaryFile.writeFile(input.content, "utf8");
|
|
1771
|
+
await temporaryFile.sync();
|
|
1772
|
+
await temporaryFile.close();
|
|
1773
|
+
temporaryFile = null;
|
|
1774
|
+
await assertMutationTarget(target);
|
|
1775
|
+
const currentContent = await readPhysicalUtf8(target.targetPath);
|
|
1776
|
+
if (currentContent !== input.expectedContent) return {
|
|
1777
|
+
state: "conflict",
|
|
1778
|
+
content: currentContent
|
|
1779
|
+
};
|
|
1780
|
+
await rename(temporaryPath, target.targetPath);
|
|
1781
|
+
committed = true;
|
|
1782
|
+
return { state: "written" };
|
|
1783
|
+
} finally {
|
|
1784
|
+
await temporaryFile?.close().catch(() => void 0);
|
|
1785
|
+
await rm(temporaryPath, { force: true }).catch(() => void 0);
|
|
1786
|
+
}
|
|
1787
|
+
}, (targetPath) => committed ? settleReactiveFileWrite(targetPath, input.content) : settleReactivePathMutation(targetPath));
|
|
1788
|
+
}
|
|
1725
1789
|
/** Create one root-confined directory and synchronously settle overlapping reactive readers. */
|
|
1726
1790
|
async function createPhysicalReactiveDirectory(input) {
|
|
1727
1791
|
await runResolvedPhysicalReactivePathMutation(input, async (target) => {
|
|
@@ -1830,14 +1894,16 @@ var Validator = class {
|
|
|
1830
1894
|
//#endregion
|
|
1831
1895
|
//#region src/adapter.ts
|
|
1832
1896
|
/**
|
|
1833
|
-
* Orthogonal intents (updated 2026-
|
|
1897
|
+
* Orthogonal intents (updated 2026-08-02 Asia/Shanghai):
|
|
1834
1898
|
* 1. Read and mutate one CLI-selected planning root through reactive filesystem APIs.
|
|
1835
|
-
* 2. Project Specs, Changes, Archives, and schema-neutral entity files.
|
|
1899
|
+
* 2. Project recursive Specs, Changes, Archives, and schema-neutral entity files.
|
|
1836
1900
|
* 3. Keep tracked workflow tasks distinct from document checklist analytics.
|
|
1837
1901
|
* 4. Preserve filesystem provenance and mutation boundaries for server consumers.
|
|
1838
|
-
* 5. Expose
|
|
1902
|
+
* 5. Expose Launch Project local-initialization evidence independently from Planning-root readiness.
|
|
1839
1903
|
*
|
|
1840
1904
|
* Original request (2026-07-15): "Split formal tracked progress, document checklist statistics, and Apply instruction progress into non-interchangeable facts."
|
|
1905
|
+
* Original request (2026-08-01): adapt OpenSpec 1.7 nested Spec ids such as `platform/auth`.
|
|
1906
|
+
* Review correction (2026-08-02): a same-named ordinary file is not initialized project structure.
|
|
1841
1907
|
*/
|
|
1842
1908
|
/**
|
|
1843
1909
|
* OpenSpec filesystem adapter
|
|
@@ -1873,8 +1939,21 @@ var OpenSpecAdapter = class {
|
|
|
1873
1939
|
updatedAt: statInfo.mtime
|
|
1874
1940
|
};
|
|
1875
1941
|
}
|
|
1942
|
+
/** List every Spec directory containing `spec.md` as a slash-separated relative identity. */
|
|
1876
1943
|
async listSpecs() {
|
|
1877
|
-
|
|
1944
|
+
const visit = async (directory, prefix) => {
|
|
1945
|
+
const names = await reactiveReadDir(directory, {
|
|
1946
|
+
directoriesOnly: true,
|
|
1947
|
+
throwOnError: true
|
|
1948
|
+
});
|
|
1949
|
+
return (await Promise.all(names.map(async (name) => {
|
|
1950
|
+
const specDirectory = join(directory, name);
|
|
1951
|
+
const specId = prefix ? `${prefix}/${name}` : name;
|
|
1952
|
+
const [content, descendants] = await Promise.all([reactiveReadFile(join(specDirectory, "spec.md")), visit(specDirectory, specId)]);
|
|
1953
|
+
return content === null ? descendants : [specId, ...descendants];
|
|
1954
|
+
}))).flat();
|
|
1955
|
+
};
|
|
1956
|
+
return (await visit(this.specsDir, "")).sort((left, right) => left < right ? -1 : left > right ? 1 : 0);
|
|
1878
1957
|
}
|
|
1879
1958
|
/**
|
|
1880
1959
|
* List specs with metadata (id, name, and time info)
|
|
@@ -1976,7 +2055,7 @@ var OpenSpecAdapter = class {
|
|
|
1976
2055
|
}
|
|
1977
2056
|
}
|
|
1978
2057
|
async readSpecRaw(specId) {
|
|
1979
|
-
const canonicalSpecId =
|
|
2058
|
+
const canonicalSpecId = requireCanonicalOpenSpecSpecId(specId);
|
|
1980
2059
|
return reactiveReadFile(join(this.specsDir, canonicalSpecId, "spec.md"));
|
|
1981
2060
|
}
|
|
1982
2061
|
async readChange(changeId) {
|
|
@@ -2151,7 +2230,7 @@ var OpenSpecAdapter = class {
|
|
|
2151
2230
|
};
|
|
2152
2231
|
}
|
|
2153
2232
|
async writeSpec(specId, content) {
|
|
2154
|
-
const canonicalSpecId =
|
|
2233
|
+
const canonicalSpecId = requireCanonicalOpenSpecSpecId(specId);
|
|
2155
2234
|
await writePhysicalReactiveFile({
|
|
2156
2235
|
rootPath: this.projectDir,
|
|
2157
2236
|
relativePath: join("openspec", "specs", canonicalSpecId, "spec.md"),
|
|
@@ -2181,6 +2260,14 @@ var OpenSpecAdapter = class {
|
|
|
2181
2260
|
content
|
|
2182
2261
|
});
|
|
2183
2262
|
}
|
|
2263
|
+
/** Read the reactive local `openspec/` existence fact for the Launch Project. */
|
|
2264
|
+
async readLaunchProjectInitialization() {
|
|
2265
|
+
return {
|
|
2266
|
+
initialized: (new Set(await reactiveReadDir(this.projectDir, { includeHidden: true })).has("openspec") ? await reactiveStat(this.openspecDir) : null)?.isDirectory ?? false,
|
|
2267
|
+
launchProjectPath: this.projectDir,
|
|
2268
|
+
openspecPath: this.openspecDir
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
2184
2271
|
async init() {
|
|
2185
2272
|
await mkdir(this.specsDir, { recursive: true });
|
|
2186
2273
|
await mkdir(this.changesDir, { recursive: true });
|
|
@@ -2251,12 +2338,12 @@ This project uses OpenSpec for spec-driven development.
|
|
|
2251
2338
|
//#endregion
|
|
2252
2339
|
//#region src/planning-config.ts
|
|
2253
2340
|
/**
|
|
2254
|
-
* Orthogonal intents (updated 2026-
|
|
2341
|
+
* Orthogonal intents (updated 2026-08-01 Asia/Shanghai):
|
|
2255
2342
|
* 1. Define distinct Project Binding, Active Root, and reactive Environment Global config projections.
|
|
2256
2343
|
* 2. Inspect launch-project Store/Reference declarations without replacing CLI Root Context truth.
|
|
2257
2344
|
* 3. Update only binding fields while preserving unrelated YAML fields and comments.
|
|
2258
2345
|
* 4. Describe a typed launch-write result separately from asynchronous Root Context convergence.
|
|
2259
|
-
* 5. Separate
|
|
2346
|
+
* 5. Separate configured Environment defaults from CLI-effective Root Context truth and file bytes.
|
|
2260
2347
|
*
|
|
2261
2348
|
* Original request (2026-07-15): "Config ownership separates launch-project binding, active-root config, and environment-global config."
|
|
2262
2349
|
* Original request (2026-07-18): "Profile/Drift must refresh with external environment config changes."
|
|
@@ -2273,6 +2360,8 @@ const PlanningConfigJsonValueSchema = z.lazy(() => z.union([
|
|
|
2273
2360
|
]));
|
|
2274
2361
|
/** Runtime schema for the complete environment-global OpenSpec configuration document. */
|
|
2275
2362
|
const EnvironmentGlobalConfigValueSchema = z.record(z.string(), PlanningConfigJsonValueSchema);
|
|
2363
|
+
/** Runtime schema for setting or explicitly clearing the machine default Store id. */
|
|
2364
|
+
const EnvironmentDefaultStoreUpdateSchema = z.object({ value: z.string().min(1).nullable() });
|
|
2276
2365
|
/** Runtime schema for one project-declared Store Reference entry. */
|
|
2277
2366
|
const PlanningConfigReferenceSchema = z.object({
|
|
2278
2367
|
id: z.string().min(1),
|
|
@@ -2283,12 +2372,29 @@ const ProjectBindingUpdateSchema = z.object({
|
|
|
2283
2372
|
store: z.string().min(1).nullable().optional(),
|
|
2284
2373
|
references: z.array(PlanningConfigReferenceSchema).nullable().optional()
|
|
2285
2374
|
}).refine((value) => value.store !== void 0 || value.references !== void 0, { message: "At least one Project Binding field is required." });
|
|
2286
|
-
function isRecord(value) {
|
|
2375
|
+
function isRecord$1(value) {
|
|
2287
2376
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2288
2377
|
}
|
|
2378
|
+
/** Inspect only the authored machine fallback; Root Context remains the effective authority. */
|
|
2379
|
+
function inspectEnvironmentDefaultStore(config) {
|
|
2380
|
+
if (!config || !Object.prototype.hasOwnProperty.call(config, "defaultStore")) return {
|
|
2381
|
+
state: "absent",
|
|
2382
|
+
id: null
|
|
2383
|
+
};
|
|
2384
|
+
const value = config.defaultStore;
|
|
2385
|
+
if (typeof value === "string" && value.length > 0) return {
|
|
2386
|
+
state: "configured",
|
|
2387
|
+
id: value
|
|
2388
|
+
};
|
|
2389
|
+
return {
|
|
2390
|
+
state: "invalid",
|
|
2391
|
+
id: null,
|
|
2392
|
+
value: value ?? null
|
|
2393
|
+
};
|
|
2394
|
+
}
|
|
2289
2395
|
function inspectReference(value) {
|
|
2290
2396
|
if (typeof value === "string" && value.length > 0) return { id: value };
|
|
2291
|
-
if (!isRecord(value) || typeof value.id !== "string" || value.id.length === 0) return null;
|
|
2397
|
+
if (!isRecord$1(value) || typeof value.id !== "string" || value.id.length === 0) return null;
|
|
2292
2398
|
if (value.remote === void 0) return { id: value.id };
|
|
2293
2399
|
if (typeof value.remote !== "string" || value.remote.length === 0) return null;
|
|
2294
2400
|
return {
|
|
@@ -2320,7 +2426,7 @@ function inspectProjectBinding(content) {
|
|
|
2320
2426
|
};
|
|
2321
2427
|
const raw = document.toJS();
|
|
2322
2428
|
if (raw === null) return absent;
|
|
2323
|
-
if (!isRecord(raw)) return {
|
|
2429
|
+
if (!isRecord$1(raw)) return {
|
|
2324
2430
|
...absent,
|
|
2325
2431
|
diagnostics: [{
|
|
2326
2432
|
code: "config-not-mapping",
|
|
@@ -2591,11 +2697,11 @@ function formatSpawnError(err) {
|
|
|
2591
2697
|
message: `${message}${code ? ` (${code})` : ""}`
|
|
2592
2698
|
};
|
|
2593
2699
|
}
|
|
2594
|
-
function spawnSafe(command, args, options) {
|
|
2700
|
+
function spawnSafe(command$1, args, options) {
|
|
2595
2701
|
try {
|
|
2596
2702
|
return {
|
|
2597
2703
|
ok: true,
|
|
2598
|
-
child: crossSpawn(command, [...args], options)
|
|
2704
|
+
child: crossSpawn(command$1, [...args], options)
|
|
2599
2705
|
};
|
|
2600
2706
|
} catch (err) {
|
|
2601
2707
|
return {
|
|
@@ -2946,8 +3052,8 @@ function tokenizeCliCommand(input) {
|
|
|
2946
3052
|
* 1. JSON 数组:以 `[` 开头,如 `["npx", "@fission-ai/openspec"]`
|
|
2947
3053
|
* 2. shell-like 字符串:支持引号与基础转义
|
|
2948
3054
|
*/
|
|
2949
|
-
function parseCliCommand(command) {
|
|
2950
|
-
const trimmed = command.trim();
|
|
3055
|
+
function parseCliCommand(command$1) {
|
|
3056
|
+
const trimmed = command$1.trim();
|
|
2951
3057
|
if (trimmed.startsWith("[")) try {
|
|
2952
3058
|
const parsed = JSON.parse(trimmed);
|
|
2953
3059
|
if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) return parsed;
|
|
@@ -2974,10 +3080,10 @@ function commandToString(commandParts) {
|
|
|
2974
3080
|
};
|
|
2975
3081
|
return commandParts.map(formatToken).join(" ").trim();
|
|
2976
3082
|
}
|
|
2977
|
-
function isBareExecutableCommand(command) {
|
|
2978
|
-
if (!command) return false;
|
|
2979
|
-
if (command === "." || command === "..") return false;
|
|
2980
|
-
return !/[\\/]/.test(command);
|
|
3083
|
+
function isBareExecutableCommand(command$1) {
|
|
3084
|
+
if (!command$1) return false;
|
|
3085
|
+
if (command$1 === "." || command$1 === "..") return false;
|
|
3086
|
+
return !/[\\/]/.test(command$1);
|
|
2981
3087
|
}
|
|
2982
3088
|
function quotePosixShellArg(value) {
|
|
2983
3089
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
@@ -2999,11 +3105,11 @@ function pickWindowsExecutablePath(lines, pathExt) {
|
|
|
2999
3105
|
return extensions.some((ext) => lower.endsWith(ext));
|
|
3000
3106
|
}) ?? trimmed[0];
|
|
3001
3107
|
}
|
|
3002
|
-
async function resolveShellExecutablePath(command, cwd, env) {
|
|
3003
|
-
if (!isBareExecutableCommand(command)) return null;
|
|
3108
|
+
async function resolveShellExecutablePath(command$1, cwd, env) {
|
|
3109
|
+
if (!isBareExecutableCommand(command$1)) return null;
|
|
3004
3110
|
try {
|
|
3005
3111
|
if (process.platform === "win32") {
|
|
3006
|
-
const { stdout: stdout$1 } = await execFileAsync("where", [command], {
|
|
3112
|
+
const { stdout: stdout$1 } = await execFileAsync("where", [command$1], {
|
|
3007
3113
|
cwd,
|
|
3008
3114
|
env,
|
|
3009
3115
|
encoding: "utf8",
|
|
@@ -3011,7 +3117,7 @@ async function resolveShellExecutablePath(command, cwd, env) {
|
|
|
3011
3117
|
});
|
|
3012
3118
|
return pickWindowsExecutablePath(stdout$1.split(/\r?\n/), env.PATHEXT);
|
|
3013
3119
|
}
|
|
3014
|
-
const { stdout } = await execFileAsync(env.SHELL || process.env.SHELL || "/bin/sh", ["-lc", `command -v -- ${quotePosixShellArg(command)}`], {
|
|
3120
|
+
const { stdout } = await execFileAsync(env.SHELL || process.env.SHELL || "/bin/sh", ["-lc", `command -v -- ${quotePosixShellArg(command$1)}`], {
|
|
3015
3121
|
cwd,
|
|
3016
3122
|
env,
|
|
3017
3123
|
encoding: "utf8",
|
|
@@ -3025,10 +3131,10 @@ async function resolveShellExecutablePath(command, cwd, env) {
|
|
|
3025
3131
|
async function expandCliRunnerCandidates(candidates, cwd, env) {
|
|
3026
3132
|
const expanded = [];
|
|
3027
3133
|
for (const candidate of candidates) {
|
|
3028
|
-
const [command, ...rest] = candidate.commandParts;
|
|
3029
|
-
if ((candidate.id === "openspec" || candidate.id === "configured" && command.trim().toLowerCase() === "openspec") && command) {
|
|
3030
|
-
const shellResolved = await resolveShellExecutablePath(command, cwd, env);
|
|
3031
|
-
if (shellResolved && shellResolved !== command) expanded.push({
|
|
3134
|
+
const [command$1, ...rest] = candidate.commandParts;
|
|
3135
|
+
if ((candidate.id === "openspec" || candidate.id === "configured" && command$1.trim().toLowerCase() === "openspec") && command$1) {
|
|
3136
|
+
const shellResolved = await resolveShellExecutablePath(command$1, cwd, env);
|
|
3137
|
+
if (shellResolved && shellResolved !== command$1) expanded.push({
|
|
3032
3138
|
...candidate,
|
|
3033
3139
|
source: `${candidate.source} (shell)`,
|
|
3034
3140
|
commandParts: [shellResolved, ...rest]
|
|
@@ -3442,9 +3548,9 @@ function mergeNullablePatch$1(current, patch) {
|
|
|
3442
3548
|
}
|
|
3443
3549
|
function toPersistedConfig(config, options = {}) {
|
|
3444
3550
|
const persisted = {};
|
|
3445
|
-
const command = config.cli.command?.trim();
|
|
3551
|
+
const command$1 = config.cli.command?.trim();
|
|
3446
3552
|
const args = (config.cli.args ?? []).map((arg) => arg.trim()).filter(Boolean);
|
|
3447
|
-
const cliCommandParts = command ? [command, ...args] : void 0;
|
|
3553
|
+
const cliCommandParts = command$1 ? [command$1, ...args] : void 0;
|
|
3448
3554
|
if (cliCommandParts && !areStringArraysEqual(cliCommandParts, options.defaultCliCommandParts)) {
|
|
3449
3555
|
const persistedCommand = cliCommandParts[0];
|
|
3450
3556
|
persisted.cli = args.length > 0 ? {
|
|
@@ -3756,8 +3862,8 @@ var ConfigManager = class {
|
|
|
3756
3862
|
/**
|
|
3757
3863
|
* 设置 CLI 命令
|
|
3758
3864
|
*/
|
|
3759
|
-
async setCliCommand(command) {
|
|
3760
|
-
const trimmed = command.trim();
|
|
3865
|
+
async setCliCommand(command$1) {
|
|
3866
|
+
const trimmed = command$1.trim();
|
|
3761
3867
|
if (!trimmed) {
|
|
3762
3868
|
await this.writeConfig({ cli: {
|
|
3763
3869
|
command: null,
|
|
@@ -3787,10 +3893,10 @@ var ConfigManager = class {
|
|
|
3787
3893
|
} });
|
|
3788
3894
|
}
|
|
3789
3895
|
getConfiguredCommandParts(cli) {
|
|
3790
|
-
const command = cli.command?.trim();
|
|
3791
|
-
if (!command) return [];
|
|
3792
|
-
if (Array.isArray(cli.args) && cli.args.length > 0) return [command, ...cli.args];
|
|
3793
|
-
return parseCliCommand(command);
|
|
3896
|
+
const command$1 = cli.command?.trim();
|
|
3897
|
+
if (!command$1) return [];
|
|
3898
|
+
if (Array.isArray(cli.args) && cli.args.length > 0) return [command$1, ...cli.args];
|
|
3899
|
+
return parseCliCommand(command$1);
|
|
3794
3900
|
}
|
|
3795
3901
|
/**
|
|
3796
3902
|
* 设置主题
|
|
@@ -4418,9 +4524,9 @@ function isOpenSpecWorkerMessage(value) {
|
|
|
4418
4524
|
function cleanWorkerEnv(env) {
|
|
4419
4525
|
return Object.fromEntries(Object.entries(env).filter((entry) => entry[1] !== void 0));
|
|
4420
4526
|
}
|
|
4421
|
-
function isNodeExecutable(command) {
|
|
4422
|
-
const executable = basename(command).toLowerCase();
|
|
4423
|
-
return executable === "node" || executable === "node.exe" || resolve(command) === resolve(process.execPath);
|
|
4527
|
+
function isNodeExecutable(command$1) {
|
|
4528
|
+
const executable = basename(command$1).toLowerCase();
|
|
4529
|
+
return executable === "node" || executable === "node.exe" || resolve(command$1) === resolve(process.execPath);
|
|
4424
4530
|
}
|
|
4425
4531
|
function isMissingPathError(error) {
|
|
4426
4532
|
if (typeof error !== "object" || error === null || !("code" in error)) return false;
|
|
@@ -4448,16 +4554,16 @@ async function moduleFromBin(binPath) {
|
|
|
4448
4554
|
if (basename(physicalBin) !== "openspec.js" || basename(dirname$1(physicalBin)) !== "bin") return null;
|
|
4449
4555
|
return existingFile(join$1(dirname$1(dirname$1(physicalBin)), "dist", "cli", "index.js"));
|
|
4450
4556
|
}
|
|
4451
|
-
async function moduleFromVitePlusShim(command) {
|
|
4452
|
-
if (basename(command) !== "openspec" || basename(dirname$1(command)) !== "bin") return null;
|
|
4453
|
-
const vitePlusRoot = dirname$1(dirname$1(command));
|
|
4557
|
+
async function moduleFromVitePlusShim(command$1) {
|
|
4558
|
+
if (basename(command$1) !== "openspec" || basename(dirname$1(command$1)) !== "bin") return null;
|
|
4559
|
+
const vitePlusRoot = dirname$1(dirname$1(command$1));
|
|
4454
4560
|
if (basename(vitePlusRoot) !== ".vite-plus") return null;
|
|
4455
4561
|
return existingFile(join$1(vitePlusRoot, "packages", "@fission-ai", "openspec", "lib", "node_modules", "@fission-ai", "openspec", "dist", "cli", "index.js"));
|
|
4456
4562
|
}
|
|
4457
4563
|
async function resolveOpenSpecWorkerInvocation(fullCommand) {
|
|
4458
|
-
const [command, ...commandArgs] = fullCommand;
|
|
4459
|
-
if (!command) throw new Error("OpenSpec CLI command is empty.");
|
|
4460
|
-
if (isNodeExecutable(command)) {
|
|
4564
|
+
const [command$1, ...commandArgs] = fullCommand;
|
|
4565
|
+
if (!command$1) throw new Error("OpenSpec CLI command is empty.");
|
|
4566
|
+
if (isNodeExecutable(command$1)) {
|
|
4461
4567
|
const [binPath, ...args] = commandArgs;
|
|
4462
4568
|
if (!binPath) throw new Error("Node OpenSpec runner does not include its bin entry.");
|
|
4463
4569
|
const modulePath$1 = await moduleFromBin(binPath);
|
|
@@ -4467,8 +4573,8 @@ async function resolveOpenSpecWorkerInvocation(fullCommand) {
|
|
|
4467
4573
|
args
|
|
4468
4574
|
};
|
|
4469
4575
|
}
|
|
4470
|
-
const modulePath = await moduleFromBin(command) ?? await moduleFromVitePlusShim(resolve(command)) ?? await moduleFromVitePlusShim(command);
|
|
4471
|
-
if (!modulePath) throw new OpenSpecCliModuleNotFoundError(`Cannot resolve the OpenSpec CLI module from runner: ${command}`);
|
|
4576
|
+
const modulePath = await moduleFromBin(command$1) ?? await moduleFromVitePlusShim(resolve(command$1)) ?? await moduleFromVitePlusShim(command$1);
|
|
4577
|
+
if (!modulePath) throw new OpenSpecCliModuleNotFoundError(`Cannot resolve the OpenSpec CLI module from runner: ${command$1}`);
|
|
4472
4578
|
return {
|
|
4473
4579
|
modulePath,
|
|
4474
4580
|
args: commandArgs
|
|
@@ -4618,11 +4724,11 @@ function runOpenSpecCliWorker(options) {
|
|
|
4618
4724
|
//#endregion
|
|
4619
4725
|
//#region src/cli-executor.ts
|
|
4620
4726
|
/**
|
|
4621
|
-
* Orthogonal intents (updated 2026-
|
|
4727
|
+
* Orthogonal intents (updated 2026-08-02 Asia/Shanghai):
|
|
4622
4728
|
* 1. Execute buffered CLI work through process/Worker backends with runner recovery,
|
|
4623
4729
|
* observer-explicit OTel phase evidence, bounded probes, and owner-scoped disposal.
|
|
4624
4730
|
* 2. Own streaming CLI processes through cancellation request, escalation, and confirmed settlement.
|
|
4625
|
-
* 3. Retain
|
|
4731
|
+
* 3. Retain lifecycle helpers and add the fixed-path, tools-none project bootstrap stream.
|
|
4626
4732
|
* 4. Expose the physically separated OpenSpec 1.6 typed command facade.
|
|
4627
4733
|
* 5. Clear the Core-owned direct-child slot independently from stream settlement, and keep
|
|
4628
4734
|
* response-Span delivery physically separate from late child-process settlement evidence.
|
|
@@ -4637,16 +4743,21 @@ function runOpenSpecCliWorker(options) {
|
|
|
4637
4743
|
* Original request (2026-07-31): "这些命令的执行,时间绝对不是七八秒那么久...请看一下代码,看能不能让trace更精确"
|
|
4638
4744
|
* Original request (2026-07-31): "终端大量报错,比如: Cannot execute the operation on ended Span"
|
|
4639
4745
|
* Original request (2026-07-31): "在主线程,通过 OPENSPEC_SPAWN_MODE=process|worker 来进行区分两种模式。"
|
|
4746
|
+
* Original request (2026-08-02): initialize the Launch Project with `openspec init <path> --tools=none`.
|
|
4747
|
+
* Review correction (2026-08-02): streamed command evidence must preserve argv boundaries.
|
|
4640
4748
|
*/
|
|
4641
4749
|
/** Failure raised when even forced termination cannot confirm child-process close. */
|
|
4642
4750
|
var CliStreamTerminationError = class extends Error {
|
|
4643
|
-
constructor(command) {
|
|
4644
|
-
super(`CLI stream did not close after forced termination: ${command}`);
|
|
4751
|
+
constructor(command$1) {
|
|
4752
|
+
super(`CLI stream did not close after forced termination: ${command$1}`);
|
|
4645
4753
|
this.name = "CliStreamTerminationError";
|
|
4646
4754
|
}
|
|
4647
4755
|
};
|
|
4648
4756
|
const STREAM_TERMINATION_GRACE_MS = 1e3;
|
|
4649
4757
|
const STREAM_FORCE_CLOSE_TIMEOUT_MS = 1e3;
|
|
4758
|
+
function formatCommandEvidence(argv) {
|
|
4759
|
+
return JSON.stringify(argv);
|
|
4760
|
+
}
|
|
4650
4761
|
const CLI_PHASE_EVENT_SUFFIXES = {
|
|
4651
4762
|
"spawn-called": "spawn.called",
|
|
4652
4763
|
"spawn-returned": "spawn.returned",
|
|
@@ -4677,10 +4788,10 @@ function phaseEventAttributes(event, spawnCalledAt, attempt) {
|
|
|
4677
4788
|
function setObservedDuration(span, key, base, observedAt) {
|
|
4678
4789
|
if (observedAt > 0) span.setAttribute(key, roundedMs(observedAt - base));
|
|
4679
4790
|
}
|
|
4680
|
-
function executableRealpath(command) {
|
|
4681
|
-
if (!isAbsolute(command)) return null;
|
|
4791
|
+
function executableRealpath(command$1) {
|
|
4792
|
+
if (!isAbsolute(command$1)) return null;
|
|
4682
4793
|
try {
|
|
4683
|
-
return realpathSync.native(command);
|
|
4794
|
+
return realpathSync.native(command$1);
|
|
4684
4795
|
} catch {
|
|
4685
4796
|
return null;
|
|
4686
4797
|
}
|
|
@@ -4872,7 +4983,7 @@ var CliExecutor = class {
|
|
|
4872
4983
|
}
|
|
4873
4984
|
};
|
|
4874
4985
|
const cliEnv = createCleanCliEnv();
|
|
4875
|
-
const command = spawnMode === "worker" && workerInvocation ? runOpenSpecCliWorker({
|
|
4986
|
+
const command$1 = spawnMode === "worker" && workerInvocation ? runOpenSpecCliWorker({
|
|
4876
4987
|
cwd: this.projectDir,
|
|
4877
4988
|
env: cliEnv,
|
|
4878
4989
|
signal: this.bufferedAbortController.signal,
|
|
@@ -4892,9 +5003,9 @@ var CliExecutor = class {
|
|
|
4892
5003
|
eagerResolveJson: isJsonCommand,
|
|
4893
5004
|
onPhase: observePhase
|
|
4894
5005
|
});
|
|
4895
|
-
this.activeBufferedCommands.add(command);
|
|
4896
|
-
const result = await command.finally(() => {
|
|
4897
|
-
this.activeBufferedCommands.delete(command);
|
|
5006
|
+
this.activeBufferedCommands.add(command$1);
|
|
5007
|
+
const result = await command$1.finally(() => {
|
|
5008
|
+
this.activeBufferedCommands.delete(command$1);
|
|
4898
5009
|
admission.release();
|
|
4899
5010
|
});
|
|
4900
5011
|
if (result.spawnError) return {
|
|
@@ -5241,7 +5352,7 @@ var CliExecutor = class {
|
|
|
5241
5352
|
return;
|
|
5242
5353
|
}
|
|
5243
5354
|
if (cancelRequested || settled) return;
|
|
5244
|
-
activeCommand = fullCommand
|
|
5355
|
+
activeCommand = formatCommandEvidence(fullCommand);
|
|
5245
5356
|
onEvent({
|
|
5246
5357
|
type: "command",
|
|
5247
5358
|
data: activeCommand
|
|
@@ -5352,6 +5463,14 @@ var CliExecutor = class {
|
|
|
5352
5463
|
if (options.force) args.push("--force");
|
|
5353
5464
|
return this.executeStream(args, onEvent);
|
|
5354
5465
|
}
|
|
5466
|
+
/** Stream the fixed project bootstrap command without installing Agent integrations. */
|
|
5467
|
+
initProjectStream(projectPath, onEvent) {
|
|
5468
|
+
return this.executeStream([
|
|
5469
|
+
"init",
|
|
5470
|
+
projectPath,
|
|
5471
|
+
"--tools=none"
|
|
5472
|
+
], onEvent);
|
|
5473
|
+
}
|
|
5355
5474
|
/**
|
|
5356
5475
|
* 流式执行 openspec archive
|
|
5357
5476
|
*/
|
|
@@ -5372,8 +5491,8 @@ var CliExecutor = class {
|
|
|
5372
5491
|
* 字面量 `openspec` 会自动通过已解析的 CLI runner 执行,
|
|
5373
5492
|
* 其它命令保持原始 spawn 行为。
|
|
5374
5493
|
*/
|
|
5375
|
-
executeCommandStream(command, onEvent) {
|
|
5376
|
-
const [cmd, ...cmdArgs] = command;
|
|
5494
|
+
executeCommandStream(command$1, onEvent) {
|
|
5495
|
+
const [cmd, ...cmdArgs] = command$1;
|
|
5377
5496
|
if (cmd === "openspec") return this.executeStream([...cmdArgs], onEvent);
|
|
5378
5497
|
return this.createStreamHandle(() => [cmd, ...cmdArgs], onEvent);
|
|
5379
5498
|
}
|
|
@@ -5784,146 +5903,241 @@ var RuntimeRootInvalidationRegistry = class {
|
|
|
5784
5903
|
};
|
|
5785
5904
|
|
|
5786
5905
|
//#endregion
|
|
5787
|
-
//#region src/
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5906
|
+
//#region src/agent-delivery-registry.ts
|
|
5907
|
+
const CODEX_MANAGED_PROMPTS = {
|
|
5908
|
+
"opsx-propose.md": ["propose"],
|
|
5909
|
+
"opsx-explore.md": ["explore"],
|
|
5910
|
+
"opsx-new.md": ["new"],
|
|
5911
|
+
"opsx-continue.md": ["continue"],
|
|
5912
|
+
"opsx-apply.md": ["apply"],
|
|
5913
|
+
"opsx-update.md": ["update"],
|
|
5914
|
+
"opsx-ff.md": ["ff"],
|
|
5915
|
+
"opsx-sync.md": ["sync"],
|
|
5916
|
+
"opsx-archive.md": ["archive"],
|
|
5917
|
+
"opsx-bulk-archive.md": ["bulk-archive"],
|
|
5918
|
+
"opsx-verify.md": ["verify"],
|
|
5919
|
+
"opsx-onboard.md": ["onboard"]
|
|
5920
|
+
};
|
|
5921
|
+
function command(pathTemplate, content, options = {}) {
|
|
5922
|
+
const fileName = pathTemplate.split("/").at(-1) ?? pathTemplate;
|
|
5923
|
+
return {
|
|
5924
|
+
scope: "project",
|
|
5925
|
+
format: content.kind,
|
|
5926
|
+
content,
|
|
5927
|
+
pathTemplate,
|
|
5928
|
+
legacyPathTemplates: options.legacyPathTemplates,
|
|
5929
|
+
invocation: {
|
|
5930
|
+
style: fileName.startsWith("opsx-") ? "flat" : "namespaced",
|
|
5931
|
+
prefix: options.invocationPrefix ?? "/"
|
|
5932
|
+
}
|
|
5933
|
+
};
|
|
5934
|
+
}
|
|
5935
|
+
const yamlMarkdown = (...fields) => ({
|
|
5936
|
+
kind: "markdown",
|
|
5937
|
+
frontmatter: {
|
|
5938
|
+
kind: "yaml",
|
|
5939
|
+
fields
|
|
5940
|
+
},
|
|
5941
|
+
bodyLayout: "direct"
|
|
5942
|
+
});
|
|
5943
|
+
const headingMarkdown = {
|
|
5944
|
+
kind: "markdown",
|
|
5945
|
+
frontmatter: { kind: "none" },
|
|
5946
|
+
bodyLayout: "headings"
|
|
5947
|
+
};
|
|
5948
|
+
const plainMarkdown = {
|
|
5949
|
+
kind: "markdown",
|
|
5950
|
+
frontmatter: { kind: "none" },
|
|
5951
|
+
bodyLayout: "direct"
|
|
5952
|
+
};
|
|
5953
|
+
const tomlCommand = {
|
|
5954
|
+
kind: "toml",
|
|
5955
|
+
fields: ["description", "prompt"]
|
|
5956
|
+
};
|
|
5957
|
+
const projectCleanup = (...patterns) => ({
|
|
5958
|
+
kind: "project-patterns",
|
|
5959
|
+
patterns
|
|
5960
|
+
});
|
|
5961
|
+
/** Complete OpenSpec 1.7 Agent delivery registry in official order. */
|
|
5962
|
+
const AGENT_DELIVERY_REGISTRY = [
|
|
5823
5963
|
{
|
|
5824
5964
|
name: "Amazon Q Developer",
|
|
5825
5965
|
value: "amazon-q",
|
|
5826
5966
|
available: true,
|
|
5827
5967
|
successLabel: "Amazon Q Developer",
|
|
5828
|
-
skillsDir: ".amazonq"
|
|
5968
|
+
skillsDir: ".amazonq",
|
|
5969
|
+
capability: "adapter-backed",
|
|
5970
|
+
command: command(".amazonq/prompts/opsx-{workflow}.md", yamlMarkdown("description"), { invocationPrefix: "@" }),
|
|
5971
|
+
cleanup: projectCleanup(".amazonq/prompts/openspec-*.md")
|
|
5829
5972
|
},
|
|
5830
5973
|
{
|
|
5831
5974
|
name: "Antigravity",
|
|
5832
5975
|
value: "antigravity",
|
|
5833
5976
|
available: true,
|
|
5834
5977
|
successLabel: "Antigravity",
|
|
5835
|
-
skillsDir: ".agent"
|
|
5978
|
+
skillsDir: ".agent",
|
|
5979
|
+
capability: "adapter-backed",
|
|
5980
|
+
command: command(".agent/workflows/opsx-{workflow}.md", yamlMarkdown("description")),
|
|
5981
|
+
cleanup: projectCleanup(".agent/workflows/openspec-*.md")
|
|
5836
5982
|
},
|
|
5837
5983
|
{
|
|
5838
5984
|
name: "Auggie (Augment CLI)",
|
|
5839
5985
|
value: "auggie",
|
|
5840
5986
|
available: true,
|
|
5841
5987
|
successLabel: "Auggie",
|
|
5842
|
-
skillsDir: ".augment"
|
|
5988
|
+
skillsDir: ".augment",
|
|
5989
|
+
capability: "adapter-backed",
|
|
5990
|
+
command: command(".augment/commands/opsx-{workflow}.md", yamlMarkdown("description", "argument-hint")),
|
|
5991
|
+
cleanup: projectCleanup(".augment/commands/openspec-*.md")
|
|
5843
5992
|
},
|
|
5844
5993
|
{
|
|
5845
5994
|
name: "Bob Shell",
|
|
5846
5995
|
value: "bob",
|
|
5847
5996
|
available: true,
|
|
5848
5997
|
successLabel: "Bob Shell",
|
|
5849
|
-
skillsDir: ".bob"
|
|
5998
|
+
skillsDir: ".bob",
|
|
5999
|
+
capability: "adapter-backed",
|
|
6000
|
+
command: command(".bob/commands/opsx-{workflow}.md", yamlMarkdown("description", "argument-hint"))
|
|
5850
6001
|
},
|
|
5851
6002
|
{
|
|
5852
6003
|
name: "Claude Code",
|
|
5853
6004
|
value: "claude",
|
|
5854
6005
|
available: true,
|
|
5855
6006
|
successLabel: "Claude Code",
|
|
5856
|
-
skillsDir: ".claude"
|
|
6007
|
+
skillsDir: ".claude",
|
|
6008
|
+
capability: "adapter-backed",
|
|
6009
|
+
command: command(".claude/commands/opsx/{workflow}.md", yamlMarkdown("name", "description", "allowed-tools", "category", "tags")),
|
|
6010
|
+
cleanup: projectCleanup(".claude/commands/openspec")
|
|
5857
6011
|
},
|
|
5858
6012
|
{
|
|
5859
6013
|
name: "Cline",
|
|
5860
6014
|
value: "cline",
|
|
5861
6015
|
available: true,
|
|
5862
6016
|
successLabel: "Cline",
|
|
5863
|
-
skillsDir: ".cline"
|
|
6017
|
+
skillsDir: ".cline",
|
|
6018
|
+
capability: "adapter-backed",
|
|
6019
|
+
command: command(".clinerules/workflows/opsx-{workflow}.md", headingMarkdown),
|
|
6020
|
+
cleanup: projectCleanup(".clinerules/workflows/openspec-*.md")
|
|
6021
|
+
},
|
|
6022
|
+
{
|
|
6023
|
+
name: "CodeArts",
|
|
6024
|
+
value: "codeartsagent",
|
|
6025
|
+
available: true,
|
|
6026
|
+
successLabel: "CodeArts",
|
|
6027
|
+
skillsDir: ".codeartsdoer",
|
|
6028
|
+
capability: "none",
|
|
6029
|
+
command: null
|
|
5864
6030
|
},
|
|
5865
6031
|
{
|
|
5866
6032
|
name: "Codex",
|
|
5867
6033
|
value: "codex",
|
|
5868
6034
|
available: true,
|
|
5869
6035
|
successLabel: "Codex",
|
|
5870
|
-
skillsDir: ".codex"
|
|
6036
|
+
skillsDir: ".codex",
|
|
6037
|
+
capability: "skills-invocable",
|
|
6038
|
+
command: null,
|
|
6039
|
+
cleanup: {
|
|
6040
|
+
kind: "managed-global-prompts",
|
|
6041
|
+
projectPatterns: [".codex/prompts/openspec-*.md"],
|
|
6042
|
+
managedFiles: CODEX_MANAGED_PROMPTS,
|
|
6043
|
+
replacementLabel: "Codex skills"
|
|
6044
|
+
}
|
|
6045
|
+
},
|
|
6046
|
+
{
|
|
6047
|
+
name: "Devin Desktop (formerly Windsurf)",
|
|
6048
|
+
value: "devin",
|
|
6049
|
+
available: true,
|
|
6050
|
+
successLabel: "Devin Desktop",
|
|
6051
|
+
skillsDir: ".devin",
|
|
6052
|
+
detectionPaths: [".devin", ".windsurf"],
|
|
6053
|
+
capability: "adapter-backed",
|
|
6054
|
+
command: command(".devin/workflows/opsx-{workflow}.md", yamlMarkdown("name", "description", "category", "tags")),
|
|
6055
|
+
aliases: ["windsurf"],
|
|
6056
|
+
cleanup: projectCleanup(".windsurf/workflows/openspec-*.md"),
|
|
6057
|
+
migrations: [{
|
|
6058
|
+
from: ".windsurf",
|
|
6059
|
+
to: ".devin",
|
|
6060
|
+
needsConsent: true
|
|
6061
|
+
}]
|
|
5871
6062
|
},
|
|
5872
6063
|
{
|
|
5873
6064
|
name: "ForgeCode",
|
|
5874
6065
|
value: "forgecode",
|
|
5875
6066
|
available: true,
|
|
5876
6067
|
successLabel: "ForgeCode",
|
|
5877
|
-
skillsDir: ".forge"
|
|
6068
|
+
skillsDir: ".forge",
|
|
6069
|
+
capability: "none",
|
|
6070
|
+
command: null
|
|
5878
6071
|
},
|
|
5879
6072
|
{
|
|
5880
6073
|
name: "CodeBuddy Code (CLI)",
|
|
5881
6074
|
value: "codebuddy",
|
|
5882
6075
|
available: true,
|
|
5883
6076
|
successLabel: "CodeBuddy Code",
|
|
5884
|
-
skillsDir: ".codebuddy"
|
|
6077
|
+
skillsDir: ".codebuddy",
|
|
6078
|
+
capability: "adapter-backed",
|
|
6079
|
+
command: command(".codebuddy/commands/opsx/{workflow}.md", yamlMarkdown("name", "description", "argument-hint")),
|
|
6080
|
+
cleanup: projectCleanup(".codebuddy/commands/openspec")
|
|
5885
6081
|
},
|
|
5886
6082
|
{
|
|
5887
6083
|
name: "Continue",
|
|
5888
6084
|
value: "continue",
|
|
5889
6085
|
available: true,
|
|
5890
6086
|
successLabel: "Continue (VS Code / JetBrains / Cli)",
|
|
5891
|
-
skillsDir: ".continue"
|
|
6087
|
+
skillsDir: ".continue",
|
|
6088
|
+
capability: "adapter-backed",
|
|
6089
|
+
command: command(".continue/prompts/opsx-{workflow}.prompt", yamlMarkdown("name", "description", "invokable")),
|
|
6090
|
+
cleanup: projectCleanup(".continue/prompts/openspec-*.prompt")
|
|
5892
6091
|
},
|
|
5893
6092
|
{
|
|
5894
6093
|
name: "CoStrict",
|
|
5895
6094
|
value: "costrict",
|
|
5896
6095
|
available: true,
|
|
5897
6096
|
successLabel: "CoStrict",
|
|
5898
|
-
skillsDir: ".cospec"
|
|
6097
|
+
skillsDir: ".cospec",
|
|
6098
|
+
capability: "adapter-backed",
|
|
6099
|
+
command: command(".cospec/openspec/commands/opsx-{workflow}.md", yamlMarkdown("description", "argument-hint")),
|
|
6100
|
+
cleanup: projectCleanup(".cospec/openspec/commands")
|
|
5899
6101
|
},
|
|
5900
6102
|
{
|
|
5901
6103
|
name: "Crush",
|
|
5902
6104
|
value: "crush",
|
|
5903
6105
|
available: true,
|
|
5904
6106
|
successLabel: "Crush",
|
|
5905
|
-
skillsDir: ".crush"
|
|
6107
|
+
skillsDir: ".crush",
|
|
6108
|
+
capability: "adapter-backed",
|
|
6109
|
+
command: command(".crush/commands/opsx/{workflow}.md", yamlMarkdown("name", "description", "category", "tags")),
|
|
6110
|
+
cleanup: projectCleanup(".crush/commands/openspec")
|
|
5906
6111
|
},
|
|
5907
6112
|
{
|
|
5908
6113
|
name: "Cursor",
|
|
5909
6114
|
value: "cursor",
|
|
5910
6115
|
available: true,
|
|
5911
6116
|
successLabel: "Cursor",
|
|
5912
|
-
skillsDir: ".cursor"
|
|
6117
|
+
skillsDir: ".cursor",
|
|
6118
|
+
capability: "adapter-backed",
|
|
6119
|
+
command: command(".cursor/commands/opsx-{workflow}.md", yamlMarkdown("name", "id", "category", "description")),
|
|
6120
|
+
cleanup: projectCleanup(".cursor/commands/openspec-*.md")
|
|
5913
6121
|
},
|
|
5914
6122
|
{
|
|
5915
6123
|
name: "Factory Droid",
|
|
5916
6124
|
value: "factory",
|
|
5917
6125
|
available: true,
|
|
5918
6126
|
successLabel: "Factory Droid",
|
|
5919
|
-
skillsDir: ".factory"
|
|
6127
|
+
skillsDir: ".factory",
|
|
6128
|
+
capability: "adapter-backed",
|
|
6129
|
+
command: command(".factory/commands/opsx-{workflow}.md", yamlMarkdown("description", "argument-hint")),
|
|
6130
|
+
cleanup: projectCleanup(".factory/commands/openspec-*.md")
|
|
5920
6131
|
},
|
|
5921
6132
|
{
|
|
5922
6133
|
name: "Gemini CLI",
|
|
5923
6134
|
value: "gemini",
|
|
5924
6135
|
available: true,
|
|
5925
6136
|
successLabel: "Gemini CLI",
|
|
5926
|
-
skillsDir: ".gemini"
|
|
6137
|
+
skillsDir: ".gemini",
|
|
6138
|
+
capability: "adapter-backed",
|
|
6139
|
+
command: command(".gemini/commands/opsx/{workflow}.toml", tomlCommand),
|
|
6140
|
+
cleanup: projectCleanup(".gemini/commands/openspec")
|
|
5927
6141
|
},
|
|
5928
6142
|
{
|
|
5929
6143
|
name: "GitHub Copilot",
|
|
@@ -5939,164 +6153,254 @@ const AI_TOOLS = [
|
|
|
5939
6153
|
".github/agents",
|
|
5940
6154
|
".github/skills",
|
|
5941
6155
|
".github/.mcp.json"
|
|
5942
|
-
]
|
|
6156
|
+
],
|
|
6157
|
+
capability: "adapter-backed",
|
|
6158
|
+
command: command(".github/prompts/opsx-{workflow}.prompt.md", yamlMarkdown("description")),
|
|
6159
|
+
cleanup: projectCleanup(".github/prompts/openspec-*.prompt.md")
|
|
6160
|
+
},
|
|
6161
|
+
{
|
|
6162
|
+
name: "Hermes Agent",
|
|
6163
|
+
value: "hermes",
|
|
6164
|
+
available: true,
|
|
6165
|
+
successLabel: "Hermes Agent",
|
|
6166
|
+
skillsDir: ".hermes",
|
|
6167
|
+
detectionPaths: [
|
|
6168
|
+
".hermes",
|
|
6169
|
+
"HERMES.md",
|
|
6170
|
+
".hermes.md"
|
|
6171
|
+
],
|
|
6172
|
+
setupNote: "Hermes only loads skills from ~/.hermes/skills by default. Add this project's .hermes/skills directory to skills.external_dirs in ~/.hermes/config.yaml so Hermes picks up the generated OpenSpec skills.",
|
|
6173
|
+
capability: "none",
|
|
6174
|
+
command: null
|
|
5943
6175
|
},
|
|
5944
6176
|
{
|
|
5945
6177
|
name: "iFlow",
|
|
5946
6178
|
value: "iflow",
|
|
5947
6179
|
available: true,
|
|
5948
6180
|
successLabel: "iFlow",
|
|
5949
|
-
skillsDir: ".iflow"
|
|
6181
|
+
skillsDir: ".iflow",
|
|
6182
|
+
capability: "adapter-backed",
|
|
6183
|
+
command: command(".iflow/commands/opsx-{workflow}.md", yamlMarkdown("name", "id", "category", "description")),
|
|
6184
|
+
cleanup: projectCleanup(".iflow/commands/openspec-*.md")
|
|
5950
6185
|
},
|
|
5951
6186
|
{
|
|
5952
6187
|
name: "Junie",
|
|
5953
6188
|
value: "junie",
|
|
5954
6189
|
available: true,
|
|
5955
6190
|
successLabel: "Junie",
|
|
5956
|
-
skillsDir: ".junie"
|
|
6191
|
+
skillsDir: ".junie",
|
|
6192
|
+
capability: "adapter-backed",
|
|
6193
|
+
command: command(".junie/commands/opsx-{workflow}.md", yamlMarkdown("description")),
|
|
6194
|
+
cleanup: projectCleanup(".junie/commands/opsx-*.md", ".junie/commands/openspec-*.md")
|
|
5957
6195
|
},
|
|
5958
6196
|
{
|
|
5959
6197
|
name: "Kilo Code",
|
|
5960
6198
|
value: "kilocode",
|
|
5961
6199
|
available: true,
|
|
5962
6200
|
successLabel: "Kilo Code",
|
|
5963
|
-
skillsDir: ".kilocode"
|
|
6201
|
+
skillsDir: ".kilocode",
|
|
6202
|
+
capability: "adapter-backed",
|
|
6203
|
+
command: command(".kilocode/workflows/opsx-{workflow}.md", plainMarkdown),
|
|
6204
|
+
cleanup: projectCleanup(".kilocode/workflows/openspec-*.md")
|
|
5964
6205
|
},
|
|
5965
6206
|
{
|
|
5966
|
-
name: "Kimi
|
|
6207
|
+
name: "Kimi Code",
|
|
5967
6208
|
value: "kimi",
|
|
5968
6209
|
available: true,
|
|
5969
|
-
successLabel: "Kimi
|
|
5970
|
-
skillsDir: ".kimi"
|
|
6210
|
+
successLabel: "Kimi Code",
|
|
6211
|
+
skillsDir: ".kimi-code",
|
|
6212
|
+
detectionPaths: [".kimi-code", ".kimi"],
|
|
6213
|
+
capability: "none",
|
|
6214
|
+
command: null,
|
|
6215
|
+
migrations: [{
|
|
6216
|
+
from: ".kimi",
|
|
6217
|
+
to: ".kimi-code",
|
|
6218
|
+
needsConsent: false
|
|
6219
|
+
}]
|
|
5971
6220
|
},
|
|
5972
6221
|
{
|
|
5973
6222
|
name: "Kiro",
|
|
5974
6223
|
value: "kiro",
|
|
5975
6224
|
available: true,
|
|
5976
6225
|
successLabel: "Kiro",
|
|
5977
|
-
skillsDir: ".kiro"
|
|
6226
|
+
skillsDir: ".kiro",
|
|
6227
|
+
capability: "adapter-backed",
|
|
6228
|
+
command: command(".kiro/prompts/opsx-{workflow}.prompt.md", yamlMarkdown("description")),
|
|
6229
|
+
cleanup: projectCleanup(".kiro/prompts/openspec-*.prompt.md")
|
|
5978
6230
|
},
|
|
5979
6231
|
{
|
|
5980
6232
|
name: "Lingma",
|
|
5981
6233
|
value: "lingma",
|
|
5982
6234
|
available: true,
|
|
5983
6235
|
successLabel: "Lingma",
|
|
5984
|
-
skillsDir: ".lingma"
|
|
6236
|
+
skillsDir: ".lingma",
|
|
6237
|
+
capability: "adapter-backed",
|
|
6238
|
+
command: command(".lingma/commands/opsx/{workflow}.md", yamlMarkdown("name", "description", "category", "tags")),
|
|
6239
|
+
cleanup: projectCleanup(".lingma/commands/openspec")
|
|
5985
6240
|
},
|
|
5986
6241
|
{
|
|
5987
6242
|
name: "Mistral Vibe",
|
|
5988
6243
|
value: "vibe",
|
|
5989
6244
|
available: true,
|
|
5990
6245
|
successLabel: "Mistral Vibe",
|
|
5991
|
-
skillsDir: ".vibe"
|
|
6246
|
+
skillsDir: ".vibe",
|
|
6247
|
+
capability: "none",
|
|
6248
|
+
command: null
|
|
5992
6249
|
},
|
|
5993
6250
|
{
|
|
5994
6251
|
name: "Oh My Pi",
|
|
5995
6252
|
value: "oh-my-pi",
|
|
5996
6253
|
available: true,
|
|
5997
6254
|
successLabel: "Oh My Pi",
|
|
5998
|
-
skillsDir: ".omp"
|
|
6255
|
+
skillsDir: ".omp",
|
|
6256
|
+
capability: "adapter-backed",
|
|
6257
|
+
command: command(".omp/commands/opsx-{workflow}.md", yamlMarkdown("description"))
|
|
5999
6258
|
},
|
|
6000
6259
|
{
|
|
6001
6260
|
name: "OpenCode",
|
|
6002
6261
|
value: "opencode",
|
|
6003
6262
|
available: true,
|
|
6004
6263
|
successLabel: "OpenCode",
|
|
6005
|
-
skillsDir: ".opencode"
|
|
6264
|
+
skillsDir: ".opencode",
|
|
6265
|
+
capability: "adapter-backed",
|
|
6266
|
+
command: command(".opencode/commands/opsx-{workflow}.md", yamlMarkdown("description"), { legacyPathTemplates: [".opencode/command/opsx-{workflow}.md"] }),
|
|
6267
|
+
cleanup: projectCleanup(".opencode/command/opsx-*.md", ".opencode/command/openspec-*.md")
|
|
6006
6268
|
},
|
|
6007
6269
|
{
|
|
6008
6270
|
name: "Pi",
|
|
6009
6271
|
value: "pi",
|
|
6010
6272
|
available: true,
|
|
6011
6273
|
successLabel: "Pi",
|
|
6012
|
-
skillsDir: ".pi"
|
|
6274
|
+
skillsDir: ".pi",
|
|
6275
|
+
capability: "adapter-backed",
|
|
6276
|
+
command: command(".pi/prompts/opsx-{workflow}.md", yamlMarkdown("description"))
|
|
6013
6277
|
},
|
|
6014
6278
|
{
|
|
6015
6279
|
name: "Qoder",
|
|
6016
6280
|
value: "qoder",
|
|
6017
6281
|
available: true,
|
|
6018
6282
|
successLabel: "Qoder",
|
|
6019
|
-
skillsDir: ".qoder"
|
|
6283
|
+
skillsDir: ".qoder",
|
|
6284
|
+
capability: "adapter-backed",
|
|
6285
|
+
command: command(".qoder/commands/opsx/{workflow}.md", yamlMarkdown("name", "description", "category", "tags")),
|
|
6286
|
+
cleanup: projectCleanup(".qoder/commands/openspec")
|
|
6020
6287
|
},
|
|
6021
6288
|
{
|
|
6022
6289
|
name: "Qwen Code",
|
|
6023
6290
|
value: "qwen",
|
|
6024
6291
|
available: true,
|
|
6025
6292
|
successLabel: "Qwen Code",
|
|
6026
|
-
skillsDir: ".qwen"
|
|
6293
|
+
skillsDir: ".qwen",
|
|
6294
|
+
capability: "adapter-backed",
|
|
6295
|
+
command: command(".qwen/commands/opsx-{workflow}.md", yamlMarkdown("description")),
|
|
6296
|
+
cleanup: projectCleanup(".qwen/commands/opsx-*.toml", ".qwen/commands/openspec-*.toml")
|
|
6027
6297
|
},
|
|
6028
6298
|
{
|
|
6029
|
-
name: "
|
|
6299
|
+
name: "Zoo Code",
|
|
6030
6300
|
value: "roocode",
|
|
6031
6301
|
available: true,
|
|
6032
|
-
successLabel: "
|
|
6033
|
-
skillsDir: ".roo"
|
|
6302
|
+
successLabel: "Zoo Code",
|
|
6303
|
+
skillsDir: ".roo",
|
|
6304
|
+
capability: "adapter-backed",
|
|
6305
|
+
command: command(".roo/commands/opsx-{workflow}.md", headingMarkdown),
|
|
6306
|
+
cleanup: projectCleanup(".roo/commands/openspec-*.md")
|
|
6034
6307
|
},
|
|
6035
6308
|
{
|
|
6036
6309
|
name: "Trae",
|
|
6037
6310
|
value: "trae",
|
|
6038
6311
|
available: true,
|
|
6039
6312
|
successLabel: "Trae",
|
|
6040
|
-
skillsDir: ".trae"
|
|
6313
|
+
skillsDir: ".trae",
|
|
6314
|
+
capability: "adapter-backed",
|
|
6315
|
+
command: command(".trae/commands/opsx-{workflow}.md", yamlMarkdown("name", "description"))
|
|
6041
6316
|
},
|
|
6042
6317
|
{
|
|
6043
|
-
name: "
|
|
6044
|
-
value: "
|
|
6318
|
+
name: "ZCode",
|
|
6319
|
+
value: "zcode",
|
|
6045
6320
|
available: true,
|
|
6046
|
-
successLabel: "
|
|
6047
|
-
skillsDir: ".
|
|
6321
|
+
successLabel: "ZCode",
|
|
6322
|
+
skillsDir: ".zcode",
|
|
6323
|
+
capability: "adapter-backed",
|
|
6324
|
+
command: command(".zcode/commands/opsx/{workflow}.md", yamlMarkdown("name", "description", "category", "tags"))
|
|
6325
|
+
},
|
|
6326
|
+
{
|
|
6327
|
+
name: "AGENTS.md (works with Amp, VS Code, …)",
|
|
6328
|
+
value: "agents",
|
|
6329
|
+
available: false,
|
|
6330
|
+
successLabel: "your AGENTS.md-compatible assistant",
|
|
6331
|
+
skillsDir: null,
|
|
6332
|
+
capability: "none",
|
|
6333
|
+
command: null
|
|
6048
6334
|
}
|
|
6049
6335
|
];
|
|
6336
|
+
/** Backwards-compatible public name; the registry remains the single physical owner. */
|
|
6337
|
+
const AI_TOOLS = AGENT_DELIVERY_REGISTRY;
|
|
6338
|
+
/** Resolve retired ids to their current official registry entry id. */
|
|
6339
|
+
function resolveAgentToolId(toolId) {
|
|
6340
|
+
return AGENT_DELIVERY_REGISTRY.find((tool) => tool.aliases?.includes(toolId))?.value ?? toolId;
|
|
6341
|
+
}
|
|
6342
|
+
/** Resolve one command path template for an OPSX workflow. */
|
|
6343
|
+
function resolveAgentCommandPathTemplate(pathTemplate, workflow) {
|
|
6344
|
+
return pathTemplate.replace("{workflow}", workflow);
|
|
6345
|
+
}
|
|
6346
|
+
|
|
6347
|
+
//#endregion
|
|
6348
|
+
//#region src/tool-config.ts
|
|
6050
6349
|
/**
|
|
6051
|
-
*
|
|
6350
|
+
* Orthogonal intents (updated 2026-08-01 Asia/Shanghai):
|
|
6351
|
+
* 1. Expose the unified OpenSpec 1.7 Agent delivery registry through the established Tool APIs.
|
|
6352
|
+
* 2. Detect configured project-local Agent roots reactively without duplicating registry metadata.
|
|
6353
|
+
*
|
|
6354
|
+
* Original request (2026-08-01): adapt the complete OpenSpec 1.7 Agent delivery protocol for OpenSpecUI 7.
|
|
6052
6355
|
*/
|
|
6356
|
+
/** OpenSpec initialization generated skill directory names. */
|
|
6357
|
+
const SKILL_NAMES = [
|
|
6358
|
+
"openspec-explore",
|
|
6359
|
+
"openspec-new-change",
|
|
6360
|
+
"openspec-continue-change",
|
|
6361
|
+
"openspec-apply-change",
|
|
6362
|
+
"openspec-update-change",
|
|
6363
|
+
"openspec-ff-change",
|
|
6364
|
+
"openspec-sync-specs",
|
|
6365
|
+
"openspec-archive-change",
|
|
6366
|
+
"openspec-bulk-archive-change",
|
|
6367
|
+
"openspec-verify-change",
|
|
6368
|
+
"openspec-onboard",
|
|
6369
|
+
"openspec-propose"
|
|
6370
|
+
];
|
|
6371
|
+
/** Return registry entries available to OpenSpec init/update. */
|
|
6053
6372
|
function getAvailableTools() {
|
|
6054
6373
|
return AI_TOOLS.filter((tool) => tool.available);
|
|
6055
6374
|
}
|
|
6056
|
-
/**
|
|
6057
|
-
* 获取所有可用的工具 ID 列表(available: true)
|
|
6058
|
-
*/
|
|
6375
|
+
/** Return available official Tool ids. */
|
|
6059
6376
|
function getAvailableToolIds() {
|
|
6060
6377
|
return getAvailableTools().map((tool) => tool.value);
|
|
6061
6378
|
}
|
|
6062
|
-
/**
|
|
6063
|
-
* 获取所有工具
|
|
6064
|
-
*/
|
|
6379
|
+
/** Return the complete official registry, including unavailable pseudo-tools. */
|
|
6065
6380
|
function getAllTools() {
|
|
6066
6381
|
return AI_TOOLS;
|
|
6067
6382
|
}
|
|
6068
|
-
/**
|
|
6069
|
-
* 检测当前项目中已经存在的工具目录。
|
|
6070
|
-
*
|
|
6071
|
-
* 这里对齐 OpenSpec 官方 `getAvailableTools(projectPath)` 的语义:
|
|
6072
|
-
* 仅根据项目根目录下的工具目录是否存在来判断,不读取全局命令安装状态。
|
|
6073
|
-
*/
|
|
6383
|
+
/** Detect project-local Agent roots using the official OpenSpec detection paths. */
|
|
6074
6384
|
async function getDetectedProjectTools(projectDir) {
|
|
6075
6385
|
return (await Promise.all(AI_TOOLS.map(async (tool) => {
|
|
6076
6386
|
if (!tool.skillsDir) return null;
|
|
6077
|
-
|
|
6078
|
-
return (await
|
|
6387
|
+
if (tool.detectionPaths?.length) return (await Promise.all(tool.detectionPaths.map((detectionPath) => reactiveStat(join$1(projectDir, detectionPath))))).some((entry) => entry !== null) ? tool : null;
|
|
6388
|
+
return (await reactiveStat(join$1(projectDir, tool.skillsDir)))?.isDirectory === true ? tool : null;
|
|
6079
6389
|
}))).filter((tool) => tool !== null);
|
|
6080
6390
|
}
|
|
6081
|
-
/**
|
|
6082
|
-
* 获取所有工具 ID 列表
|
|
6083
|
-
*/
|
|
6391
|
+
/** Return every current official Tool id in registry order. */
|
|
6084
6392
|
function getAllToolIds() {
|
|
6085
6393
|
return AI_TOOLS.map((tool) => tool.value);
|
|
6086
6394
|
}
|
|
6087
|
-
/**
|
|
6088
|
-
* 根据工具 ID 获取工具配置
|
|
6089
|
-
*/
|
|
6395
|
+
/** Resolve one current or retired Tool id to its official registry entry. */
|
|
6090
6396
|
function getToolById(toolId) {
|
|
6091
|
-
|
|
6397
|
+
const resolvedToolId = resolveAgentToolId(toolId);
|
|
6398
|
+
return AI_TOOLS.find((tool) => tool.value === resolvedToolId);
|
|
6092
6399
|
}
|
|
6093
|
-
/** 状态缓存:projectDir -> ReactiveState */
|
|
6094
6400
|
const stateCache = /* @__PURE__ */ new Map();
|
|
6095
|
-
/** 监听器释放函数缓存 */
|
|
6096
6401
|
const releaseCache = /* @__PURE__ */ new Map();
|
|
6097
6402
|
function getSkillsDir(projectDir, tool) {
|
|
6098
|
-
|
|
6099
|
-
return join$1(projectDir, tool.skillsDir, "skills");
|
|
6403
|
+
return tool.skillsDir ? join$1(projectDir, tool.skillsDir, "skills") : null;
|
|
6100
6404
|
}
|
|
6101
6405
|
async function getSkillCount(projectDir, tool) {
|
|
6102
6406
|
const skillsDir = getSkillsDir(projectDir, tool);
|
|
@@ -6105,75 +6409,160 @@ async function getSkillCount(projectDir, tool) {
|
|
|
6105
6409
|
for (const skillName of SKILL_NAMES) if (await reactiveExists(join$1(skillsDir, skillName, "SKILL.md"))) count++;
|
|
6106
6410
|
return count;
|
|
6107
6411
|
}
|
|
6108
|
-
/**
|
|
6109
|
-
* 扫描已配置的工具(并行检查)
|
|
6110
|
-
*/
|
|
6111
6412
|
async function scanConfiguredTools(projectDir) {
|
|
6112
|
-
return (await Promise.all(AI_TOOLS.map(async (
|
|
6113
|
-
if (!
|
|
6114
|
-
return await getSkillCount(projectDir,
|
|
6115
|
-
}))).filter((
|
|
6413
|
+
return (await Promise.all(AI_TOOLS.map(async (tool) => {
|
|
6414
|
+
if (!tool.skillsDir) return null;
|
|
6415
|
+
return await getSkillCount(projectDir, tool) > 0 ? tool.value : null;
|
|
6416
|
+
}))).filter((toolId) => toolId !== null);
|
|
6116
6417
|
}
|
|
6117
|
-
/**
|
|
6118
|
-
* 获取需要监听的项目级目录列表
|
|
6119
|
-
*/
|
|
6120
6418
|
function getProjectWatchDirs(projectDir) {
|
|
6121
6419
|
const dirs = /* @__PURE__ */ new Set();
|
|
6122
|
-
for (const
|
|
6123
|
-
if (
|
|
6124
|
-
dirs.add(join$1(projectDir,
|
|
6420
|
+
for (const tool of AI_TOOLS) {
|
|
6421
|
+
if (tool.skillsDir) dirs.add(join$1(projectDir, tool.skillsDir));
|
|
6422
|
+
for (const migration of tool.migrations ?? []) dirs.add(join$1(projectDir, migration.from));
|
|
6125
6423
|
}
|
|
6126
|
-
return
|
|
6424
|
+
return [...dirs];
|
|
6127
6425
|
}
|
|
6128
|
-
/**
|
|
6129
|
-
* 检测项目中已配置的工具(响应式)
|
|
6130
|
-
*/
|
|
6426
|
+
/** Detect configured Agents through a retained reactive projection. */
|
|
6131
6427
|
async function getConfiguredTools(projectDir) {
|
|
6132
6428
|
const normalizedPath = resolve(projectDir);
|
|
6133
6429
|
const key = `tools:${normalizedPath}`;
|
|
6134
6430
|
let state = stateCache.get(key);
|
|
6135
6431
|
if (!state) {
|
|
6136
|
-
state = new ReactiveState(await scanConfiguredTools(normalizedPath), { equals: (
|
|
6432
|
+
state = new ReactiveState(await scanConfiguredTools(normalizedPath), { equals: (left, right) => left.length === right.length && left.every((value, index) => value === right[index]) });
|
|
6137
6433
|
stateCache.set(key, state);
|
|
6138
6434
|
const releases = [];
|
|
6139
|
-
const onUpdate = async () =>
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
const projectWatchDirs = getProjectWatchDirs(normalizedPath);
|
|
6144
|
-
for (const dir of projectWatchDirs) {
|
|
6145
|
-
const release = acquireWatcher(dir, onUpdate, { recursive: true });
|
|
6146
|
-
releases.push(release);
|
|
6147
|
-
}
|
|
6148
|
-
const rootRelease = acquireWatcher(normalizedPath, onUpdate, { recursive: false });
|
|
6149
|
-
releases.push(rootRelease);
|
|
6150
|
-
releaseCache.set(key, () => releases.forEach((r) => r()));
|
|
6435
|
+
const onUpdate = async () => state?.set(await scanConfiguredTools(normalizedPath));
|
|
6436
|
+
for (const dir of getProjectWatchDirs(normalizedPath)) releases.push(acquireWatcher(dir, onUpdate, { recursive: true }));
|
|
6437
|
+
releases.push(acquireWatcher(normalizedPath, onUpdate, { recursive: false }));
|
|
6438
|
+
releaseCache.set(key, () => releases.forEach((release) => release()));
|
|
6151
6439
|
}
|
|
6152
6440
|
return state.get();
|
|
6153
6441
|
}
|
|
6442
|
+
/** Check whether a current or retired Tool id resolves to configured skills. */
|
|
6443
|
+
async function isToolConfigured(projectDir, toolId) {
|
|
6444
|
+
return (await getConfiguredTools(projectDir)).includes(resolveAgentToolId(toolId));
|
|
6445
|
+
}
|
|
6446
|
+
|
|
6447
|
+
//#endregion
|
|
6448
|
+
//#region src/agent-delivery-policy.ts
|
|
6154
6449
|
/**
|
|
6155
|
-
*
|
|
6450
|
+
* Orthogonal intents (created 2026-08-01 Asia/Shanghai):
|
|
6451
|
+
* 1. Define the structured Agent profile, delivery, and workflow mutation contract.
|
|
6452
|
+
* 2. Normalize Core versus Custom workflow semantics exactly once.
|
|
6453
|
+
* 3. Preserve unknown environment-global JSON fields while updating official Agent policy keys.
|
|
6454
|
+
*
|
|
6455
|
+
* Original request (2026-08-01): keep raw environment config authoring while moving official Agent controls to Config.
|
|
6156
6456
|
*/
|
|
6157
|
-
|
|
6158
|
-
|
|
6457
|
+
const AgentDeliveryProfileSchema = z.enum(["core", "custom"]);
|
|
6458
|
+
const AgentDeliveryModeSchema = z.enum([
|
|
6459
|
+
"both",
|
|
6460
|
+
"skills",
|
|
6461
|
+
"commands"
|
|
6462
|
+
]);
|
|
6463
|
+
const AgentDeliveryWorkflowSchema = z.enum(OPSX_ALL_WORKFLOWS);
|
|
6464
|
+
const AgentDeliveryPolicyUpdateSchema = z.object({
|
|
6465
|
+
profile: AgentDeliveryProfileSchema,
|
|
6466
|
+
delivery: AgentDeliveryModeSchema,
|
|
6467
|
+
workflows: z.array(AgentDeliveryWorkflowSchema)
|
|
6468
|
+
}).superRefine((value, context$1) => {
|
|
6469
|
+
if (new Set(value.workflows).size !== value.workflows.length) context$1.addIssue({
|
|
6470
|
+
code: "custom",
|
|
6471
|
+
message: "Agent workflows must be unique."
|
|
6472
|
+
});
|
|
6473
|
+
});
|
|
6474
|
+
/** Normalize authored policy through official omitted-value defaults and Core workflow semantics. */
|
|
6475
|
+
function normalizeAgentDeliveryPolicy(input) {
|
|
6476
|
+
const profile = input.profile === "custom" ? "custom" : "core";
|
|
6477
|
+
return {
|
|
6478
|
+
profile,
|
|
6479
|
+
delivery: input.delivery === "skills" || input.delivery === "commands" ? input.delivery : "both",
|
|
6480
|
+
workflows: profile === "core" ? [...OPSX_CORE_PROFILE_WORKFLOWS] : OPSX_ALL_WORKFLOWS.filter((workflow) => input.workflows?.includes(workflow))
|
|
6481
|
+
};
|
|
6482
|
+
}
|
|
6483
|
+
/** Update only official Agent policy keys while retaining every team-authored extension field. */
|
|
6484
|
+
function applyAgentDeliveryPolicy(config, update) {
|
|
6485
|
+
const policy = normalizeAgentDeliveryPolicy(update);
|
|
6486
|
+
return {
|
|
6487
|
+
...config,
|
|
6488
|
+
profile: policy.profile,
|
|
6489
|
+
delivery: policy.delivery,
|
|
6490
|
+
workflows: policy.workflows
|
|
6491
|
+
};
|
|
6159
6492
|
}
|
|
6160
6493
|
|
|
6161
6494
|
//#endregion
|
|
6162
|
-
//#region src/
|
|
6495
|
+
//#region src/agent-command-content.ts
|
|
6163
6496
|
/**
|
|
6164
|
-
* Orthogonal intents (
|
|
6165
|
-
* 1.
|
|
6166
|
-
* 2.
|
|
6167
|
-
* 3.
|
|
6168
|
-
* 4. Bound reactive observation through existing parent inventories while preserving fresh one-shot reads.
|
|
6497
|
+
* Orthogonal intents (created 2026-08-01 Asia/Shanghai):
|
|
6498
|
+
* 1. Resolve the running OpenSpec CLI's private command-generation boundary without bundling copied prompts.
|
|
6499
|
+
* 2. Produce exact per-Agent, per-workflow command contents for physical fingerprint comparison.
|
|
6500
|
+
* 3. Fail closed when the configured runner has no importable OpenSpec module or compatible generator contract.
|
|
6169
6501
|
*
|
|
6170
|
-
* Original request (2026-
|
|
6171
|
-
* Remote CI fixed point (2026-07-28): Launch-local skill creation must converge when its tool root was absent at initial projection.
|
|
6502
|
+
* Original request (2026-08-01): adapt the complete OpenSpec 1.7 Agent delivery protocol for OpenSpecUI 7.
|
|
6172
6503
|
*/
|
|
6173
|
-
|
|
6174
|
-
function
|
|
6175
|
-
return
|
|
6504
|
+
const KNOWN_WORKFLOWS = new Set(OPSX_ALL_WORKFLOWS);
|
|
6505
|
+
function isRecord(value) {
|
|
6506
|
+
return typeof value === "object" && value !== null;
|
|
6507
|
+
}
|
|
6508
|
+
function isRuntimeSkillGenerationModule(value) {
|
|
6509
|
+
return isRecord(value) && typeof value.getCommandContents === "function";
|
|
6510
|
+
}
|
|
6511
|
+
function isRuntimeCommandAdapterRegistry(value) {
|
|
6512
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) return false;
|
|
6513
|
+
return "get" in value && typeof value.get === "function";
|
|
6514
|
+
}
|
|
6515
|
+
function isRuntimeCommandGenerationModule(value) {
|
|
6516
|
+
return isRecord(value) && isRuntimeCommandAdapterRegistry(value.CommandAdapterRegistry) && typeof value.generateCommands === "function";
|
|
6176
6517
|
}
|
|
6518
|
+
function isRuntimeCommandContent(value) {
|
|
6519
|
+
return isRecord(value) && typeof value.id === "string" && KNOWN_WORKFLOWS.has(value.id);
|
|
6520
|
+
}
|
|
6521
|
+
function isRuntimeGeneratedCommand(value) {
|
|
6522
|
+
return isRecord(value) && typeof value.fileContent === "string";
|
|
6523
|
+
}
|
|
6524
|
+
/**
|
|
6525
|
+
* Load exact command contents from the configured OpenSpec CLI.
|
|
6526
|
+
*
|
|
6527
|
+
* The private generator is intentionally treated as optional evidence. When the runner is not an
|
|
6528
|
+
* importable local OpenSpec module, callers receive `null` and commands-only installs cannot be
|
|
6529
|
+
* declared current from path existence alone.
|
|
6530
|
+
*/
|
|
6531
|
+
async function loadOpenSpecAgentCommandContents(cliCommand, workflows) {
|
|
6532
|
+
try {
|
|
6533
|
+
const cliModuleDir = dirname$1((await resolveOpenSpecWorkerInvocation(cliCommand)).modulePath);
|
|
6534
|
+
const [skillGenerationModule, commandGenerationModule] = await Promise.all([import(pathToFileURL(resolve(cliModuleDir, "../core/shared/skill-generation.js")).href), import(pathToFileURL(resolve(cliModuleDir, "../core/command-generation/index.js")).href)]);
|
|
6535
|
+
if (!isRuntimeSkillGenerationModule(skillGenerationModule) || !isRuntimeCommandGenerationModule(commandGenerationModule)) return null;
|
|
6536
|
+
const commandContents = skillGenerationModule.getCommandContents(workflows);
|
|
6537
|
+
if (!Array.isArray(commandContents) || !commandContents.every(isRuntimeCommandContent)) return null;
|
|
6538
|
+
const catalog = {};
|
|
6539
|
+
for (const tool of AGENT_DELIVERY_REGISTRY) {
|
|
6540
|
+
if (!tool.command) continue;
|
|
6541
|
+
const adapter = commandGenerationModule.CommandAdapterRegistry.get(tool.value);
|
|
6542
|
+
if (!adapter) return null;
|
|
6543
|
+
const generatedCommands = commandGenerationModule.generateCommands(commandContents, adapter);
|
|
6544
|
+
if (!Array.isArray(generatedCommands) || generatedCommands.length !== commandContents.length || !generatedCommands.every(isRuntimeGeneratedCommand)) return null;
|
|
6545
|
+
catalog[tool.value] = Object.fromEntries(commandContents.map((content, index) => [content.id, generatedCommands[index]?.fileContent]));
|
|
6546
|
+
}
|
|
6547
|
+
return catalog;
|
|
6548
|
+
} catch {
|
|
6549
|
+
return null;
|
|
6550
|
+
}
|
|
6551
|
+
}
|
|
6552
|
+
|
|
6553
|
+
//#endregion
|
|
6554
|
+
//#region src/tool-init-state.ts
|
|
6555
|
+
/**
|
|
6556
|
+
* Orthogonal intents (updated 2026-08-01 Asia/Shanghai):
|
|
6557
|
+
* 1. Project the unified OpenSpec 1.7 Agent registry into exact skill and command artifact state.
|
|
6558
|
+
* 2. Report partial, stale-version, cleanup-needed, migration-required, and unavailable states from physical evidence.
|
|
6559
|
+
* 3. Preserve bounded reactive directory observation and fresh one-shot cache invalidation.
|
|
6560
|
+
* 4. Expose Codex managed-global-prompt observation without treating those prompts as current commands.
|
|
6561
|
+
*
|
|
6562
|
+
* Original request (2026-08-01): adapt the complete OpenSpec 1.7 Agent delivery protocol for OpenSpecUI 7.
|
|
6563
|
+
*/
|
|
6564
|
+
/** Pinned source version used when a runtime CLI version is not supplied by the Server owner. */
|
|
6565
|
+
const PINNED_AGENT_GENERATOR_VERSION = "1.7.0";
|
|
6177
6566
|
const ALL_TOOL_WORKFLOWS = [...OPSX_ALL_WORKFLOWS];
|
|
6178
6567
|
function toKnownWorkflows(workflows) {
|
|
6179
6568
|
return workflows.filter((workflow) => workflow in OPSX_WORKFLOW_TO_SKILL_DIR);
|
|
@@ -6182,65 +6571,40 @@ function resolveCodexHome() {
|
|
|
6182
6571
|
const configuredHome = process.env.CODEX_HOME?.trim();
|
|
6183
6572
|
return resolve(configuredHome ? configuredHome : join$1(homedir(), ".codex"));
|
|
6184
6573
|
}
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
costrict: { primary: (projectDir, workflow) => resolve(projectDir, ".cospec", "openspec", "commands", `opsx-${workflow}.md`) },
|
|
6196
|
-
crush: { primary: (projectDir, workflow) => resolve(projectDir, ".crush", "commands", "opsx", `${workflow}.md`) },
|
|
6197
|
-
cursor: { primary: (projectDir, workflow) => resolve(projectDir, ".cursor", "commands", `opsx-${workflow}.md`) },
|
|
6198
|
-
factory: { primary: (projectDir, workflow) => resolve(projectDir, ".factory", "commands", `opsx-${workflow}.md`) },
|
|
6199
|
-
gemini: { primary: (projectDir, workflow) => resolve(projectDir, ".gemini", "commands", "opsx", `${workflow}.toml`) },
|
|
6200
|
-
"github-copilot": { primary: (projectDir, workflow) => resolve(projectDir, ".github", "prompts", `opsx-${workflow}.prompt.md`) },
|
|
6201
|
-
iflow: { primary: (projectDir, workflow) => resolve(projectDir, ".iflow", "commands", `opsx-${workflow}.md`) },
|
|
6202
|
-
junie: { primary: (projectDir, workflow) => resolve(projectDir, ".junie", "commands", `opsx-${workflow}.md`) },
|
|
6203
|
-
kilocode: { primary: (projectDir, workflow) => resolve(projectDir, ".kilocode", "workflows", `opsx-${workflow}.md`) },
|
|
6204
|
-
kiro: { primary: (projectDir, workflow) => resolve(projectDir, ".kiro", "prompts", `opsx-${workflow}.prompt.md`) },
|
|
6205
|
-
lingma: { primary: (projectDir, workflow) => resolve(projectDir, ".lingma", "commands", "opsx", `${workflow}.md`) },
|
|
6206
|
-
opencode: {
|
|
6207
|
-
primary: (projectDir, workflow) => resolve(projectDir, ".opencode", "commands", `opsx-${workflow}.md`),
|
|
6208
|
-
legacy: [(projectDir, workflow) => resolve(projectDir, ".opencode", "command", `opsx-${workflow}.md`)]
|
|
6209
|
-
},
|
|
6210
|
-
"oh-my-pi": { primary: (projectDir, workflow) => resolve(projectDir, ".omp", "commands", `opsx-${workflow}.md`) },
|
|
6211
|
-
pi: { primary: (projectDir, workflow) => resolve(projectDir, ".pi", "prompts", `opsx-${workflow}.md`) },
|
|
6212
|
-
qoder: { primary: (projectDir, workflow) => resolve(projectDir, ".qoder", "commands", "opsx", `${workflow}.md`) },
|
|
6213
|
-
qwen: { primary: (projectDir, workflow) => resolve(projectDir, ".qwen", "commands", `opsx-${workflow}.toml`) },
|
|
6214
|
-
roocode: { primary: (projectDir, workflow) => resolve(projectDir, ".roo", "commands", `opsx-${workflow}.md`) },
|
|
6215
|
-
trae: { primary: (projectDir, workflow) => resolve(projectDir, ".trae", "commands", `opsx-${workflow}.md`) },
|
|
6216
|
-
windsurf: { primary: (projectDir, workflow) => resolve(projectDir, ".windsurf", "workflows", `opsx-${workflow}.md`) }
|
|
6217
|
-
};
|
|
6218
|
-
function resolveToolCommandArtifact(projectDir, toolId, workflow) {
|
|
6219
|
-
const config = TOOL_COMMAND_PATHS[toolId];
|
|
6220
|
-
if (!config) return null;
|
|
6574
|
+
/** Return the external directory containing allowlisted managed legacy Codex prompts. */
|
|
6575
|
+
function getExternalCodexCommandObservationRoot() {
|
|
6576
|
+
return join$1(resolveCodexHome(), "prompts");
|
|
6577
|
+
}
|
|
6578
|
+
function resolveCommandArtifact(projectDir, tool, workflow, rootOverride) {
|
|
6579
|
+
if (!tool.command) return null;
|
|
6580
|
+
const rebase = (pathTemplate) => {
|
|
6581
|
+
if (!rootOverride || !tool.skillsDir || !pathTemplate.startsWith(`${tool.skillsDir}/`)) return pathTemplate;
|
|
6582
|
+
return `${rootOverride}${pathTemplate.slice(tool.skillsDir.length)}`;
|
|
6583
|
+
};
|
|
6221
6584
|
return {
|
|
6222
6585
|
workflow,
|
|
6223
|
-
path:
|
|
6224
|
-
legacyPaths:
|
|
6586
|
+
path: resolve(projectDir, resolveAgentCommandPathTemplate(rebase(tool.command.pathTemplate), workflow)),
|
|
6587
|
+
legacyPaths: tool.command.legacyPathTemplates?.map((pathTemplate) => resolve(projectDir, resolveAgentCommandPathTemplate(rebase(pathTemplate), workflow)))
|
|
6225
6588
|
};
|
|
6226
6589
|
}
|
|
6227
|
-
function getSkillArtifacts(projectDir, skillsDir) {
|
|
6228
|
-
return
|
|
6590
|
+
function getSkillArtifacts(projectDir, skillsDir, workflows = ALL_TOOL_WORKFLOWS) {
|
|
6591
|
+
return workflows.map((workflow) => ({
|
|
6229
6592
|
workflow,
|
|
6230
6593
|
path: resolve(projectDir, skillsDir, "skills", OPSX_WORKFLOW_TO_SKILL_DIR[workflow], "SKILL.md")
|
|
6231
6594
|
}));
|
|
6232
6595
|
}
|
|
6233
|
-
function getCommandArtifacts(projectDir,
|
|
6596
|
+
function getCommandArtifacts(projectDir, tool, rootOverride) {
|
|
6234
6597
|
return ALL_TOOL_WORKFLOWS.flatMap((workflow) => {
|
|
6235
|
-
const artifact =
|
|
6598
|
+
const artifact = resolveCommandArtifact(projectDir, tool, workflow, rootOverride);
|
|
6236
6599
|
return artifact ? [artifact] : [];
|
|
6237
6600
|
});
|
|
6238
6601
|
}
|
|
6239
6602
|
function invalidateToolInitCaches(projectDir) {
|
|
6240
|
-
const cacheRoots = new Set([resolve(projectDir)]);
|
|
6603
|
+
const cacheRoots = new Set([resolve(projectDir), getExternalCodexCommandObservationRoot()]);
|
|
6241
6604
|
for (const tool of AI_TOOLS) {
|
|
6242
6605
|
if (tool.skillsDir) cacheRoots.add(resolve(projectDir, tool.skillsDir));
|
|
6243
|
-
for (const
|
|
6606
|
+
for (const migration of tool.migrations ?? []) cacheRoots.add(resolve(projectDir, migration.from));
|
|
6607
|
+
for (const commandArtifact of getCommandArtifacts(projectDir, tool)) {
|
|
6244
6608
|
cacheRoots.add(dirname$1(commandArtifact.path));
|
|
6245
6609
|
for (const legacyPath of commandArtifact.legacyPaths ?? []) cacheRoots.add(dirname$1(legacyPath));
|
|
6246
6610
|
}
|
|
@@ -6265,10 +6629,9 @@ async function getExistingSkillPaths(projectDir, skillsDir, entries, projectRoot
|
|
|
6265
6629
|
async function getExistingCommandPaths(entries) {
|
|
6266
6630
|
const pathsByDirectory = /* @__PURE__ */ new Map();
|
|
6267
6631
|
for (const entry of entries) for (const path of [entry.path, ...entry.legacyPaths ?? []]) {
|
|
6268
|
-
const
|
|
6269
|
-
const paths = pathsByDirectory.get(directory) ?? [];
|
|
6632
|
+
const paths = pathsByDirectory.get(dirname$1(path)) ?? [];
|
|
6270
6633
|
paths.push(path);
|
|
6271
|
-
pathsByDirectory.set(
|
|
6634
|
+
pathsByDirectory.set(dirname$1(path), paths);
|
|
6272
6635
|
}
|
|
6273
6636
|
const directoryEntries = await Promise.all([...pathsByDirectory].map(async ([directory, paths]) => ({
|
|
6274
6637
|
paths,
|
|
@@ -6282,8 +6645,12 @@ function hasExistingArtifact(entry, existingPaths) {
|
|
|
6282
6645
|
function hasLegacyArtifact(entry, existingPaths) {
|
|
6283
6646
|
return entry.legacyPaths?.some((legacyPath) => existingPaths.has(legacyPath)) ?? false;
|
|
6284
6647
|
}
|
|
6285
|
-
function
|
|
6286
|
-
|
|
6648
|
+
function resolveExistingArtifactPath(entry, existingPaths) {
|
|
6649
|
+
if (existingPaths.has(entry.path)) return entry.path;
|
|
6650
|
+
return entry.legacyPaths?.find((legacyPath) => existingPaths.has(legacyPath)) ?? null;
|
|
6651
|
+
}
|
|
6652
|
+
function collectExistingWorkflows(entries, existingPaths) {
|
|
6653
|
+
return entries.filter((entry) => hasExistingArtifact(entry, existingPaths)).map((entry) => entry.workflow);
|
|
6287
6654
|
}
|
|
6288
6655
|
function collectMissingWorkflows(entries, existingPaths) {
|
|
6289
6656
|
return entries.filter((entry) => !hasExistingArtifact(entry, existingPaths)).map((entry) => entry.workflow);
|
|
@@ -6294,61 +6661,228 @@ function collectUnexpectedWorkflows(entries, desiredWorkflowSet, existingPaths)
|
|
|
6294
6661
|
function collectLegacyWorkflows(entries, existingPaths) {
|
|
6295
6662
|
return entries.filter((entry) => hasLegacyArtifact(entry, existingPaths)).map((entry) => entry.workflow);
|
|
6296
6663
|
}
|
|
6664
|
+
function extractGeneratedByVersion(content) {
|
|
6665
|
+
if (!content) return null;
|
|
6666
|
+
return content.match(/^\s*generatedBy:\s*["']?([^"'\n]+)["']?\s*$/m)?.[1]?.trim() ?? null;
|
|
6667
|
+
}
|
|
6668
|
+
async function readGeneratedByVersion(entries, existingPaths) {
|
|
6669
|
+
for (const entry of entries) {
|
|
6670
|
+
if (!existingPaths.has(entry.path)) continue;
|
|
6671
|
+
const generatedByVersion = extractGeneratedByVersion(await reactiveReadFile(entry.path));
|
|
6672
|
+
if (generatedByVersion) return generatedByVersion;
|
|
6673
|
+
}
|
|
6674
|
+
return null;
|
|
6675
|
+
}
|
|
6676
|
+
function normalizeCommandContent(content) {
|
|
6677
|
+
return content.replace(/^\uFEFF/u, "").replaceAll("\r\n", "\n");
|
|
6678
|
+
}
|
|
6679
|
+
async function areExpectedCommandContentsCurrent(toolId, entries, existingPaths, commandContents) {
|
|
6680
|
+
if (entries.length === 0) return false;
|
|
6681
|
+
const expectedContents = commandContents?.[toolId];
|
|
6682
|
+
if (!expectedContents) return false;
|
|
6683
|
+
for (const entry of entries) {
|
|
6684
|
+
const path = resolveExistingArtifactPath(entry, existingPaths);
|
|
6685
|
+
const expectedContent = expectedContents[entry.workflow];
|
|
6686
|
+
if (!path || expectedContent === void 0) return false;
|
|
6687
|
+
const actualContent = await reactiveReadFile(path);
|
|
6688
|
+
if (actualContent === null || normalizeCommandContent(actualContent) !== normalizeCommandContent(expectedContent)) return false;
|
|
6689
|
+
}
|
|
6690
|
+
return true;
|
|
6691
|
+
}
|
|
6692
|
+
function isCurrentGeneratedByVersion(version, expectedVersion, hasAnyArtifacts) {
|
|
6693
|
+
return !hasAnyArtifacts || version === expectedVersion;
|
|
6694
|
+
}
|
|
6695
|
+
async function collectCodexCleanup(cleanup) {
|
|
6696
|
+
const promptRoot = getExternalCodexCommandObservationRoot();
|
|
6697
|
+
const promptFiles = await readArtifactDirectory(promptRoot);
|
|
6698
|
+
const managedFiles = Object.entries(cleanup.managedFiles).filter(([fileName]) => promptFiles.has(fileName));
|
|
6699
|
+
if (managedFiles.length === 0) return void 0;
|
|
6700
|
+
return {
|
|
6701
|
+
required: true,
|
|
6702
|
+
kind: cleanup.kind,
|
|
6703
|
+
paths: managedFiles.map(([fileName]) => join$1(promptRoot, fileName)),
|
|
6704
|
+
workflows: toKnownWorkflows(managedFiles.flatMap(([, workflows]) => workflows)),
|
|
6705
|
+
replacementLabel: cleanup.replacementLabel
|
|
6706
|
+
};
|
|
6707
|
+
}
|
|
6708
|
+
function cleanupPatternMatches(fileName, patternName) {
|
|
6709
|
+
const escaped = patternName.replace(/[.+?^${}()|[\]\\]/gu, "\\$&").replaceAll("*", ".*");
|
|
6710
|
+
return new RegExp(`^${escaped}$`, "u").test(fileName);
|
|
6711
|
+
}
|
|
6712
|
+
function isAmbiguousProjectCleanupPattern(tool, pattern) {
|
|
6713
|
+
if (!pattern.includes("opsx-*") || !tool.command) return false;
|
|
6714
|
+
return [tool.command.pathTemplate, ...tool.command.legacyPathTemplates ?? []].map((pathTemplate) => pathTemplate.replace("{workflow}", "*")).includes(pattern);
|
|
6715
|
+
}
|
|
6716
|
+
async function collectProjectCleanup(projectDir, tool, cleanup, projectRootEntries, extraPatterns = []) {
|
|
6717
|
+
const paths = [];
|
|
6718
|
+
const workflows = [];
|
|
6719
|
+
for (const pattern of [...cleanup.patterns, ...extraPatterns]) {
|
|
6720
|
+
if (isAmbiguousProjectCleanupPattern(tool, pattern)) continue;
|
|
6721
|
+
const rootName = pattern.split("/")[0];
|
|
6722
|
+
if (!rootName || !projectRootEntries.has(rootName)) continue;
|
|
6723
|
+
const absolutePattern = resolve(projectDir, pattern);
|
|
6724
|
+
if (!pattern.includes("*")) {
|
|
6725
|
+
if ((await readArtifactDirectory(dirname$1(absolutePattern))).has(basename(absolutePattern))) paths.push(absolutePattern);
|
|
6726
|
+
continue;
|
|
6727
|
+
}
|
|
6728
|
+
const directory = dirname$1(absolutePattern);
|
|
6729
|
+
const filePattern = basename(absolutePattern);
|
|
6730
|
+
const entries = await readArtifactDirectory(directory);
|
|
6731
|
+
for (const fileName of entries) {
|
|
6732
|
+
if (!cleanupPatternMatches(fileName, filePattern)) continue;
|
|
6733
|
+
paths.push(join$1(directory, fileName));
|
|
6734
|
+
const workflow = fileName.replace(/^opsx-/u, "").replace(/^openspec-/u, "").replace(/\.(?:prompt\.)?(?:md|toml|prompt)$/u, "");
|
|
6735
|
+
workflows.push(workflow);
|
|
6736
|
+
}
|
|
6737
|
+
}
|
|
6738
|
+
return {
|
|
6739
|
+
paths,
|
|
6740
|
+
workflows: toKnownWorkflows(workflows)
|
|
6741
|
+
};
|
|
6742
|
+
}
|
|
6743
|
+
async function collectCleanup(projectDir, tool, projectRootEntries) {
|
|
6744
|
+
if (!tool.cleanup) return void 0;
|
|
6745
|
+
const globalCleanup = tool.cleanup.kind === "managed-global-prompts" ? await collectCodexCleanup(tool.cleanup) : void 0;
|
|
6746
|
+
const projectCleanup$1 = await collectProjectCleanup(projectDir, tool, tool.cleanup.kind === "project-patterns" ? tool.cleanup : {
|
|
6747
|
+
kind: "project-patterns",
|
|
6748
|
+
patterns: []
|
|
6749
|
+
}, projectRootEntries, tool.cleanup.kind === "managed-global-prompts" ? tool.cleanup.projectPatterns : []);
|
|
6750
|
+
const paths = [...projectCleanup$1.paths, ...globalCleanup?.paths ?? []];
|
|
6751
|
+
if (paths.length === 0) return void 0;
|
|
6752
|
+
const workflows = [...new Set([...projectCleanup$1.workflows, ...globalCleanup?.workflows ?? []])];
|
|
6753
|
+
return {
|
|
6754
|
+
required: true,
|
|
6755
|
+
kind: projectCleanup$1.paths.length > 0 && globalCleanup ? "mixed" : globalCleanup ? "managed-global-prompts" : "project-artifacts",
|
|
6756
|
+
paths,
|
|
6757
|
+
workflows,
|
|
6758
|
+
replacementLabel: globalCleanup?.replacementLabel ?? "OpenSpec 1.7 Agent delivery"
|
|
6759
|
+
};
|
|
6760
|
+
}
|
|
6761
|
+
async function collectMigrationEvidence(projectDir, tool, projectRootEntries) {
|
|
6762
|
+
for (const migration of tool.migrations ?? []) {
|
|
6763
|
+
const skillArtifacts = getSkillArtifacts(projectDir, migration.from);
|
|
6764
|
+
const commandArtifacts = getCommandArtifacts(projectDir, tool, migration.from);
|
|
6765
|
+
const skillPaths = await getExistingSkillPaths(projectDir, migration.from, skillArtifacts, projectRootEntries);
|
|
6766
|
+
const commandPaths = await getExistingCommandPaths(commandArtifacts);
|
|
6767
|
+
const workflows = [...new Set([...collectExistingWorkflows(skillArtifacts, skillPaths), ...collectExistingWorkflows(commandArtifacts, commandPaths)])];
|
|
6768
|
+
if (workflows.length === 0) continue;
|
|
6769
|
+
return {
|
|
6770
|
+
state: {
|
|
6771
|
+
...migration,
|
|
6772
|
+
workflows,
|
|
6773
|
+
skillFiles: collectExistingWorkflows(skillArtifacts, skillPaths).length,
|
|
6774
|
+
commandFiles: collectExistingWorkflows(commandArtifacts, commandPaths).length
|
|
6775
|
+
},
|
|
6776
|
+
skillPaths,
|
|
6777
|
+
commandPaths,
|
|
6778
|
+
skillArtifacts,
|
|
6779
|
+
commandArtifacts
|
|
6780
|
+
};
|
|
6781
|
+
}
|
|
6782
|
+
}
|
|
6783
|
+
function resolveSummaryStatus(readiness, issues) {
|
|
6784
|
+
if (issues.includes("migration-required")) return "migration-required";
|
|
6785
|
+
if (issues.includes("cleanup-needed")) return "cleanup-needed";
|
|
6786
|
+
if (issues.includes("stale-version")) return "stale-version";
|
|
6787
|
+
return readiness;
|
|
6788
|
+
}
|
|
6297
6789
|
async function projectToolInitStates(projectDir, options) {
|
|
6298
6790
|
const desiredWorkflows = toKnownWorkflows(options.workflows);
|
|
6299
6791
|
const desiredWorkflowSet = new Set(desiredWorkflows);
|
|
6300
|
-
const shouldGenerateSkills = options.delivery !== "commands";
|
|
6301
|
-
const shouldGenerateCommands = options.delivery !== "skills";
|
|
6302
6792
|
const projectRootEntries = await readArtifactDirectory(projectDir);
|
|
6303
|
-
return Promise.all(AI_TOOLS.
|
|
6793
|
+
return Promise.all(AI_TOOLS.map(async (tool) => {
|
|
6794
|
+
if (!tool.available || !tool.skillsDir) return {
|
|
6795
|
+
toolId: tool.value,
|
|
6796
|
+
toolName: tool.name,
|
|
6797
|
+
status: "unavailable",
|
|
6798
|
+
readiness: "unavailable",
|
|
6799
|
+
issues: [],
|
|
6800
|
+
hasAnyArtifacts: false,
|
|
6801
|
+
expectedSkillCount: 0,
|
|
6802
|
+
presentExpectedSkillCount: 0,
|
|
6803
|
+
detectedSkillCount: 0,
|
|
6804
|
+
expectedCommandCount: 0,
|
|
6805
|
+
presentExpectedCommandCount: 0,
|
|
6806
|
+
detectedCommandCount: 0,
|
|
6807
|
+
missingSkillWorkflows: [],
|
|
6808
|
+
missingCommandWorkflows: [],
|
|
6809
|
+
unexpectedSkillWorkflows: [],
|
|
6810
|
+
unexpectedCommandWorkflows: [],
|
|
6811
|
+
legacyCommandWorkflows: [],
|
|
6812
|
+
installedSkillWorkflows: [],
|
|
6813
|
+
installedCommandWorkflows: [],
|
|
6814
|
+
generatedByVersion: null
|
|
6815
|
+
};
|
|
6816
|
+
const shouldGenerateSkills = options.delivery !== "commands" || tool.capability === "skills-invocable";
|
|
6817
|
+
const shouldGenerateCommands = options.delivery !== "skills" && tool.capability === "adapter-backed";
|
|
6304
6818
|
const skillArtifacts = getSkillArtifacts(projectDir, tool.skillsDir);
|
|
6305
|
-
const commandArtifacts = getCommandArtifacts(projectDir, tool
|
|
6819
|
+
const commandArtifacts = getCommandArtifacts(projectDir, tool);
|
|
6306
6820
|
const existingSkillPaths = await getExistingSkillPaths(projectDir, tool.skillsDir, skillArtifacts, projectRootEntries);
|
|
6307
6821
|
const existingCommandPaths = await getExistingCommandPaths(commandArtifacts);
|
|
6308
6822
|
const expectedSkillArtifacts = shouldGenerateSkills ? skillArtifacts.filter((entry) => desiredWorkflowSet.has(entry.workflow)) : [];
|
|
6309
6823
|
const expectedCommandArtifacts = shouldGenerateCommands ? commandArtifacts.filter((entry) => desiredWorkflowSet.has(entry.workflow)) : [];
|
|
6310
6824
|
const missingSkillWorkflows = collectMissingWorkflows(expectedSkillArtifacts, existingSkillPaths);
|
|
6311
6825
|
const missingCommandWorkflows = collectMissingWorkflows(expectedCommandArtifacts, existingCommandPaths);
|
|
6312
|
-
const unexpectedSkillWorkflows = collectUnexpectedWorkflows(
|
|
6313
|
-
const unexpectedCommandWorkflows = collectUnexpectedWorkflows(
|
|
6826
|
+
const unexpectedSkillWorkflows = collectUnexpectedWorkflows(skillArtifacts, shouldGenerateSkills ? desiredWorkflowSet : /* @__PURE__ */ new Set(), existingSkillPaths);
|
|
6827
|
+
const unexpectedCommandWorkflows = collectUnexpectedWorkflows(commandArtifacts, shouldGenerateCommands ? desiredWorkflowSet : /* @__PURE__ */ new Set(), existingCommandPaths);
|
|
6828
|
+
const installedSkillWorkflows = collectExistingWorkflows(skillArtifacts, existingSkillPaths);
|
|
6829
|
+
const installedCommandWorkflows = collectExistingWorkflows(commandArtifacts, existingCommandPaths);
|
|
6314
6830
|
const legacyCommandWorkflows = collectLegacyWorkflows(commandArtifacts, existingCommandPaths);
|
|
6831
|
+
const migrationEvidence = await collectMigrationEvidence(projectDir, tool, projectRootEntries);
|
|
6832
|
+
const cleanup = await collectCleanup(projectDir, tool, projectRootEntries);
|
|
6833
|
+
const skillGeneratedByVersion = await readGeneratedByVersion(skillArtifacts, existingSkillPaths) ?? (migrationEvidence ? await readGeneratedByVersion(migrationEvidence.skillArtifacts, migrationEvidence.skillPaths) : null);
|
|
6315
6834
|
const expectedSkillCount = expectedSkillArtifacts.length;
|
|
6316
|
-
const presentExpectedSkillCount = expectedSkillCount - missingSkillWorkflows.length;
|
|
6317
|
-
const detectedSkillCount = countExisting(skillArtifacts, existingSkillPaths);
|
|
6318
6835
|
const expectedCommandCount = expectedCommandArtifacts.length;
|
|
6319
|
-
const
|
|
6320
|
-
const detectedCommandCount =
|
|
6321
|
-
const hasAnyArtifacts = detectedSkillCount + detectedCommandCount > 0;
|
|
6836
|
+
const detectedSkillCount = installedSkillWorkflows.length;
|
|
6837
|
+
const detectedCommandCount = installedCommandWorkflows.length;
|
|
6838
|
+
const hasAnyArtifacts = detectedSkillCount + detectedCommandCount + (migrationEvidence?.state.workflows.length ?? 0) > 0;
|
|
6839
|
+
const commandContentsCurrent = !(detectedSkillCount + (migrationEvidence?.state.skillFiles ?? 0) > 0) && detectedCommandCount > 0 && await areExpectedCommandContentsCurrent(tool.value, expectedCommandArtifacts, existingCommandPaths, options.commandContents);
|
|
6840
|
+
const generatedByVersion = skillGeneratedByVersion ?? (commandContentsCurrent ? options.generatorVersion ?? PINNED_AGENT_GENERATOR_VERSION : null);
|
|
6322
6841
|
const isInitialized = missingSkillWorkflows.length === 0 && missingCommandWorkflows.length === 0 && unexpectedSkillWorkflows.length === 0 && unexpectedCommandWorkflows.length === 0;
|
|
6842
|
+
const migration = migrationEvidence?.state;
|
|
6843
|
+
const readiness = !hasAnyArtifacts ? "uninitialized" : isInitialized ? "initialized" : "partial";
|
|
6844
|
+
const issues = [];
|
|
6845
|
+
if (!isCurrentGeneratedByVersion(generatedByVersion, options.generatorVersion ?? PINNED_AGENT_GENERATOR_VERSION, hasAnyArtifacts)) issues.push("stale-version");
|
|
6846
|
+
if (cleanup) issues.push("cleanup-needed");
|
|
6847
|
+
if (migration) issues.push("migration-required");
|
|
6323
6848
|
return {
|
|
6324
6849
|
toolId: tool.value,
|
|
6325
6850
|
toolName: tool.name,
|
|
6326
|
-
status:
|
|
6851
|
+
status: resolveSummaryStatus(readiness, issues),
|
|
6852
|
+
readiness,
|
|
6853
|
+
issues,
|
|
6327
6854
|
hasAnyArtifacts,
|
|
6328
6855
|
expectedSkillCount,
|
|
6329
|
-
presentExpectedSkillCount,
|
|
6856
|
+
presentExpectedSkillCount: expectedSkillCount - missingSkillWorkflows.length,
|
|
6330
6857
|
detectedSkillCount,
|
|
6331
6858
|
expectedCommandCount,
|
|
6332
|
-
presentExpectedCommandCount,
|
|
6859
|
+
presentExpectedCommandCount: expectedCommandCount - missingCommandWorkflows.length,
|
|
6333
6860
|
detectedCommandCount,
|
|
6334
6861
|
missingSkillWorkflows,
|
|
6335
6862
|
missingCommandWorkflows,
|
|
6336
6863
|
unexpectedSkillWorkflows,
|
|
6337
6864
|
unexpectedCommandWorkflows,
|
|
6338
|
-
legacyCommandWorkflows
|
|
6865
|
+
legacyCommandWorkflows,
|
|
6866
|
+
installedSkillWorkflows,
|
|
6867
|
+
installedCommandWorkflows,
|
|
6868
|
+
generatedByVersion,
|
|
6869
|
+
cleanup,
|
|
6870
|
+
migration
|
|
6339
6871
|
};
|
|
6340
6872
|
}));
|
|
6341
6873
|
}
|
|
6342
|
-
/** Read a fresh one-shot Project
|
|
6874
|
+
/** Read a fresh one-shot Project Agent artifact inventory. */
|
|
6343
6875
|
async function getToolInitStates(projectDir, options) {
|
|
6344
6876
|
invalidateToolInitCaches(projectDir);
|
|
6345
6877
|
return projectToolInitStates(projectDir, options);
|
|
6346
6878
|
}
|
|
6347
|
-
/** Create a retained
|
|
6879
|
+
/** Create a retained Agent inventory task executed by one ReactiveContext. */
|
|
6348
6880
|
function createToolInitStateProjection(projectDir, options) {
|
|
6349
6881
|
const projectionOptions = {
|
|
6350
6882
|
delivery: options.delivery,
|
|
6351
|
-
workflows: [...options.workflows]
|
|
6883
|
+
workflows: [...options.workflows],
|
|
6884
|
+
generatorVersion: options.generatorVersion,
|
|
6885
|
+
commandContents: options.commandContents
|
|
6352
6886
|
};
|
|
6353
6887
|
return () => projectToolInitStates(projectDir, projectionOptions);
|
|
6354
6888
|
}
|
|
@@ -6505,11 +7039,11 @@ async function mapCliProjectionSeries(inputs, project) {
|
|
|
6505
7039
|
//#endregion
|
|
6506
7040
|
//#region src/opsx-kernel.ts
|
|
6507
7041
|
/**
|
|
6508
|
-
* Orthogonal intents (updated 2026-
|
|
7042
|
+
* Orthogonal intents (updated 2026-08-02 Asia/Shanghai):
|
|
6509
7043
|
* 1. Maintain reactive CLI-backed projections and their direct typed Projection Work readers.
|
|
6510
7044
|
* 2. Share and release per-entity streams through one planning-root kernel lifecycle.
|
|
6511
|
-
* 3. Keep OpenSpec configuration ownership outside the workflow
|
|
6512
|
-
* 4. Preserve typed Status/Instructions provenance with the resolved root selector.
|
|
7045
|
+
* 3. Keep OpenSpec configuration ownership outside the workflow cache while tracking both YAML filename variants.
|
|
7046
|
+
* 4. Preserve typed Status and Artifact/Apply/Archive Instructions provenance with the resolved root selector.
|
|
6513
7047
|
* 5. Keep Change enumeration business truth in the typed CLI result while files only invalidate it.
|
|
6514
7048
|
*
|
|
6515
7049
|
* Original request (2026-07-15): "Planning-root adapters and services consume the CLI-resolved root."
|
|
@@ -6588,7 +7122,7 @@ async function readGlobArtifactFiles(projectDir, changeId, outputPath) {
|
|
|
6588
7122
|
}
|
|
6589
7123
|
async function touchOpsxProjectDeps(projectDir) {
|
|
6590
7124
|
const openspecDir = join$1(projectDir, "openspec");
|
|
6591
|
-
await reactiveReadFile(join$1(openspecDir, "config.yaml"));
|
|
7125
|
+
await Promise.all([reactiveReadFile(join$1(openspecDir, "config.yaml")), reactiveReadFile(join$1(openspecDir, "config.yml"))]);
|
|
6592
7126
|
const schemaRoot = join$1(openspecDir, "schemas");
|
|
6593
7127
|
const schemaDirs = await reactiveReadDir(schemaRoot, {
|
|
6594
7128
|
directoriesOnly: true,
|
|
@@ -6645,10 +7179,10 @@ function readOpsxRoot(data) {
|
|
|
6645
7179
|
const parsed = z.object({ root: CliRootSchema }).passthrough().safeParse(data);
|
|
6646
7180
|
return parsed.success ? parsed.data.root : void 0;
|
|
6647
7181
|
}
|
|
6648
|
-
function createOpsxCliEvidence(result, command, rootSelector) {
|
|
7182
|
+
function createOpsxCliEvidence(result, command$1, rootSelector) {
|
|
6649
7183
|
const root = readOpsxRoot(result.data);
|
|
6650
7184
|
return OpsxCliEvidenceSchema.parse({
|
|
6651
|
-
command,
|
|
7185
|
+
command: command$1,
|
|
6652
7186
|
success: result.success,
|
|
6653
7187
|
stdout: result.stdout,
|
|
6654
7188
|
stderr: result.stderr,
|
|
@@ -6683,6 +7217,7 @@ var OpsxKernel = class {
|
|
|
6683
7217
|
_statuses = /* @__PURE__ */ new Map();
|
|
6684
7218
|
_instructions = /* @__PURE__ */ new Map();
|
|
6685
7219
|
_applyInstructions = /* @__PURE__ */ new Map();
|
|
7220
|
+
_archiveInstructions = /* @__PURE__ */ new Map();
|
|
6686
7221
|
_changeMetadata = /* @__PURE__ */ new Map();
|
|
6687
7222
|
_artifactOutputs = /* @__PURE__ */ new Map();
|
|
6688
7223
|
_globArtifactFiles = /* @__PURE__ */ new Map();
|
|
@@ -6759,6 +7294,12 @@ var OpsxKernel = class {
|
|
|
6759
7294
|
if (!state) throw new Error(`Apply instructions not found for change "${changeId}"`);
|
|
6760
7295
|
return state.get();
|
|
6761
7296
|
}
|
|
7297
|
+
getArchiveInstructions(changeId, schema) {
|
|
7298
|
+
const key = `${changeId}:${schema ?? ""}`;
|
|
7299
|
+
const state = this._archiveInstructions.get(key);
|
|
7300
|
+
if (!state) throw new Error(`Archive instructions not found for change "${changeId}"`);
|
|
7301
|
+
return state.get();
|
|
7302
|
+
}
|
|
6762
7303
|
getSchemaResolution(name) {
|
|
6763
7304
|
const state = this._schemaResolutions.get(name);
|
|
6764
7305
|
if (!state) throw new Error(`Schema resolution not found for "${name}"`);
|
|
@@ -6882,16 +7423,20 @@ var OpsxKernel = class {
|
|
|
6882
7423
|
if (!this._changeMetadata.has(changeId)) this._changeMetadata.set(changeId, new ReactiveState(null));
|
|
6883
7424
|
const applyKey = `${changeId}:`;
|
|
6884
7425
|
if (!this._applyInstructions.has(applyKey)) this._applyInstructions.set(applyKey, new ReactiveState(null));
|
|
7426
|
+
const archiveKey = `${changeId}:`;
|
|
7427
|
+
if (!this._archiveInstructions.has(archiveKey)) this._archiveInstructions.set(archiveKey, new ReactiveState(null));
|
|
6885
7428
|
await Promise.all([
|
|
6886
7429
|
this.startStreamOnce(`change:${changeId}:status:`, this._statuses.get(statusKey), () => this.fetchStatus(changeId, void 0), signal),
|
|
6887
7430
|
this.startStreamOnce(`change:${changeId}:metadata`, this._changeMetadata.get(changeId), () => this.fetchChangeMetadata(changeId), signal),
|
|
6888
|
-
this.startStreamOnce(`change:${changeId}:apply:`, this._applyInstructions.get(applyKey), () => this.fetchApplyInstructions(changeId, void 0), signal)
|
|
7431
|
+
this.startStreamOnce(`change:${changeId}:apply:`, this._applyInstructions.get(applyKey), () => this.fetchApplyInstructions(changeId, void 0), signal),
|
|
7432
|
+
this.startStreamOnce(`change:${changeId}:archive:`, this._archiveInstructions.get(archiveKey), () => this.fetchArchiveInstructions(changeId, void 0), signal)
|
|
6889
7433
|
]);
|
|
6890
7434
|
const status = this._statuses.get(statusKey)?.get();
|
|
6891
7435
|
if (status?.artifacts) await Promise.all(status.artifacts.map(async (artifact) => {
|
|
6892
7436
|
const instrKey = `${changeId}:${artifact.id}:`;
|
|
6893
7437
|
if (!this._instructions.has(instrKey)) this._instructions.set(instrKey, new ReactiveState(null));
|
|
6894
7438
|
await this.startStreamOnce(`change:${changeId}:instructions:${artifact.id}:`, this._instructions.get(instrKey), () => this.fetchInstructions(changeId, artifact.id, void 0), signal);
|
|
7439
|
+
if (artifact.status === "skipped") return;
|
|
6895
7440
|
const outputKey = `${changeId}:${artifact.outputPath}`;
|
|
6896
7441
|
if (!this._artifactOutputs.has(outputKey)) this._artifactOutputs.set(outputKey, new ReactiveState(null));
|
|
6897
7442
|
await this.startStreamOnce(`change:${changeId}:output:${artifact.outputPath}`, this._artifactOutputs.get(outputKey), () => this.fetchArtifactOutput(changeId, artifact.outputPath), signal);
|
|
@@ -6948,6 +7493,10 @@ var OpsxKernel = class {
|
|
|
6948
7493
|
this._applyInstructions.delete(key);
|
|
6949
7494
|
this._streamReady.delete(`change:${id}:apply:${key.slice(id.length + 1)}`);
|
|
6950
7495
|
}
|
|
7496
|
+
for (const key of this._archiveInstructions.keys()) if (key.startsWith(`${id}:`)) {
|
|
7497
|
+
this._archiveInstructions.delete(key);
|
|
7498
|
+
this._streamReady.delete(`change:${id}:archive:${key.slice(id.length + 1)}`);
|
|
7499
|
+
}
|
|
6951
7500
|
this._changeMetadata.delete(id);
|
|
6952
7501
|
this._streamReady.delete(`change:${id}:metadata`);
|
|
6953
7502
|
for (const key of this._artifactOutputs.keys()) if (key.startsWith(`${id}:`)) {
|
|
@@ -7029,7 +7578,7 @@ var OpsxKernel = class {
|
|
|
7029
7578
|
}
|
|
7030
7579
|
});
|
|
7031
7580
|
const changeRelDir = `openspec/changes/${changeId}`;
|
|
7032
|
-
for (const artifact of status.artifacts) {
|
|
7581
|
+
for (const artifact of status.artifacts) if (artifact.status !== "skipped") {
|
|
7033
7582
|
artifact.relativePath = `${changeRelDir}/${artifact.outputPath}`;
|
|
7034
7583
|
await touchArtifactOutputDeps(this.projectDir, changeId, artifact.outputPath);
|
|
7035
7584
|
}
|
|
@@ -7077,6 +7626,19 @@ var OpsxKernel = class {
|
|
|
7077
7626
|
applyInstructionProgress: createApplyInstructionProgress(instructions.applyInstructionProgress, trackedTaskProgress)
|
|
7078
7627
|
};
|
|
7079
7628
|
}
|
|
7629
|
+
async fetchArchiveInstructions(changeId, schema) {
|
|
7630
|
+
await touchOpsxProjectDeps(this.projectDir);
|
|
7631
|
+
await touchOpsxChangeDeps(this.projectDir, changeId);
|
|
7632
|
+
const result = await this.cliExecutor.contracts.archiveInstructions(changeId, {
|
|
7633
|
+
...this.rootSelector,
|
|
7634
|
+
...schema ? { schema } : {}
|
|
7635
|
+
});
|
|
7636
|
+
const data = requireCommandData("openspec instructions archive", result, CliArchiveInstructionsSuccessSchema);
|
|
7637
|
+
return ArchiveInstructionsSchema.parse({
|
|
7638
|
+
...data,
|
|
7639
|
+
evidence: createOpsxCliEvidence(result, "instructions archive", this.rootSelector)
|
|
7640
|
+
});
|
|
7641
|
+
}
|
|
7080
7642
|
async fetchSchemaResolution(name) {
|
|
7081
7643
|
return (await this.fetchSchemaResolutionProjection(name)).value;
|
|
7082
7644
|
}
|
|
@@ -7191,6 +7753,10 @@ var OpsxKernel = class {
|
|
|
7191
7753
|
readApplyInstructionsProjection(changeId, schema) {
|
|
7192
7754
|
return this.fetchApplyInstructions(changeId, schema);
|
|
7193
7755
|
}
|
|
7756
|
+
/** Execute one Archive-instructions projection in the caller-owned Work generation. */
|
|
7757
|
+
readArchiveInstructionsProjection(changeId, schema) {
|
|
7758
|
+
return this.fetchArchiveInstructions(changeId, schema);
|
|
7759
|
+
}
|
|
7194
7760
|
/** Execute the aggregate Schema bundle while retaining exact resolved-file dependencies. */
|
|
7195
7761
|
async readConfigBundleProjection() {
|
|
7196
7762
|
const schemasProjection = await this.fetchSchemasProjection();
|
|
@@ -7253,6 +7819,12 @@ var OpsxKernel = class {
|
|
|
7253
7819
|
if (!this._applyInstructions.has(key)) this._applyInstructions.set(key, new ReactiveState(null));
|
|
7254
7820
|
await this.startStreamOnce(`change:${canonicalChangeId}:apply:${schema ?? ""}`, this._applyInstructions.get(key), () => this.fetchApplyInstructions(canonicalChangeId, schema), this.controller.signal);
|
|
7255
7821
|
}
|
|
7822
|
+
async ensureArchiveInstructions(changeId, schema) {
|
|
7823
|
+
const canonicalChangeId = requireCanonicalOpenSpecEntityId(changeId, "changeId");
|
|
7824
|
+
const key = `${canonicalChangeId}:${schema ?? ""}`;
|
|
7825
|
+
if (!this._archiveInstructions.has(key)) this._archiveInstructions.set(key, new ReactiveState(null));
|
|
7826
|
+
await this.startStreamOnce(`change:${canonicalChangeId}:archive:${schema ?? ""}`, this._archiveInstructions.get(key), () => this.fetchArchiveInstructions(canonicalChangeId, schema), this.controller.signal);
|
|
7827
|
+
}
|
|
7256
7828
|
async ensureArtifactOutput(changeId, outputPath) {
|
|
7257
7829
|
const location = requireCanonicalArtifactLocation(changeId, outputPath);
|
|
7258
7830
|
const key = `${location.changeId}:${location.outputPath}`;
|
|
@@ -7513,4 +8085,4 @@ const PtyServerMessageSchema = z.discriminatedUnion("type", [
|
|
|
7513
8085
|
]);
|
|
7514
8086
|
|
|
7515
8087
|
//#endregion
|
|
7516
|
-
export { ACCESS_GATE_CREDENTIAL_BYTES, AI_TOOLS, ApplyInstructionsContextFilesSchema, ApplyInstructionsProjectionSchema, ApplyInstructionsSchema, ApplyTaskSchema, ArtifactInstructionsSchema, ArtifactStatusSchema, BUILTIN_SOUND_IDS, BUILTIN_SOUND_OPTIONS, BUILTIN_TERMINAL_SPAWN_COMMANDS, BatchTranslateEventSchema, BatchTranslateInputSchema, BuiltinSoundIdSchema, CODE_EDITOR_THEME_VALUES, CUSTOM_SOUND_ADD_VALUE, ChangeFileSchema, ChangeSchema, ChangeStatusSchema, CliApplyInstructionsSchema, CliArchiveSchema, CliArtifactInstructionsSchema, CliChangeListSchema, CliContextSchema, CliDiagnosticFailureSchema, CliDiagnosticSchema, CliDoctorReferenceEntrySchema, CliDoctorSchema, CliExecutor, CliJsonValueSchema, CliProjectionCommandError, CliProjectionCommandEvidenceSchema, CliProjectionFailureSchema, CliProjectionInvalidationCauseSchema, CliProjectionNoticeSchema, CliProjectionStateNameSchema, CliReferenceIndexEntrySchema, CliRootSchema, CliRootSourceSchema, CliShowSpecDocumentSchema, CliShowSpecSchema, CliSpecListSchema, CliStoreCleanupSchema, CliStoreDoctorEntrySchema, CliStoreDoctorSchema, CliStoreListSchema, CliStoreMutationSchema, CliStoreSchema, CliStreamTerminationError, CliValidateSchema, CliWorkflowStatusSchema, CodeEditorThemeSchema, ConfigManager, CustomSoundHashSchema, CustomSoundIdSchema, CustomSoundMetadataFileSchema, CustomSoundMetadataSchema, DASHBOARD_METRIC_KEYS, DEFAULT_BELL_SOUND_ID, DEFAULT_CONFIG, DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET, DEFAULT_GLOBAL_SETTINGS, DEFAULT_NOTIFICATION_SOUND_ID, DEFAULT_TERMINAL_DARK_THEME, DEFAULT_TERMINAL_LIGHT_THEME, DEFAULT_TERMINAL_THEME_MODE, DEFAULT_TRANSLATION_CACHE_ENTRY_LIMIT, DEFAULT_TRANSLATION_ENGINE_ID, DOCUMENT_TRANSLATION_DISPLAY_MODES, DashboardConfigSchema, DashboardGitSnapshotSchema, DashboardOverviewSchema, DashboardSummaryIdentitySchema, DashboardSummaryInvalidationCauseSchema, DashboardSummaryInvalidationSchema, DashboardSummaryProjectionSchema, DashboardSummaryProjectionStateSchema, DashboardTrendsProjectionSchema, DeltaOperationType, DeltaSchema, DeltaSpecSchema, DependencyInfoSchema, DocumentTranslationConfigSchema, DocumentTranslationConfigUpdateSchema, DocumentTranslationDisplayModeSchema, DocumentTranslationGlobalSettingsUpdateSchema, EnvironmentGlobalConfigValueSchema, EnvironmentGlobalFileProjectionDataSchema, EnvironmentGlobalFileProjectionStateSchema, EnvironmentGlobalProjectionDataSchema, EnvironmentGlobalProjectionStateSchema, FILE_PREVIEW_KINDS, GitConfigSchema, GlobalSettingsManager, HOSTED_SHELL_PROTOCOL_VERSION, LEGACY_SOUND_ID_MAP, LOCAL_MODEL_PROFILE_DEFINITIONS, LocalModelAssetLogSchema, LocalModelAssetPlanSnapshotSchema, LocalModelAssetStateSchema, LocalModelDownloadStatusSchema, LocalModelLifecycleFileStateSchema, LocalModelLifecycleGroupStateSchema, LocalModelProfileLoadStateSchema, LocalModelProfileManifestFileSchema, LocalModelProfileManifestGroupSchema, LocalModelProfileManifestSchema, LocalModelProfileStatusSchema, MAX_TRANSLATION_CACHE_ENTRY_LIMIT, MIN_TRANSLATION_CACHE_ENTRY_LIMIT, ManagedLocalCatalogSourceSchema, MarkdownParser, MarkdownReadingPluginRegistry, NOTIFICATION_SOUND_OPTIONS, NOTIFICATION_SOUND_VALUES, NotificationActionSchema, NotificationGroupKeySchema, NotificationPublishInputSchema, NotificationRecordSchema, NotificationSettingsSchema, NotificationSoundSchema, NotificationSourceSchema, OFFICIAL_APP_BASE_URL, OPENSPECUI_DOCUMENT_HOOK_VERSION, OPENSPECUI_RUNTIME_CAPABILITIES, OPENSPECUI_WORKFLOW_HOOK_VERSION, OPENSPEC_SPAWN_MODE_ENV, OPEN_SPEC_DATA_DIRECTORY_NAME, OPEN_SPEC_DATA_HOME_OBSERVATION_TARGETS, OPEN_SPEC_READING_SECTIONS_PROJECTION_ID, OPEN_SPEC_SPEC_PROJECTION_ID, OPSX_AGENT_INVOCATION_MODE_VALUES, OPSX_ALL_WORKFLOWS, OPSX_ARTIFACT_INPUT_ACTIONS, OPSX_CHANGE_INPUT_ACTIONS, OPSX_COMMAND_CAPABLE_WORKFLOWS, OPSX_CORE_PROFILE_WORKFLOWS, OPSX_TEXT_INPUT_ACTIONS, OPSX_WORKFLOW_LABELS, OPSX_WORKFLOW_TO_SKILL_DIR, OPSX_WORKFLOW_TO_SKILL_DIR as TOOL_WORKFLOW_TO_SKILL_DIR, OpenSpecAdapter, OpenSpecCliContractExecutor, OpenSpecDataHomeObserver, OpenSpecUIConfigSchema, OpenSpecUIGlobalSettingsSchema, OpenSpecUIGlobalSettingsUpdateSchema, OpenSpecWatcher, OpsxAgentInvocationModeSchema, OpsxCliEvidenceSchema, OpsxConfigBundleSchema, OpsxConfigSchema, OpsxKernel, OpsxStatusEvidenceSchema, OwnedSpecIdentitySchema, PlanningCliProjectionDataSchema, PlanningCliProjectionSelectorSchema, PlanningCliProjectionStateSchema, PlanningConfigJsonValueSchema, PlanningConfigReferenceSchema, ProjectBindingUpdateSchema, ProjectWatcher, PtyAttachMessageSchema, PtyBellResponseSchema, PtyBufferResponseSchema, PtyClientMessageSchema, PtyCloseMessageSchema, PtyCreateMessageSchema, PtyCreatedResponseSchema, PtyErrorCodeSchema, PtyErrorResponseSchema, PtyExitResponseSchema, PtyInputMessageSchema, PtyListMessageSchema, PtyListResponseSchema, PtyOutputResponseSchema, PtyPlatformSchema, PtyProcessTitleResponseSchema, PtyResizeMessageSchema, PtyServerMessageSchema, PtyTitleResponseSchema, RUNTIME_INVALIDATION_FACETS, ReactiveContext, ReactiveObservationEnvironment, ReactiveState, ReferencedSpecIdentitySchema, RequirementSchema, RuntimeInvalidationIndex, RuntimeRootInvalidationRegistry, SERVE_PRESENTATION_MODES, SERVICE_TRANSLATION_ENGINE_IDS, SILENT_SOUND_ID, ScenarioStepKeywordSchema, ScenarioStepSchema, SchemaArtifactSchema, SchemaDetailSchema, SchemaInfoSchema, SchemaResolutionSchema, ServePresentationModeSchema, ServiceTranslationEngineIdSchema, SoundConfigIdSchema, SoundIdSchema, SpecCatalogSchema, SpecCommandEvidenceSchema, SpecDocumentProjectionSchema, SpecIdentitySchema, SpecSchema, StoreDoctorResultSchema, StoreListResultSchema, StoreMutationLifecycleEventSchema, StoreMutationResultSchema, StoreMutationSchema, StoreMutationStartResponseSchema, TERMINAL_BELL_SOUND_OPTIONS, TERMINAL_BELL_SOUND_VALUES, TERMINAL_COMMAND_FIELD_TYPE_VALUES, TERMINAL_SHELL_QUOTE_STYLE_VALUES, TERMINAL_THEME_MODE_VALUES, TERMINAL_THEME_VALUES, TRANSLATION_CACHE_POLICY_VERSION, TRANSLATION_ENGINE_IDS, TRANSLATION_ENGINE_MANIFESTS, TRANSLATOR_CONTRACT_VERSION, TaskSchema, TemplateContentMapSchema, TemplateContentSchema, TemplatesSchema, TerminalBellSoundSchema, TerminalCommandFieldSchema, TerminalConfigSchema, TerminalControlParser, TerminalCwdTargetSchema, TerminalInvocationSettingsSchema, TerminalNotificationParser, TerminalRendererEngineSchema, TerminalShellProfileSchema, TerminalShellQuoteStyleSchema, TerminalSpawnCommandSchema, TerminalThemeModeSchema, TerminalThemeSchema, TrackedTaskProgressSchema, TranslationCacheEntrySchema, TranslationCacheReadInputSchema, TranslationCacheSettingsSchema, TranslationCacheSettingsUpdateSchema, TranslationCacheStatsSchema, TranslationCacheWriteInputSchema, TranslationDownloadFilePlanSchema, TranslationDownloadGroupPlanSchema, TranslationEngineAssetStateSchema, TranslationEngineAssetStatusSchema, TranslationEngineDependencyStateSchema, TranslationEngineDependencyStatusSchema, TranslationEngineGlobalSettingsSchema, TranslationEngineGlobalSettingsUpdateSchema, TranslationEngineIdSchema, TranslationEngineInstallLogEventSchema, TranslationEngineInstallLogStreamSchema, TranslationEngineLifecycleEventSchema, TranslationEngineLifecycleStatusSchema, TranslationEngineProjectSettingsSchema, TranslationEngineProjectSettingsUpdateSchema, TranslationEngineRuntimeStateSchema, TranslationEngineRuntimeStatusSchema, TranslationLocalCt2SettingsSchema, TranslationLocalCt2SettingsUpdateSchema, TranslationLocalLlamaSettingsSchema, TranslationLocalLlamaSettingsUpdateSchema, TranslationLocalSettingsSchema, TranslationLocalSettingsUpdateSchema, TranslationOpenAISettingsSchema, TranslationOpenAISettingsUpdateSchema, VIRTUAL_PROJECT_DIRNAME, Validator, accessGateFingerprint, acquireWatcher, acquireWatcherRoot, annotateOpenSpecFacts, annotateOpenSpecMarkdown, asEnvUri, buildBackendHealthPayload, buildCliRunnerCandidates, buildEmbeddedUiLaunchUrl, buildHostedLaunchUrl, buildLocalDownloadPlanFromRepositoryFiles, buildLocalDownloadPlanFromRuntimeProfileFiles, buildMarkdownParentMap, buildOpsxEntityDetail, buildRuntimePackageInstallCommand, buildSpecCatalog, builtinOpenSpecReadingPlugin, checkLocalDirectionalModelLanguagePair, classifyStoreCliResult, clearCache, cliProjectionStates, closeAllProjectWatchers, closeAllWatchers, computeEnvUri, constantTimeEqual, contextStorage, createApplyInstructionProgress, createCleanCliEnv, createCliProjectionStateSchema, createDocumentChecklistSummary, createFileChangeObservable, createMarkdownReadingDocument, createMarkdownReadingDocumentFromFacts, createOpenSpecReadingPlugin, createPhysicalReactiveDirectory, createStaticSpecCatalogOwnedProjection, createStaticSpecCatalogReferenceProjection, createStaticSpecCatalogReferenceSource, createToolInitStateProjection, createTrackedTaskProgress, createTranslationEngineLifecycleStatus, customHashFromSoundId, deriveTrackedTaskPhase, detectRuntimePackageManager, generateAccessGateCredential, getActiveWatcherCount, getAllToolIds, getAllTools, getAvailableToolIds, getAvailableTools, getBuiltinSoundUrl, getCacheSize, getConfiguredTools, getDefaultCliCommand, getDefaultCliCommandString, getDefaultGlobalSettingsPath, getDetectedProjectTools, getExternalCodexCommandObservationRoot, getManagedLocalTranslationEngineManifest, getMarkdownAnnotation, getMarkdownAnnotationsForFact, getMarkdownFactSpan, getMarkdownHeadingEnd, getMarkdownHeadingFacts, getNotificationGroupKey, getNotificationGroupLabel, getOpenSpecAnnotation, getOpenSpecAnnotationsForFact, getOpenSpecProjectionAnnotation, getOpenSpecReadingSections, getOpsxEntityMetadataPath, getOpsxEntityRootRelativePath, getProjectWatcher, getRootContextCliSelector, getSpecCatalogEntry, getTerminalCommandDefaultValues, getToolById, getToolInitStates, getTranslationEngineLifecycleMessage, getTranslationEngineManifest, getWatcherRuntimeStatus, groupNotifications, hasCapability, inferFileMime, inferFilePreviewKind, inferLocalDirectionalModelLanguagePair, inspectProjectBinding, isBackendHealthRuntimeMetadata, isBatchTranslationAbort, isDirectionalManagedLocalTranslationEngineId, isGlobPattern, isHostedBackendHealthResponse, isManagedLocalTranslationEngineId, isMarkdownTaskSourcePath, isOpsxCoreWorkflowSelection, isOpsxGlobPattern, isPreviewableFile, isReferencedSpecIdentity, isSupportedEmbeddedUiUrl, isTerminalMutationStatus, isTerminalRendererEngine, isTextLikeFile, isTextLikeMime, isToolConfigured, isTranslationEngineDependencyReady, isTranslationEngineRuntimeReady, isWatcherPoolInitialized, mergeSpecCatalog, normalizeAccessGatePassword, normalizeBatchTranslationError, normalizeEmbeddedUiUrl, normalizeHostedAppBaseUrl, normalizeLegacySoundId, normalizeOpsxEntityPath, openSpecAnnotationRules, opsxGlobToRegex, opsxPathMatchesPattern, parseCliCommand, parseCliCommandResult, parseMarkdownFacts, parseMarkdownTasks, parseOpenSpecMarkdownToSpec, parseOpsxEntityMetadata, parseOpsxSchemaDetail, projectAnnotatedOpenSpecToSpec, projectOpenSpecMarkdown, projectTaskProjectionsFromMarkdownFiles, quoteTerminalShellArg, reactiveExists, reactiveReadDir, reactiveReadFile, reactiveStat, redactSnapshotForPublication, removePhysicalReactivePath, renderTerminalCommandArgs, renderTerminalSpawnCommandLine, requireCanonicalOpenSpecEntityId, requireOpenSpecEntityRelativePath, resolveHostedAppBaseUrl, resolveOpenSpecDataScope, resolveOpenSpecSpawnMode, resolveRootContext, resolveRuntimePackageInstallStrategy, resolveTerminalShellDefaults, runControlledTranslationTask, runPhysicalReactivePathMutation, selectLocalDownloadGroup, shouldShowTranslationEngineInstallGate, snapshotHasAbsolutePath, sniffGlobalCli, sortMarkdownReadingPlugins, soundIdFromCustomHash, specIdentityFromRoute, specIdentityKey, specRoutePath, subscribeWatcherRuntimeStatus, terminalNotificationEventToPublishInput, toCliProjectionCommandEvidence, toCliProjectionFailure, toCliProjectionNotice, toMarkdownFactKind, toOpsxDisplayPath, toPersistedGlobalSettings, toStoreFeatureResult, toggleMarkdownTask, trimMarkdownSlice, updateProjectBindingContent, updateReactiveFileCache, writePhysicalReactiveFile };
|
|
8088
|
+
export { ACCESS_GATE_CREDENTIAL_BYTES, AI_TOOLS, ActiveRootMutationSchema, ActiveRootOfficialConfigSchema, ActiveRootRevisionSchema, ActiveRootStructuredUpdateSchema, AgentDeliveryModeSchema, AgentDeliveryPolicyUpdateSchema, AgentDeliveryProfileSchema, AgentDeliveryWorkflowSchema, ApplyInstructionsContextFilesSchema, ApplyInstructionsProjectionSchema, ApplyInstructionsSchema, ApplyTaskSchema, ArchiveInstructionsSchema, ArtifactInstructionsSchema, ArtifactStatusSchema, BUILTIN_SOUND_IDS, BUILTIN_SOUND_OPTIONS, BUILTIN_TERMINAL_SPAWN_COMMANDS, BatchTranslateEventSchema, BatchTranslateInputSchema, BuiltinSoundIdSchema, CODE_EDITOR_THEME_VALUES, CUSTOM_SOUND_ADD_VALUE, ChangeFileSchema, ChangeSchema, ChangeStatusSchema, CliApplyInstructionsSchema, CliArchiveInstructionsSchema, CliArchiveSchema, CliArtifactInstructionsSchema, CliChangeListSchema, CliContextSchema, CliDiagnosticFailureSchema, CliDiagnosticSchema, CliDoctorReferenceEntrySchema, CliDoctorSchema, CliExecutor, CliJsonValueSchema, CliProjectionCommandError, CliProjectionCommandEvidenceSchema, CliProjectionFailureSchema, CliProjectionInvalidationCauseSchema, CliProjectionNoticeSchema, CliProjectionStateNameSchema, CliReferenceIndexEntrySchema, CliRootSchema, CliRootSourceSchema, CliShowSpecDocumentSchema, CliShowSpecSchema, CliSpecListSchema, CliStoreCleanupSchema, CliStoreDoctorEntrySchema, CliStoreDoctorSchema, CliStoreListSchema, CliStoreMutationSchema, CliStoreSchema, CliStreamTerminationError, CliValidateSchema, CliWorkflowStatusSchema, CodeEditorThemeSchema, ConfigManager, CustomSoundHashSchema, CustomSoundIdSchema, CustomSoundMetadataFileSchema, CustomSoundMetadataSchema, DASHBOARD_METRIC_KEYS, DEFAULT_BELL_SOUND_ID, DEFAULT_CONFIG, DEFAULT_GIT_DIFF_EAGER_LINE_BUDGET, DEFAULT_GLOBAL_SETTINGS, DEFAULT_NOTIFICATION_SOUND_ID, DEFAULT_TERMINAL_DARK_THEME, DEFAULT_TERMINAL_LIGHT_THEME, DEFAULT_TERMINAL_THEME_MODE, DEFAULT_TRANSLATION_CACHE_ENTRY_LIMIT, DEFAULT_TRANSLATION_ENGINE_ID, DOCUMENT_TRANSLATION_DISPLAY_MODES, DashboardConfigSchema, DashboardGitSnapshotSchema, DashboardOverviewSchema, DashboardSummaryIdentitySchema, DashboardSummaryInvalidationCauseSchema, DashboardSummaryInvalidationSchema, DashboardSummaryProjectionSchema, DashboardSummaryProjectionStateSchema, DashboardTrendsProjectionSchema, DeltaOperationType, DeltaSchema, DeltaSpecSchema, DependencyInfoSchema, DocumentTranslationConfigSchema, DocumentTranslationConfigUpdateSchema, DocumentTranslationDisplayModeSchema, DocumentTranslationGlobalSettingsUpdateSchema, EnvironmentDefaultStoreUpdateSchema, EnvironmentGlobalConfigValueSchema, EnvironmentGlobalFileProjectionDataSchema, EnvironmentGlobalFileProjectionStateSchema, EnvironmentGlobalProjectionDataSchema, EnvironmentGlobalProjectionStateSchema, FILE_PREVIEW_KINDS, GitConfigSchema, GlobalSettingsManager, HOSTED_SHELL_PROTOCOL_VERSION, LEGACY_SOUND_ID_MAP, LOCAL_MODEL_PROFILE_DEFINITIONS, LocalModelAssetLogSchema, LocalModelAssetPlanSnapshotSchema, LocalModelAssetStateSchema, LocalModelDownloadStatusSchema, LocalModelLifecycleFileStateSchema, LocalModelLifecycleGroupStateSchema, LocalModelProfileLoadStateSchema, LocalModelProfileManifestFileSchema, LocalModelProfileManifestGroupSchema, LocalModelProfileManifestSchema, LocalModelProfileStatusSchema, MAX_ACTIVE_ROOT_CONTEXT_BYTES, MAX_TRANSLATION_CACHE_ENTRY_LIMIT, MIN_TRANSLATION_CACHE_ENTRY_LIMIT, ManagedLocalCatalogSourceSchema, MarkdownParser, MarkdownReadingPluginRegistry, NOTIFICATION_SOUND_OPTIONS, NOTIFICATION_SOUND_VALUES, NotificationActionSchema, NotificationGroupKeySchema, NotificationPublishInputSchema, NotificationRecordSchema, NotificationSettingsSchema, NotificationSoundSchema, NotificationSourceSchema, OFFICIAL_APP_BASE_URL, OPENSPECUI_DOCUMENT_HOOK_VERSION, OPENSPECUI_RUNTIME_CAPABILITIES, OPENSPECUI_WORKFLOW_HOOK_VERSION, OPENSPEC_SPAWN_MODE_ENV, OPEN_SPEC_DATA_DIRECTORY_NAME, OPEN_SPEC_DATA_HOME_OBSERVATION_TARGETS, OPEN_SPEC_READING_SECTIONS_PROJECTION_ID, OPEN_SPEC_SPEC_PROJECTION_ID, OPSX_AGENT_INVOCATION_MODE_VALUES, OPSX_ALL_WORKFLOWS, OPSX_ARTIFACT_INPUT_ACTIONS, OPSX_CHANGE_INPUT_ACTIONS, OPSX_COMMAND_CAPABLE_WORKFLOWS, OPSX_CORE_PROFILE_WORKFLOWS, OPSX_TEXT_INPUT_ACTIONS, OPSX_WORKFLOW_LABELS, OPSX_WORKFLOW_TO_SKILL_DIR, OPSX_WORKFLOW_TO_SKILL_DIR as TOOL_WORKFLOW_TO_SKILL_DIR, OpenSpecAdapter, OpenSpecCliContractExecutor, OpenSpecDataHomeObserver, OpenSpecUIConfigSchema, OpenSpecUIGlobalSettingsSchema, OpenSpecUIGlobalSettingsUpdateSchema, OpenSpecWatcher, OpsxAgentInvocationModeSchema, OpsxCliEvidenceSchema, OpsxConfigBundleSchema, OpsxConfigSchema, OpsxKernel, OpsxStatusEvidenceSchema, OwnedSpecIdentitySchema, PINNED_AGENT_GENERATOR_VERSION, PlanningCliProjectionDataSchema, PlanningCliProjectionSelectorSchema, PlanningCliProjectionStateSchema, PlanningConfigJsonValueSchema, PlanningConfigReferenceSchema, ProjectBindingUpdateSchema, ProjectWatcher, PtyAttachMessageSchema, PtyBellResponseSchema, PtyBufferResponseSchema, PtyClientMessageSchema, PtyCloseMessageSchema, PtyCreateMessageSchema, PtyCreatedResponseSchema, PtyErrorCodeSchema, PtyErrorResponseSchema, PtyExitResponseSchema, PtyInputMessageSchema, PtyListMessageSchema, PtyListResponseSchema, PtyOutputResponseSchema, PtyPlatformSchema, PtyProcessTitleResponseSchema, PtyResizeMessageSchema, PtyServerMessageSchema, PtyTitleResponseSchema, RUNTIME_INVALIDATION_FACETS, ReactiveContext, ReactiveObservationEnvironment, ReactiveState, ReferencedSpecIdentitySchema, RequirementSchema, RuntimeInvalidationIndex, RuntimeRootInvalidationRegistry, SERVE_PRESENTATION_MODES, SERVICE_TRANSLATION_ENGINE_IDS, SILENT_SOUND_ID, ScenarioStepKeywordSchema, ScenarioStepSchema, SchemaArtifactSchema, SchemaDetailSchema, SchemaInfoSchema, SchemaResolutionSchema, ServePresentationModeSchema, ServiceTranslationEngineIdSchema, SoundConfigIdSchema, SoundIdSchema, SpecCatalogSchema, SpecCommandEvidenceSchema, SpecDocumentProjectionSchema, SpecIdentitySchema, SpecSchema, StoreDoctorResultSchema, StoreListResultSchema, StoreMutationLifecycleEventSchema, StoreMutationResultSchema, StoreMutationSchema, StoreMutationStartResponseSchema, TERMINAL_BELL_SOUND_OPTIONS, TERMINAL_BELL_SOUND_VALUES, TERMINAL_COMMAND_FIELD_TYPE_VALUES, TERMINAL_SHELL_QUOTE_STYLE_VALUES, TERMINAL_THEME_MODE_VALUES, TERMINAL_THEME_VALUES, TRANSLATION_CACHE_POLICY_VERSION, TRANSLATION_ENGINE_IDS, TRANSLATION_ENGINE_MANIFESTS, TRANSLATOR_CONTRACT_VERSION, TaskSchema, TemplateContentMapSchema, TemplateContentSchema, TemplatesSchema, TerminalBellSoundSchema, TerminalCommandFieldSchema, TerminalConfigSchema, TerminalControlParser, TerminalCwdTargetSchema, TerminalInvocationSettingsSchema, TerminalNotificationParser, TerminalRendererEngineSchema, TerminalShellProfileSchema, TerminalShellQuoteStyleSchema, TerminalSpawnCommandSchema, TerminalThemeModeSchema, TerminalThemeSchema, TrackedTaskProgressSchema, TranslationCacheEntrySchema, TranslationCacheReadInputSchema, TranslationCacheSettingsSchema, TranslationCacheSettingsUpdateSchema, TranslationCacheStatsSchema, TranslationCacheWriteInputSchema, TranslationDownloadFilePlanSchema, TranslationDownloadGroupPlanSchema, TranslationEngineAssetStateSchema, TranslationEngineAssetStatusSchema, TranslationEngineDependencyStateSchema, TranslationEngineDependencyStatusSchema, TranslationEngineGlobalSettingsSchema, TranslationEngineGlobalSettingsUpdateSchema, TranslationEngineIdSchema, TranslationEngineInstallLogEventSchema, TranslationEngineInstallLogStreamSchema, TranslationEngineLifecycleEventSchema, TranslationEngineLifecycleStatusSchema, TranslationEngineProjectSettingsSchema, TranslationEngineProjectSettingsUpdateSchema, TranslationEngineRuntimeStateSchema, TranslationEngineRuntimeStatusSchema, TranslationLocalCt2SettingsSchema, TranslationLocalCt2SettingsUpdateSchema, TranslationLocalLlamaSettingsSchema, TranslationLocalLlamaSettingsUpdateSchema, TranslationLocalSettingsSchema, TranslationLocalSettingsUpdateSchema, TranslationOpenAISettingsSchema, TranslationOpenAISettingsUpdateSchema, VIRTUAL_PROJECT_DIRNAME, Validator, accessGateFingerprint, acquireWatcher, acquireWatcherRoot, annotateOpenSpecFacts, annotateOpenSpecMarkdown, applyAgentDeliveryPolicy, asEnvUri, buildBackendHealthPayload, buildCliRunnerCandidates, buildEmbeddedUiLaunchUrl, buildHostedLaunchUrl, buildLocalDownloadPlanFromRepositoryFiles, buildLocalDownloadPlanFromRuntimeProfileFiles, buildMarkdownParentMap, buildOpsxEntityDetail, buildRuntimePackageInstallCommand, buildSpecCatalog, builtinOpenSpecReadingPlugin, checkLocalDirectionalModelLanguagePair, classifyStoreCliResult, clearCache, cliProjectionStates, closeAllProjectWatchers, closeAllWatchers, compareAndWriteAtomicPhysicalReactiveFile, computeEnvUri, constantTimeEqual, contextStorage, createApplyInstructionProgress, createCleanCliEnv, createCliProjectionStateSchema, createDocumentChecklistSummary, createFileChangeObservable, createMarkdownReadingDocument, createMarkdownReadingDocumentFromFacts, createOpenSpecReadingPlugin, createPhysicalReactiveDirectory, createStaticSpecCatalogOwnedProjection, createStaticSpecCatalogReferenceProjection, createStaticSpecCatalogReferenceSource, createToolInitStateProjection, createTrackedTaskProgress, createTranslationEngineLifecycleStatus, customHashFromSoundId, deriveTrackedTaskPhase, detectRuntimePackageManager, generateAccessGateCredential, getActiveWatcherCount, getAllToolIds, getAllTools, getAvailableToolIds, getAvailableTools, getBuiltinSoundUrl, getCacheSize, getConfiguredTools, getDefaultCliCommand, getDefaultCliCommandString, getDefaultGlobalSettingsPath, getDetectedProjectTools, getExternalCodexCommandObservationRoot, getManagedLocalTranslationEngineManifest, getMarkdownAnnotation, getMarkdownAnnotationsForFact, getMarkdownFactSpan, getMarkdownHeadingEnd, getMarkdownHeadingFacts, getNotificationGroupKey, getNotificationGroupLabel, getOpenSpecAnnotation, getOpenSpecAnnotationsForFact, getOpenSpecProjectionAnnotation, getOpenSpecReadingSections, getOpsxEntityMetadataPath, getOpsxEntityRootRelativePath, getProjectWatcher, getRootContextCliSelector, getSpecCatalogEntry, getTerminalCommandDefaultValues, getToolById, getToolInitStates, getTranslationEngineLifecycleMessage, getTranslationEngineManifest, getWatcherRuntimeStatus, groupNotifications, hasCapability, inferFileMime, inferFilePreviewKind, inferLocalDirectionalModelLanguagePair, inspectActiveRootOfficialConfig, inspectEnvironmentDefaultStore, inspectProjectBinding, isBackendHealthRuntimeMetadata, isBatchTranslationAbort, isDirectionalManagedLocalTranslationEngineId, isGlobPattern, isHostedBackendHealthResponse, isManagedLocalTranslationEngineId, isMarkdownTaskSourcePath, isOpsxCoreWorkflowSelection, isOpsxGlobPattern, isPreviewableFile, isReferencedSpecIdentity, isSupportedEmbeddedUiUrl, isTerminalMutationStatus, isTerminalRendererEngine, isTextLikeFile, isTextLikeMime, isToolConfigured, isTranslationEngineDependencyReady, isTranslationEngineRuntimeReady, isWatcherPoolInitialized, loadOpenSpecAgentCommandContents, mergeSpecCatalog, normalizeAccessGatePassword, normalizeAgentDeliveryPolicy, normalizeBatchTranslationError, normalizeEmbeddedUiUrl, normalizeHostedAppBaseUrl, normalizeLegacySoundId, normalizeOpsxEntityPath, openSpecAnnotationRules, opsxGlobToRegex, opsxPathMatchesPattern, parseCliCommand, parseCliCommandResult, parseMarkdownFacts, parseMarkdownTasks, parseOpenSpecMarkdownToSpec, parseOpsxEntityMetadata, parseOpsxSchemaDetail, patchActiveRootOfficialFields, projectAnnotatedOpenSpecToSpec, projectOpenSpecMarkdown, projectTaskProjectionsFromMarkdownFiles, quoteTerminalShellArg, reactiveExists, reactiveReadDir, reactiveReadFile, reactiveStat, redactSnapshotForPublication, removePhysicalReactivePath, renderTerminalCommandArgs, renderTerminalSpawnCommandLine, requireCanonicalOpenSpecEntityId, requireCanonicalOpenSpecSpecId, requireOpenSpecEntityRelativePath, resolveHostedAppBaseUrl, resolveOpenSpecDataScope, resolveOpenSpecSpawnMode, resolveRootContext, resolveRuntimePackageInstallStrategy, resolveTerminalShellDefaults, runControlledTranslationTask, runPhysicalReactivePathMutation, selectLocalDownloadGroup, shouldShowTranslationEngineInstallGate, snapshotHasAbsolutePath, sniffGlobalCli, sortMarkdownReadingPlugins, soundIdFromCustomHash, specDocumentDisplayPath, specIdentityFromRoute, specIdentityKey, specRoutePath, subscribeWatcherRuntimeStatus, terminalNotificationEventToPublishInput, toCliProjectionCommandEvidence, toCliProjectionFailure, toCliProjectionNotice, toMarkdownFactKind, toOpsxDisplayPath, toPersistedGlobalSettings, toStoreFeatureResult, toggleMarkdownTask, trimMarkdownSlice, updateProjectBindingContent, updateReactiveFileCache, validateActiveRootRawYaml, writeAtomicPhysicalReactiveFile, writePhysicalReactiveFile };
|