@openspecui/server 7.0.2 → 9.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/index.mjs +174 -65
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as resolveCt2ModelDownloadPlanFromRepositoryFiles } from "./src-Dh_UAz5C.mjs";
|
|
2
2
|
import { t as resolveGgufModelDownloadPlanFromRepositoryFiles } from "./src-CZfiVL_-.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { ActiveRootMutationSchema, ActiveRootRevisionSchema, AgentDeliveryPolicyUpdateSchema, BatchTranslateInputSchema, CliExecutor, CliProjectionCommandError, CliProjectionNoticeSchema, CodeEditorThemeSchema, ConfigManager, CustomSoundHashSchema, DASHBOARD_METRIC_KEYS, DashboardConfigSchema, DashboardGitSnapshotSchema, DashboardSummaryInvalidationSchema, DashboardSummaryProjectionStateSchema, DashboardTrendsProjectionSchema, DocumentTranslationConfigUpdateSchema, EnvironmentDefaultStoreUpdateSchema, EnvironmentGlobalConfigValueSchema, EnvironmentGlobalFileProjectionDataSchema, EnvironmentGlobalFileProjectionStateSchema, EnvironmentGlobalProjectionDataSchema, EnvironmentGlobalProjectionStateSchema, GitConfigSchema, GlobalSettingsManager, LocalModelAssetStateSchema, LocalModelLifecycleFileStateSchema, LocalModelLifecycleGroupStateSchema, LocalModelProfileManifestSchema, MarkdownParser, NotificationPublishInputSchema, NotificationSettingsSchema, OPENSPECUI_DOCUMENT_HOOK_VERSION, OPENSPECUI_WORKFLOW_HOOK_VERSION, OPSX_ARTIFACT_INPUT_ACTIONS, OPSX_CHANGE_INPUT_ACTIONS, OPSX_COMMAND_CAPABLE_WORKFLOWS, OPSX_CORE_PROFILE_WORKFLOWS, OPSX_TEXT_INPUT_ACTIONS, OpenSpecAdapter, OpenSpecDataHomeObserver, OpenSpecUIGlobalSettingsUpdateSchema, OpenSpecWatcher, OpsxConfigSchema, OpsxKernel, OwnedSpecIdentitySchema, PlanningCliProjectionDataSchema, PlanningCliProjectionSelectorSchema, PlanningCliProjectionStateSchema, ProjectBindingUpdateSchema, ProjectWatcher, PtyClientMessageSchema, RUNTIME_INVALIDATION_FACETS, ReactiveContext, ReactiveObservationEnvironment, ReactiveState, RuntimeInvalidationIndex, RuntimeRootInvalidationRegistry, ServiceTranslationEngineIdSchema, SpecIdentitySchema, StoreDoctorResultSchema, StoreListResultSchema, StoreMutationLifecycleEventSchema, StoreMutationStartResponseSchema, TRANSLATION_ENGINE_MANIFESTS, TerminalConfigSchema, TerminalControlParser, TerminalRendererEngineSchema, TranslationCacheReadInputSchema, TranslationCacheWriteInputSchema, TranslationEngineIdSchema, TranslationEngineLifecycleStatusSchema, acquireWatcher, applyAgentDeliveryPolicy, buildBackendHealthPayload, buildLocalDownloadPlanFromRepositoryFiles, buildRuntimePackageInstallCommand, checkLocalDirectionalModelLanguagePair, classifyStoreCliResult, clearCache, compareAndWriteAtomicPhysicalReactiveFile, computeEnvUri, constantTimeEqual, createCleanCliEnv, createPhysicalReactiveDirectory, createToolInitStateProjection, createTranslationEngineLifecycleStatus, detectRuntimePackageManager, getAllTools, getAvailableTools, getConfiguredTools, getDefaultCliCommandString, getDetectedProjectTools, getExternalAgentSkillsObservationRoots, getExternalCodexCommandObservationRoot, getManagedLocalTranslationEngineManifest, getOpsxEntityRootRelativePath, getRootContextCliSelector, getToolInitStates, getTranslationEngineLifecycleMessage, getWatcherRuntimeStatus, inferFileMime, inferFilePreviewKind, inspectActiveRootOfficialConfig, inspectEnvironmentDefaultStore, inspectProjectBinding, isDirectionalManagedLocalTranslationEngineId, isManagedLocalTranslationEngineId, isTerminalMutationStatus, isTranslationEngineDependencyReady, isTranslationEngineRuntimeReady, loadOpenSpecAgentCommandContents, normalizeAgentDeliveryPolicy, normalizeBatchTranslationError, parseCliCommandResult, parseOpsxEntityMetadata, parseOpsxSchemaDetail, patchActiveRootOfficialFields, reactiveReadFile, reactiveStat, removePhysicalReactivePath, replaceFileAtomically, requireCanonicalOpenSpecEntityId, requireCanonicalOpenSpecSpecId, requireOpenSpecEntityRelativePath, resolveCommandInvocation, resolveOpenSpecDataScope, resolveRootContext, resolveRuntimePackageInstallStrategy, resolveTerminalShellDefaults, runPhysicalReactivePathMutation, selectAgentDeliveryRegistry, selectLocalDownloadGroup, shouldShowTranslationEngineInstallGate, sniffGlobalCli, spawnSafe, subscribeWatcherRuntimeStatus, terminalNotificationEventToPublishInput, terminateChildProcessTree, toCliProjectionCommandEvidence, toCliProjectionFailure, toCliProjectionNotice, toStoreFeatureResult, toggleMarkdownTask, updateProjectBindingContent, updateReactiveFileCache, validateActiveRootRawYaml, writePhysicalReactiveFile } from "@openspecui/core";
|
|
4
4
|
import { basename, dirname, extname, isAbsolute, join, matchesGlob, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { access, copyFile, link, lstat, mkdir, open, readFile, readlink, realpath, rename, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
@@ -33,6 +33,7 @@ import { NodeWorkerSearchProvider } from "@openspecui/search/node";
|
|
|
33
33
|
import * as pty from "@lydell/node-pty";
|
|
34
34
|
import { EventEmitter as EventEmitter$1 } from "events";
|
|
35
35
|
import { HostedCliProjectionNoticeSchema, HostedRootContextProjectionStateSchema, HostedRootContextResolvedStateSchema, HostedStoreContentChangesProjectionStateSchema, HostedStoreContentSpecsProjectionStateSchema, HostedStoreDoctorEnvelopeSchema, HostedStoreDoctorProjectionStateSchema, HostedStoreListEnvelopeSchema, HostedStoreListProjectionStateSchema } from "@openspecui/core/hosted-contract";
|
|
36
|
+
import { deriveOpenSpecCliCapabilities, parseOpenSpecCliVersion } from "@openspecui/core/openspec-compat";
|
|
36
37
|
import { StoreContentChangeListSchema, StoreContentSpecListSchema } from "@openspecui/core/store-content-projection";
|
|
37
38
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
38
39
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
@@ -2983,13 +2984,15 @@ function resolveDefaultServerHostIdentity() {
|
|
|
2983
2984
|
//#endregion
|
|
2984
2985
|
//#region src/agent-delivery-projection-service.ts
|
|
2985
2986
|
/**
|
|
2986
|
-
* Orthogonal intents (
|
|
2987
|
-
* 1. Combine the complete OpenSpec 1.
|
|
2987
|
+
* Orthogonal intents (updated 2026-08-15 Asia/Shanghai):
|
|
2988
|
+
* 1. Combine the complete OpenSpec 1.9 Agent registry with authoritative Environment delivery policy.
|
|
2988
2989
|
* 2. Expose fresh one-shot physical projections through Core `getToolInitStates`.
|
|
2989
2990
|
* 3. Retain reactive physical projections through Core `createToolInitStateProjection`.
|
|
2990
2991
|
* 4. Rebind retained work when Environment policy changes and retire all work on dispose.
|
|
2992
|
+
* 5. Observe user-global skill roots (MiniMax Code) beside the project root and Codex prompt root.
|
|
2991
2993
|
*
|
|
2992
2994
|
* Original request (2026-08-01): "新增 Agent delivery projection service 及 checked tests。"
|
|
2995
|
+
* Original request (2026-08-15): "v9的适配需要同时适配 1.8和1.9。"
|
|
2993
2996
|
*/
|
|
2994
2997
|
/** Raised when the CLI-owned Environment projection cannot provide an executable Agent policy. */
|
|
2995
2998
|
var AgentDeliveryPolicyUnavailableError = class extends Error {
|
|
@@ -3034,8 +3037,8 @@ function cloneCleanup(cleanup) {
|
|
|
3034
3037
|
replacementLabel: cleanup.replacementLabel
|
|
3035
3038
|
};
|
|
3036
3039
|
}
|
|
3037
|
-
function cloneRegistry() {
|
|
3038
|
-
return
|
|
3040
|
+
function cloneRegistry(registry) {
|
|
3041
|
+
return registry.map((tool) => ({
|
|
3039
3042
|
name: tool.name,
|
|
3040
3043
|
value: tool.value,
|
|
3041
3044
|
available: tool.available,
|
|
@@ -3046,6 +3049,9 @@ function cloneRegistry() {
|
|
|
3046
3049
|
...tool.detectionPaths ? { detectionPaths: [...tool.detectionPaths] } : {},
|
|
3047
3050
|
...tool.setupNote !== void 0 ? { setupNote: tool.setupNote } : {},
|
|
3048
3051
|
...tool.aliases ? { aliases: [...tool.aliases] } : {},
|
|
3052
|
+
...tool.legacySkillsDirs ? { legacySkillsDirs: [...tool.legacySkillsDirs] } : {},
|
|
3053
|
+
...tool.globalSkillsDir !== void 0 && tool.globalSkillsDir !== null ? { globalSkillsDir: tool.globalSkillsDir } : {},
|
|
3054
|
+
...tool.requiresIdeRestart !== void 0 ? { requiresIdeRestart: tool.requiresIdeRestart } : {},
|
|
3049
3055
|
...tool.cleanup ? { cleanup: cloneCleanup(tool.cleanup) } : {},
|
|
3050
3056
|
...tool.migrations ? { migrations: tool.migrations.map((migration) => ({ ...migration })) } : {}
|
|
3051
3057
|
}));
|
|
@@ -3067,13 +3073,13 @@ function policyFingerprint(policy) {
|
|
|
3067
3073
|
async function resolveGeneratorEvidence(cliExecutor, cliCommandAuthority, workflows) {
|
|
3068
3074
|
const availability = await cliExecutor.checkAvailability();
|
|
3069
3075
|
return {
|
|
3070
|
-
version: availability.available && availability.version ? availability.version :
|
|
3076
|
+
version: availability.available && availability.version ? availability.version : null,
|
|
3071
3077
|
commandContents: availability.available ? await loadOpenSpecAgentCommandContents(await cliCommandAuthority.getCliCommand(), workflows) : null
|
|
3072
3078
|
};
|
|
3073
3079
|
}
|
|
3074
|
-
function createProjection(policy, states) {
|
|
3080
|
+
function createProjection(policy, states, generatorEvidence) {
|
|
3075
3081
|
return {
|
|
3076
|
-
registry: cloneRegistry(),
|
|
3082
|
+
registry: cloneRegistry(selectAgentDeliveryRegistry(generatorEvidence.version)),
|
|
3077
3083
|
policy: {
|
|
3078
3084
|
profile: policy.profile,
|
|
3079
3085
|
delivery: policy.delivery,
|
|
@@ -3147,7 +3153,7 @@ var RetainedAgentDeliveryProjection = class {
|
|
|
3147
3153
|
});
|
|
3148
3154
|
}
|
|
3149
3155
|
startPhysicalProjection(policy, generatorEvidence, force) {
|
|
3150
|
-
const fingerprint = `${policyFingerprint(policy)}:${generatorEvidence.version}`;
|
|
3156
|
+
const fingerprint = `${policyFingerprint(policy)}:${generatorEvidence.version ?? "no-cli"}`;
|
|
3151
3157
|
if (!force && this.physicalController && fingerprint === this.currentPolicyFingerprint) return;
|
|
3152
3158
|
this.stopPhysicalProjection();
|
|
3153
3159
|
this.currentPolicyFingerprint = fingerprint;
|
|
@@ -3157,8 +3163,10 @@ var RetainedAgentDeliveryProjection = class {
|
|
|
3157
3163
|
const context = new ReactiveContext();
|
|
3158
3164
|
const projectToolInitStates = createToolInitStateProjection(this.options.projectDir, {
|
|
3159
3165
|
...policy,
|
|
3160
|
-
generatorVersion: generatorEvidence.version,
|
|
3161
|
-
commandContents: generatorEvidence.commandContents
|
|
3166
|
+
generatorVersion: generatorEvidence.version ?? void 0,
|
|
3167
|
+
commandContents: generatorEvidence.commandContents?.catalog ?? null,
|
|
3168
|
+
unavailableCommandTools: generatorEvidence.commandContents?.unavailableTools ?? null,
|
|
3169
|
+
registry: selectAgentDeliveryRegistry(generatorEvidence.version)
|
|
3162
3170
|
});
|
|
3163
3171
|
(async () => {
|
|
3164
3172
|
try {
|
|
@@ -3166,7 +3174,7 @@ var RetainedAgentDeliveryProjection = class {
|
|
|
3166
3174
|
if (this.disposed || controller.signal.aborted || generation !== this.physicalGeneration) return;
|
|
3167
3175
|
this.listener({
|
|
3168
3176
|
type: "snapshot",
|
|
3169
|
-
projection: createProjection(policy, states)
|
|
3177
|
+
projection: createProjection(policy, states, generatorEvidence)
|
|
3170
3178
|
});
|
|
3171
3179
|
}
|
|
3172
3180
|
} catch (cause) {
|
|
@@ -3203,11 +3211,13 @@ var AgentDeliveryProjectionService = class {
|
|
|
3203
3211
|
const generatorEvidence = await resolveGeneratorEvidence(this.options.cliExecutor, this.options.cliCommandAuthority, policy.workflows);
|
|
3204
3212
|
const states = await getToolInitStates(this.options.projectDir, {
|
|
3205
3213
|
...policy,
|
|
3206
|
-
generatorVersion: generatorEvidence.version,
|
|
3207
|
-
commandContents: generatorEvidence.commandContents
|
|
3214
|
+
generatorVersion: generatorEvidence.version ?? void 0,
|
|
3215
|
+
commandContents: generatorEvidence.commandContents?.catalog ?? null,
|
|
3216
|
+
unavailableCommandTools: generatorEvidence.commandContents?.unavailableTools ?? null,
|
|
3217
|
+
registry: selectAgentDeliveryRegistry(generatorEvidence.version)
|
|
3208
3218
|
});
|
|
3209
3219
|
this.assertActive();
|
|
3210
|
-
return createProjection(policy, states);
|
|
3220
|
+
return createProjection(policy, states, generatorEvidence);
|
|
3211
3221
|
}
|
|
3212
3222
|
/** Retain Environment policy and physical Agent artifact observation until unsubscribed. */
|
|
3213
3223
|
subscribe(listener) {
|
|
@@ -3249,6 +3259,7 @@ var AgentDeliveryProjectionService = class {
|
|
|
3249
3259
|
try {
|
|
3250
3260
|
releases.push(await this.options.observationEnvironment.acquireRoot(this.options.projectDir));
|
|
3251
3261
|
releases.push(await this.options.observationEnvironment.acquireRoot(getExternalCodexCommandObservationRoot()));
|
|
3262
|
+
for (const globalSkillsRoot of getExternalAgentSkillsObservationRoots()) releases.push(await this.options.observationEnvironment.acquireRoot(globalSkillsRoot));
|
|
3252
3263
|
if (this.disposed) {
|
|
3253
3264
|
await Promise.all(releases.map((release) => release()));
|
|
3254
3265
|
return;
|
|
@@ -4116,13 +4127,26 @@ var ChangesProjectionService = class {
|
|
|
4116
4127
|
load: async (context) => {
|
|
4117
4128
|
context.reportStage("root-ready");
|
|
4118
4129
|
const ids = await this.options.adapter.listChanges();
|
|
4130
|
+
const cliEntries = await this.options.adapter.readCliChangeListEntries?.() ?? /* @__PURE__ */ new Map();
|
|
4119
4131
|
const rows = [];
|
|
4120
4132
|
const errors = [];
|
|
4121
4133
|
const total = ids.length;
|
|
4122
4134
|
for (const [index, id] of ids.entries()) {
|
|
4123
4135
|
if (context.signal.aborted) throw new DOMException("Change projection was cancelled.", "AbortError");
|
|
4124
4136
|
try {
|
|
4125
|
-
const
|
|
4137
|
+
const meta = await this.options.adapter.readChangeMeta(id);
|
|
4138
|
+
const entry = cliEntries.get(id);
|
|
4139
|
+
const row = entry ? {
|
|
4140
|
+
...meta,
|
|
4141
|
+
cliTaskSummary: {
|
|
4142
|
+
completedTasks: entry.completedTasks,
|
|
4143
|
+
totalTasks: entry.totalTasks,
|
|
4144
|
+
status: entry.status
|
|
4145
|
+
}
|
|
4146
|
+
} : {
|
|
4147
|
+
...meta,
|
|
4148
|
+
cliTaskSummary: meta.cliTaskSummary ?? null
|
|
4149
|
+
};
|
|
4126
4150
|
rows.push(row);
|
|
4127
4151
|
context.emitBatch({
|
|
4128
4152
|
rows: [row],
|
|
@@ -9340,17 +9364,26 @@ function selectRecentDashboardArchives(items, limit = DASHBOARD_RECENT_LIST_LIMI
|
|
|
9340
9364
|
//#region src/dashboard-summary.ts
|
|
9341
9365
|
/** Read the objective files behind Dashboard Summary without invoking Git or workflow commands. */
|
|
9342
9366
|
async function loadDashboardPlanningFacts(ctx) {
|
|
9343
|
-
const [specMetas, changeMetas, archiveMetas] = await Promise.all([
|
|
9367
|
+
const [specMetas, changeMetas, archiveMetas, cliEntries] = await Promise.all([
|
|
9344
9368
|
ctx.adapter.listSpecsWithMeta(),
|
|
9345
9369
|
ctx.adapter.listChangesWithMeta(),
|
|
9346
|
-
ctx.adapter.listArchivedChangesWithMeta()
|
|
9370
|
+
ctx.adapter.listArchivedChangesWithMeta(),
|
|
9371
|
+
ctx.readCliChangeListEntries?.().catch(() => /* @__PURE__ */ new Map()) ?? Promise.resolve(/* @__PURE__ */ new Map())
|
|
9347
9372
|
]);
|
|
9348
|
-
const allActiveChanges = changeMetas.map((changeMeta) =>
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9373
|
+
const allActiveChanges = changeMetas.map((changeMeta) => {
|
|
9374
|
+
const entry = cliEntries.get(changeMeta.id);
|
|
9375
|
+
return {
|
|
9376
|
+
id: changeMeta.id,
|
|
9377
|
+
name: changeMeta.name ?? changeMeta.id,
|
|
9378
|
+
trackedTaskProgress: changeMeta.trackedTaskProgress,
|
|
9379
|
+
cliTaskSummary: entry ? {
|
|
9380
|
+
completedTasks: entry.completedTasks,
|
|
9381
|
+
totalTasks: entry.totalTasks,
|
|
9382
|
+
status: entry.status
|
|
9383
|
+
} : changeMeta.cliTaskSummary,
|
|
9384
|
+
updatedAt: changeMeta.updatedAt
|
|
9385
|
+
};
|
|
9386
|
+
});
|
|
9354
9387
|
return {
|
|
9355
9388
|
specMetas,
|
|
9356
9389
|
archiveMetas,
|
|
@@ -10881,6 +10914,18 @@ var PlanningRootUnavailableError = class extends Error {
|
|
|
10881
10914
|
}
|
|
10882
10915
|
};
|
|
10883
10916
|
/** Serialized deep owner for one replaceable Planning-root service record. */
|
|
10917
|
+
/** Read CLI Change-list task facts once per call; failures degrade to an empty index. */
|
|
10918
|
+
function readCliChangeListEntriesFor(service) {
|
|
10919
|
+
return async () => {
|
|
10920
|
+
try {
|
|
10921
|
+
const data = await service.getCurrent({ kind: "opsx-change-list" });
|
|
10922
|
+
if (data.kind !== "opsx-change-list") return /* @__PURE__ */ new Map();
|
|
10923
|
+
return new Map(data.entries.map((entry) => [entry.name, entry]));
|
|
10924
|
+
} catch {
|
|
10925
|
+
return /* @__PURE__ */ new Map();
|
|
10926
|
+
}
|
|
10927
|
+
};
|
|
10928
|
+
}
|
|
10884
10929
|
var PlanningRootServiceManager = class {
|
|
10885
10930
|
activeRecord = null;
|
|
10886
10931
|
currentRootContextSnapshot = null;
|
|
@@ -10956,7 +11001,10 @@ var PlanningRootServiceManager = class {
|
|
|
10956
11001
|
},
|
|
10957
11002
|
codeGitBindingToken: this.options.codeBinding.bindingToken,
|
|
10958
11003
|
loaders: {
|
|
10959
|
-
loadSummary: () => loadDashboardSummary({
|
|
11004
|
+
loadSummary: () => loadDashboardSummary({
|
|
11005
|
+
adapter,
|
|
11006
|
+
readCliChangeListEntries: readCliChangeListEntriesFor(planningCliProjectionService)
|
|
11007
|
+
}),
|
|
10960
11008
|
loadTrends: () => loadDashboardTrends({
|
|
10961
11009
|
adapter,
|
|
10962
11010
|
configManager: this.options.configManager
|
|
@@ -10967,16 +11015,6 @@ var PlanningRootServiceManager = class {
|
|
|
10967
11015
|
}, "projection-work", signal)
|
|
10968
11016
|
}
|
|
10969
11017
|
});
|
|
10970
|
-
const changesProjectionService = new ChangesProjectionService({
|
|
10971
|
-
workOwner: this.changesProjectionWorkOwner,
|
|
10972
|
-
root: {
|
|
10973
|
-
path: projectDir,
|
|
10974
|
-
source: planningRoot.source,
|
|
10975
|
-
storeSelector: rootCliSelector.store ?? null,
|
|
10976
|
-
generation: gitBindingToken
|
|
10977
|
-
},
|
|
10978
|
-
adapter
|
|
10979
|
-
});
|
|
10980
11018
|
const planningCliProjectionService = new PlanningCliProjectionService({
|
|
10981
11019
|
rootContext: rootContextValue,
|
|
10982
11020
|
gitBindingToken,
|
|
@@ -10987,6 +11025,28 @@ var PlanningRootServiceManager = class {
|
|
|
10987
11025
|
storeObservation: this.options.storeObservation,
|
|
10988
11026
|
workOwner: this.planningCliProjectionWorkOwner
|
|
10989
11027
|
});
|
|
11028
|
+
const changesProjectionService = new ChangesProjectionService({
|
|
11029
|
+
workOwner: this.changesProjectionWorkOwner,
|
|
11030
|
+
root: {
|
|
11031
|
+
path: projectDir,
|
|
11032
|
+
source: planningRoot.source,
|
|
11033
|
+
storeSelector: rootCliSelector.store ?? null,
|
|
11034
|
+
generation: gitBindingToken
|
|
11035
|
+
},
|
|
11036
|
+
adapter: {
|
|
11037
|
+
listChanges: () => adapter.listChanges(),
|
|
11038
|
+
readChangeMeta: (id) => adapter.readChangeMeta(id),
|
|
11039
|
+
readCliChangeListEntries: async () => {
|
|
11040
|
+
try {
|
|
11041
|
+
const data = await planningCliProjectionService.getCurrent({ kind: "opsx-change-list" });
|
|
11042
|
+
if (data.kind !== "opsx-change-list") return /* @__PURE__ */ new Map();
|
|
11043
|
+
return new Map(data.entries.map((entry) => [entry.name, entry]));
|
|
11044
|
+
} catch {
|
|
11045
|
+
return /* @__PURE__ */ new Map();
|
|
11046
|
+
}
|
|
11047
|
+
}
|
|
11048
|
+
}
|
|
11049
|
+
});
|
|
10990
11050
|
const filePreviewService = new FilePreviewService(projectDir, this.options.previewAssetsDir);
|
|
10991
11051
|
const schemaMutationService = new SchemaMutationService({
|
|
10992
11052
|
planningRoot: projectDir,
|
|
@@ -14703,7 +14763,16 @@ const changeProjectionDataSchema = z.object({
|
|
|
14703
14763
|
remaining: z.number().int().nonnegative()
|
|
14704
14764
|
}),
|
|
14705
14765
|
createdAt: z.number(),
|
|
14706
|
-
updatedAt: z.number()
|
|
14766
|
+
updatedAt: z.number(),
|
|
14767
|
+
cliTaskSummary: z.object({
|
|
14768
|
+
completedTasks: z.number().int().nonnegative(),
|
|
14769
|
+
totalTasks: z.number().int().nonnegative(),
|
|
14770
|
+
status: z.enum([
|
|
14771
|
+
"no-tasks",
|
|
14772
|
+
"complete",
|
|
14773
|
+
"in-progress"
|
|
14774
|
+
])
|
|
14775
|
+
}).nullable()
|
|
14707
14776
|
})),
|
|
14708
14777
|
errors: z.array(changeProjectionRowErrorSchema)
|
|
14709
14778
|
});
|
|
@@ -15345,12 +15414,31 @@ const specRouter = router({
|
|
|
15345
15414
|
/**
|
|
15346
15415
|
* Change router - change proposal operations
|
|
15347
15416
|
*/
|
|
15417
|
+
/**
|
|
15418
|
+
* Join the CLI-owned Change-list task facts onto adapter ChangeMeta rows. The CLI entry is
|
|
15419
|
+
* the task-count authority (`openspec list` reports the same checkbox semantics as Apply);
|
|
15420
|
+
* rows the CLI did not list keep a null summary rather than a UI-side recomputation.
|
|
15421
|
+
*/
|
|
15422
|
+
async function listChangesWithCliTaskSummary(ctx, adapter) {
|
|
15423
|
+
const [rows, cliList] = await Promise.all([adapter.listChangesWithMeta(), runPlanningRootRead(ctx, ({ planningCliProjectionService }) => planningCliProjectionService.getCurrent({ kind: "opsx-change-list" })).then((data) => data.kind === "opsx-change-list" ? new Map(data.entries.map((entry) => [entry.name, entry])) : /* @__PURE__ */ new Map(), () => /* @__PURE__ */ new Map())]);
|
|
15424
|
+
return rows.map((row) => {
|
|
15425
|
+
const entry = cliList.get(row.id);
|
|
15426
|
+
return entry ? {
|
|
15427
|
+
...row,
|
|
15428
|
+
cliTaskSummary: {
|
|
15429
|
+
completedTasks: entry.completedTasks,
|
|
15430
|
+
totalTasks: entry.totalTasks,
|
|
15431
|
+
status: entry.status
|
|
15432
|
+
}
|
|
15433
|
+
} : row;
|
|
15434
|
+
});
|
|
15435
|
+
}
|
|
15348
15436
|
const changeRouter = router({
|
|
15349
15437
|
list: publicProcedure.query(async ({ ctx }) => {
|
|
15350
15438
|
return runPlanningRootRead(ctx, ({ adapter }) => adapter.listChanges());
|
|
15351
15439
|
}),
|
|
15352
15440
|
listWithMeta: publicProcedure.query(async ({ ctx }) => {
|
|
15353
|
-
return runPlanningRootRead(ctx, ({ adapter }) => adapter
|
|
15441
|
+
return runPlanningRootRead(ctx, ({ adapter }) => listChangesWithCliTaskSummary(ctx, adapter));
|
|
15354
15442
|
}),
|
|
15355
15443
|
listArchived: publicProcedure.query(async ({ ctx }) => {
|
|
15356
15444
|
return runPlanningRootRead(ctx, ({ adapter }) => adapter.listArchivedChanges());
|
|
@@ -15395,7 +15483,7 @@ const changeRouter = router({
|
|
|
15395
15483
|
return { success: true };
|
|
15396
15484
|
}),
|
|
15397
15485
|
subscribe: publicProcedure.subscription(({ ctx }) => {
|
|
15398
|
-
return createPlanningRootSubscription(ctx, ({ adapter }) => adapter
|
|
15486
|
+
return createPlanningRootSubscription(ctx, ({ adapter }) => listChangesWithCliTaskSummary(ctx, adapter));
|
|
15399
15487
|
}),
|
|
15400
15488
|
subscribeBatches: publicProcedure.subscription(({ ctx }) => createPlanningRootProjectionWorkSubscription(ctx, (services, listener) => services.changesProjectionService.subscribe(listener), (event) => changeProjectionEventSchema().parse(event))),
|
|
15401
15489
|
subscribeFiles: publicProcedure.input(z.object({ id: z.string() })).subscription(({ ctx, input }) => {
|
|
@@ -15673,32 +15761,45 @@ const cliRouter = router({
|
|
|
15673
15761
|
subscribeConfiguredTools: publicProcedure.subscription(({ ctx }) => {
|
|
15674
15762
|
return createReactiveSubscription(() => getConfiguredTools(ctx.projectDir));
|
|
15675
15763
|
}),
|
|
15676
|
-
validate: publicProcedure.input(z.discriminatedUnion("kind", [
|
|
15677
|
-
|
|
15678
|
-
|
|
15679
|
-
|
|
15680
|
-
|
|
15681
|
-
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
"
|
|
15685
|
-
|
|
15686
|
-
|
|
15687
|
-
|
|
15688
|
-
|
|
15689
|
-
|
|
15690
|
-
|
|
15691
|
-
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
|
|
15699
|
-
|
|
15700
|
-
|
|
15701
|
-
|
|
15764
|
+
validate: publicProcedure.input(z.discriminatedUnion("kind", [
|
|
15765
|
+
z.object({
|
|
15766
|
+
kind: z.literal("item"),
|
|
15767
|
+
id: z.string().min(1),
|
|
15768
|
+
type: z.enum(["spec", "change"]).optional(),
|
|
15769
|
+
strict: z.boolean().optional()
|
|
15770
|
+
}),
|
|
15771
|
+
z.object({
|
|
15772
|
+
kind: z.literal("scope"),
|
|
15773
|
+
scope: z.enum([
|
|
15774
|
+
"all",
|
|
15775
|
+
"changes",
|
|
15776
|
+
"specs"
|
|
15777
|
+
]),
|
|
15778
|
+
strict: z.boolean().optional()
|
|
15779
|
+
}),
|
|
15780
|
+
z.object({ kind: z.literal("archived") })
|
|
15781
|
+
])).mutation(async ({ ctx, input }) => {
|
|
15782
|
+
return runPlanningRoot(ctx, ({ rootContext }) => {
|
|
15783
|
+
if (input.kind === "archived") {
|
|
15784
|
+
const cli = rootContext.cli;
|
|
15785
|
+
if (!deriveOpenSpecCliCapabilities(cli.available ? parseOpenSpecCliVersion(cli.version) : null).archivedValidation) throw new TRPCError({
|
|
15786
|
+
code: "PRECONDITION_FAILED",
|
|
15787
|
+
message: "Archived task validation requires the detected OpenSpec CLI to declare the 1.9 archived-validation capability."
|
|
15788
|
+
});
|
|
15789
|
+
}
|
|
15790
|
+
return ctx.cliExecutor.contracts.validate({
|
|
15791
|
+
target: input.kind === "item" ? {
|
|
15792
|
+
kind: "item",
|
|
15793
|
+
id: input.id,
|
|
15794
|
+
type: input.type
|
|
15795
|
+
} : input.kind === "scope" ? {
|
|
15796
|
+
kind: "scope",
|
|
15797
|
+
scope: input.scope
|
|
15798
|
+
} : { kind: "archived" },
|
|
15799
|
+
strict: input.kind === "archived" ? void 0 : input.strict,
|
|
15800
|
+
...getRootContextCliSelector(rootContext)
|
|
15801
|
+
});
|
|
15802
|
+
});
|
|
15702
15803
|
}),
|
|
15703
15804
|
validateStream: publicProcedure.input(z.object({
|
|
15704
15805
|
type: z.enum(["spec", "change"]).optional(),
|
|
@@ -15752,7 +15853,7 @@ const cliRouter = router({
|
|
|
15752
15853
|
})
|
|
15753
15854
|
});
|
|
15754
15855
|
/** Config-owned Agent registry, policy, physical inventory, and CLI mutation boundary. */
|
|
15755
|
-
const agentIntegrationToolIdSchema = z.string().min(1).refine((toolId) => getAvailableTools().some((tool) => tool.value === toolId), "Agent tool must be an available OpenSpec 1.
|
|
15856
|
+
const agentIntegrationToolIdSchema = z.string().min(1).refine((toolId) => getAvailableTools().some((tool) => tool.value === toolId), "Agent tool must be an available OpenSpec 1.9 registry id.");
|
|
15756
15857
|
const agentIntegrationsRouter = router({
|
|
15757
15858
|
get: publicProcedure.query(({ ctx }) => ctx.agentDeliveryProjectionService.getCurrent()),
|
|
15758
15859
|
refresh: publicProcedure.query(({ ctx }) => ctx.agentDeliveryProjectionService.refresh()),
|
|
@@ -15780,6 +15881,14 @@ const agentIntegrationsRouter = router({
|
|
|
15780
15881
|
})).subscription(({ ctx, input }) => {
|
|
15781
15882
|
return createCliStreamObservable(async (onEvent) => {
|
|
15782
15883
|
const projection = await ctx.agentDeliveryProjectionService.getCurrent();
|
|
15884
|
+
if (Array.isArray(input.tools)) {
|
|
15885
|
+
const offered = new Set(projection.registry.map((tool) => tool.value));
|
|
15886
|
+
const unavailable = input.tools.filter((toolId) => !offered.has(toolId));
|
|
15887
|
+
if (unavailable.length > 0) throw new TRPCError({
|
|
15888
|
+
code: "PRECONDITION_FAILED",
|
|
15889
|
+
message: `Agent tool(s) unavailable on the admitted OpenSpec CLI line: ${unavailable.join(", ")}.`
|
|
15890
|
+
});
|
|
15891
|
+
}
|
|
15783
15892
|
return streamOpenSpecCliMutation(ctx, ["init"], (mutationEvent) => ctx.cliExecutor.initStream({
|
|
15784
15893
|
tools: input.tools,
|
|
15785
15894
|
profile: projection.policy.profile,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openspecui/server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"exports": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"@hono/node-server": "^1.14.1",
|
|
34
34
|
"@huggingface/hub": "^2.12.0",
|
|
35
35
|
"@lydell/node-pty": "^1.1.0",
|
|
36
|
-
"@openspecui/core": "
|
|
37
|
-
"@openspecui/search": "
|
|
36
|
+
"@openspecui/core": "9.0.0",
|
|
37
|
+
"@openspecui/search": "9.0.0",
|
|
38
38
|
"@opentelemetry/api": "^1.9.1",
|
|
39
39
|
"@opentelemetry/exporter-trace-otlp-http": "^0.221.0",
|
|
40
40
|
"@opentelemetry/sdk-node": "^0.221.0",
|