@openspecui/core 7.0.1 → 7.0.2
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-DxRGkvOp.d.mts → active-root-config-BHgXdX6b.d.mts} +9 -9
- package/dist/active-root-config.d.mts +4 -4
- package/dist/app-daemon-control.d.mts +18 -18
- package/dist/{cli-projection-BeBPIxhK.d.mts → cli-projection-Um81AQW5.d.mts} +9 -9
- package/dist/cli-projection.d.mts +4 -4
- package/dist/{dashboard-summary-transport-CXGjAcQZ.d.mts → dashboard-summary-transport-BJBod4rO.d.mts} +2847 -2805
- package/dist/dashboard-summary-transport.d.mts +17 -17
- package/dist/hosted-app.d.mts +17 -17
- package/dist/hosted-contract.d.mts +17 -17
- package/dist/{index-CkwSp1WZ.d.mts → index-CYFOH_f8.d.mts} +45 -45
- package/dist/index.d.mts +18 -18
- package/dist/index.mjs +370 -67
- package/dist/{local-download-profiles-DYeaRK_E.d.mts → local-download-profiles-BQLPhuE0.d.mts} +1 -1
- package/dist/local-download-profiles.d.mts +2 -2
- package/dist/{notifications-B43aFxw9.d.mts → notifications-BIs3J3BY.d.mts} +1 -1
- package/dist/{notifications-Cy74GVN7.mjs → notifications-VHUMI-qG.mjs} +1 -1
- package/dist/notifications.d.mts +2 -2
- package/dist/notifications.mjs +2 -2
- package/dist/{openspec-projection-NGJSLiSk.d.mts → openspec-projection-_1NeavJP.d.mts} +1 -1
- package/dist/openspec-projection.d.mts +2 -2
- package/dist/{opsx-entity-5ATD3peX.d.mts → opsx-entity-DZ7onDWC.d.mts} +2 -2
- package/dist/opsx-entity.d.mts +6 -6
- package/dist/{opsx-schema-detail-Cu7mIrGm.d.mts → opsx-schema-detail-D2RnlxSg.d.mts} +2 -2
- package/dist/opsx-schema-detail.d.mts +7 -7
- package/dist/{opsx-types-DJzyK1W7.d.mts → opsx-types-Ch6juiWL.d.mts} +179 -179
- package/dist/planning-cli-projection.d.mts +17 -17
- package/dist/{schemas-kuds0tNv.d.mts → schemas-zh0_vzYQ.d.mts} +128 -128
- package/dist/{sounds-vwRCMSzL.d.mts → sounds-Bb_3aeJJ.d.mts} +4 -4
- package/dist/sounds.d.mts +1 -1
- package/dist/spec-catalog.d.mts +17 -17
- package/dist/{store-mutation-protocol-D9IK_wrr.d.mts → store-mutation-protocol-BbgWMJVK.d.mts} +24 -24
- package/dist/store-mutation-protocol.d.mts +1 -1
- package/dist/{store-types-DxvwR0sj.d.mts → store-types-CF7_LsVL.d.mts} +1 -1
- package/dist/store-types.d.mts +4 -4
- package/dist/task-progress.d.mts +5 -5
- package/dist/{terminal-audio-BcjP_os4.d.mts → terminal-audio-GuG0qiiI.d.mts} +1 -1
- package/dist/terminal-audio.d.mts +2 -2
- package/dist/{terminal-control-c6oS-lFb.mjs → terminal-control-CdPuYwwU.mjs} +19 -1
- package/dist/terminal-control.d.mts +2 -2
- package/dist/terminal-control.mjs +1 -1
- package/dist/{terminal-invocation-BW357tO1.d.mts → terminal-invocation-Dx1qfSKb.d.mts} +68 -68
- package/dist/terminal-invocation.d.mts +1 -1
- package/dist/{translator-YggUX3F7.d.mts → translator-Cwaf_pXN.d.mts} +67 -67
- package/dist/translator.d.mts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -13,8 +13,8 @@ import { $ as shouldShowTranslationEngineInstallGate, A as TranslationEngineIdSc
|
|
|
13
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
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
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-
|
|
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-
|
|
16
|
+
import { n as terminalNotificationEventToPublishInput, t as TerminalControlParser } from "./terminal-control-CdPuYwwU.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-VHUMI-qG.mjs";
|
|
18
18
|
import { n as TERMINAL_BELL_SOUND_VALUES, r as TerminalBellSoundSchema, t as TERMINAL_BELL_SOUND_OPTIONS } from "./terminal-audio-DeubAfFC.mjs";
|
|
19
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
20
|
import { i as selectLocalDownloadGroup, n as buildLocalDownloadPlanFromRepositoryFiles, r as buildLocalDownloadPlanFromRuntimeProfileFiles, t as LOCAL_MODEL_PROFILE_DEFINITIONS } from "./local-download-profiles-h9lUTXr-.mjs";
|
|
@@ -34,7 +34,8 @@ import { dirname, join } from "path";
|
|
|
34
34
|
import { isMap, parseDocument } from "yaml";
|
|
35
35
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
36
36
|
import { access, lstat, mkdir as mkdir$1, open, readFile, readdir, realpath, rename, rm, stat, writeFile as writeFile$1 } from "node:fs/promises";
|
|
37
|
-
import { basename, dirname as dirname$1, isAbsolute, join as join$1, matchesGlob, posix, relative, resolve, sep, win32 } from "node:path";
|
|
37
|
+
import { basename, dirname as dirname$1, extname, isAbsolute, join as join$1, matchesGlob, posix, relative, resolve, sep, win32 } from "node:path";
|
|
38
|
+
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
38
39
|
import { existsSync, lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
39
40
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
40
41
|
import { z } from "zod";
|
|
@@ -42,12 +43,14 @@ import { EventEmitter } from "events";
|
|
|
42
43
|
import { watch } from "fs";
|
|
43
44
|
import { exec, execFile } from "child_process";
|
|
44
45
|
import { promisify } from "util";
|
|
45
|
-
import
|
|
46
|
+
import { pathToFileURL } from "node:url";
|
|
47
|
+
import { execFile as execFile$1, spawn, spawnSync } from "node:child_process";
|
|
48
|
+
import process$1 from "node:process";
|
|
49
|
+
import { promisify as promisify$1 } from "node:util";
|
|
46
50
|
import { homedir, loadavg, platform } from "node:os";
|
|
47
51
|
import { context, trace } from "@opentelemetry/api";
|
|
48
52
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
49
53
|
import { Worker } from "node:worker_threads";
|
|
50
|
-
import { pathToFileURL } from "node:url";
|
|
51
54
|
|
|
52
55
|
//#region src/parser.ts
|
|
53
56
|
const SCENARIO_STEP_PATTERN = new RegExp(`^\\s*[-*+]\\s+(?:\\*\\*)?(${[
|
|
@@ -540,7 +543,7 @@ var ProjectWatcher = class {
|
|
|
540
543
|
matchPath(event, sub) {
|
|
541
544
|
const eventPath = event.path;
|
|
542
545
|
if (sub.watchAncestorsWhileMissing && sub.awaitingPathCreation && isStrictAncestorPath(eventPath, sub.path)) return true;
|
|
543
|
-
if (sub.watchChildren) return eventPath
|
|
546
|
+
if (sub.watchChildren) return eventPath === sub.path || isStrictAncestorPath(sub.path, eventPath);
|
|
544
547
|
else {
|
|
545
548
|
const eventDir = dirname$1(eventPath);
|
|
546
549
|
return eventPath === sub.path || eventDir === sub.path;
|
|
@@ -756,13 +759,14 @@ async function closeAllProjectWatchers() {
|
|
|
756
759
|
//#endregion
|
|
757
760
|
//#region src/reactive-fs/watcher-pool.ts
|
|
758
761
|
/**
|
|
759
|
-
* Orthogonal intents (updated 2026-07
|
|
762
|
+
* Orthogonal intents (updated 2026-08-07 Asia/Shanghai):
|
|
760
763
|
* 1. Own a reference-counted dynamic set of physical watcher roots, including missing logical roots
|
|
761
764
|
* through their nearest existing ancestor.
|
|
762
765
|
* 2. Bind shared path subscriptions to the deepest active containing root.
|
|
763
766
|
* 3. Rebind pending subscriptions when roots appear, disappear, or recover.
|
|
764
767
|
* 4. Expose aggregate and per-root runtime status for server diagnostics.
|
|
765
|
-
* 5. Keep missing-path ancestor settlement explicit in subscription identity and
|
|
768
|
+
* 5. Keep missing-path ancestor settlement explicit in subscription identity and retire every
|
|
769
|
+
* physical subscription plus cached ProjectWatcher during full teardown.
|
|
766
770
|
*
|
|
767
771
|
* Original request (2026-07-15): "响应式内核要观察 data home、Store roots 和 connected project roots。"
|
|
768
772
|
* Remote CI fixed point (2026-07-28): data-home Schema creation may arrive as an ancestor event on Linux.
|
|
@@ -989,6 +993,7 @@ async function closeAllWatchers() {
|
|
|
989
993
|
]);
|
|
990
994
|
closingWatcherRoots.clear();
|
|
991
995
|
closingPhysicalWatchers.clear();
|
|
996
|
+
await closeAllProjectWatchers();
|
|
992
997
|
emitWatcherRuntimeStatus();
|
|
993
998
|
}
|
|
994
999
|
function isWatcherPoolInitialized() {
|
|
@@ -1617,19 +1622,37 @@ function getCacheSize() {
|
|
|
1617
1622
|
//#endregion
|
|
1618
1623
|
//#region src/physical-reactive-file-writer.ts
|
|
1619
1624
|
/**
|
|
1620
|
-
* Orthogonal intents (updated 2026-08-
|
|
1625
|
+
* Orthogonal intents (updated 2026-08-05 Asia/Shanghai):
|
|
1621
1626
|
* 1. Own lexical and existing-ancestor physical confinement for root-scoped mutations.
|
|
1622
|
-
* 2. Execute direct or atomic UTF-8 write,
|
|
1627
|
+
* 2. Execute direct or atomic UTF-8 write, including bounded Windows replacement retries.
|
|
1623
1628
|
* 3. Settle overlapping reactive projections before returning any terminal outcome.
|
|
1624
1629
|
* 4. Keep TOCTOU and hard-link alias limitations explicit at the mutation seam.
|
|
1625
1630
|
*
|
|
1626
1631
|
* Original request (2026-07-16): "建立唯一的 physical/reactive entity-write owner。"
|
|
1627
1632
|
* Original request (2026-07-16): "Schema/Template mutations must reject symlink escape and settle reactive projections before success."
|
|
1628
1633
|
* Derived requirement (2026-08-02): "Raw Active Root YAML uses same-directory atomic replacement before reactive settlement."
|
|
1634
|
+
* Original request (2026-08-05): Continue the Windows adaptation and fix equivalent failures together.
|
|
1629
1635
|
*/
|
|
1636
|
+
const WINDOWS_FILE_REPLACEMENT_RETRY_LIMIT = 80;
|
|
1637
|
+
const WINDOWS_FILE_REPLACEMENT_RETRY_DELAY_MS = 25;
|
|
1630
1638
|
function isMissingPath(error) {
|
|
1631
1639
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
1632
1640
|
}
|
|
1641
|
+
function isRetryableWindowsFileReplacementError(error) {
|
|
1642
|
+
if (typeof error !== "object" || error === null || !("code" in error)) return false;
|
|
1643
|
+
const code = error.code;
|
|
1644
|
+
return code === "EACCES" || code === "EBUSY" || code === "EPERM";
|
|
1645
|
+
}
|
|
1646
|
+
/** Commit one prepared replacement through rename, retrying transient Windows file locks. */
|
|
1647
|
+
async function replaceFileAtomically(temporaryPath, targetPath) {
|
|
1648
|
+
for (let attempt = 0;; attempt += 1) try {
|
|
1649
|
+
await rename(temporaryPath, targetPath);
|
|
1650
|
+
return;
|
|
1651
|
+
} catch (error) {
|
|
1652
|
+
if (process.platform !== "win32" || !isRetryableWindowsFileReplacementError(error) || attempt >= WINDOWS_FILE_REPLACEMENT_RETRY_LIMIT) throw error;
|
|
1653
|
+
await setTimeout$1(WINDOWS_FILE_REPLACEMENT_RETRY_DELAY_MS);
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1633
1656
|
function ensureContained(rootPath, candidatePath, boundary) {
|
|
1634
1657
|
const childPath = relative(rootPath, candidatePath);
|
|
1635
1658
|
if (childPath === ".." || childPath.startsWith(`..${sep}`) || isAbsolute(childPath)) throw new Error(`Mutation target escaped the ${boundary} root.`);
|
|
@@ -1734,7 +1757,7 @@ async function writeAtomicPhysicalReactiveFile(input) {
|
|
|
1734
1757
|
await temporaryFile.close();
|
|
1735
1758
|
temporaryFile = null;
|
|
1736
1759
|
await assertMutationTarget(target);
|
|
1737
|
-
await
|
|
1760
|
+
await replaceFileAtomically(temporaryPath, target.targetPath);
|
|
1738
1761
|
} finally {
|
|
1739
1762
|
await temporaryFile?.close().catch(() => void 0);
|
|
1740
1763
|
await rm(temporaryPath, { force: true }).catch(() => void 0);
|
|
@@ -1777,7 +1800,7 @@ async function compareAndWriteAtomicPhysicalReactiveFile(input) {
|
|
|
1777
1800
|
state: "conflict",
|
|
1778
1801
|
content: currentContent
|
|
1779
1802
|
};
|
|
1780
|
-
await
|
|
1803
|
+
await replaceFileAtomically(temporaryPath, target.targetPath);
|
|
1781
1804
|
committed = true;
|
|
1782
1805
|
return { state: "written" };
|
|
1783
1806
|
} finally {
|
|
@@ -1894,9 +1917,9 @@ var Validator = class {
|
|
|
1894
1917
|
//#endregion
|
|
1895
1918
|
//#region src/adapter.ts
|
|
1896
1919
|
/**
|
|
1897
|
-
* Orthogonal intents (updated 2026-08-
|
|
1920
|
+
* Orthogonal intents (updated 2026-08-04 Asia/Shanghai):
|
|
1898
1921
|
* 1. Read and mutate one CLI-selected planning root through reactive filesystem APIs.
|
|
1899
|
-
* 2. Project recursive Specs, Changes, Archives, and schema-neutral entity files.
|
|
1922
|
+
* 2. Project recursive Specs, Changes, Archives, and schema-neutral entity files with canonical protocol paths.
|
|
1900
1923
|
* 3. Keep tracked workflow tasks distinct from document checklist analytics.
|
|
1901
1924
|
* 4. Preserve filesystem provenance and mutation boundaries for server consumers.
|
|
1902
1925
|
* 5. Expose Launch Project local-initialization evidence independently from Planning-root readiness.
|
|
@@ -1904,6 +1927,7 @@ var Validator = class {
|
|
|
1904
1927
|
* Original request (2026-07-15): "Split formal tracked progress, document checklist statistics, and Apply instruction progress into non-interchangeable facts."
|
|
1905
1928
|
* Original request (2026-08-01): adapt OpenSpec 1.7 nested Spec ids such as `platform/auth`.
|
|
1906
1929
|
* Review correction (2026-08-02): a same-named ordinary file is not initialized project structure.
|
|
1930
|
+
* Original request (2026-08-04): "Make pnpm openspecui start and equivalent package scripts work on Windows."
|
|
1907
1931
|
*/
|
|
1908
1932
|
/**
|
|
1909
1933
|
* OpenSpec filesystem adapter
|
|
@@ -2117,7 +2141,7 @@ var OpenSpecAdapter = class {
|
|
|
2117
2141
|
const fullPath = join(dir, name);
|
|
2118
2142
|
const statInfo = await reactiveStat(fullPath);
|
|
2119
2143
|
if (!statInfo) continue;
|
|
2120
|
-
const relativePath = fullPath.slice(root.length + 1);
|
|
2144
|
+
const relativePath = normalizeOpsxEntityPath(fullPath.slice(root.length + 1));
|
|
2121
2145
|
if (statInfo.isDirectory) {
|
|
2122
2146
|
files.push({
|
|
2123
2147
|
path: relativePath,
|
|
@@ -2503,6 +2527,17 @@ function updateProjectBindingContent(content, update) {
|
|
|
2503
2527
|
//#endregion
|
|
2504
2528
|
//#region src/watcher.ts
|
|
2505
2529
|
/**
|
|
2530
|
+
* Orthogonal intents (updated 2026-08-09 Asia/Shanghai):
|
|
2531
|
+
* 1. Project legacy OpenSpec directory changes for compatibility consumers.
|
|
2532
|
+
* 2. Settle every native watcher handle before runtime teardown completes.
|
|
2533
|
+
* 3. Interpret native recursive-watch paths without assuming one directory separator.
|
|
2534
|
+
*
|
|
2535
|
+
* Original request (2026-08-04): "Make pnpm openspecui start and equivalent package scripts work on Windows."
|
|
2536
|
+
*/
|
|
2537
|
+
function watchedPathSegments(filename) {
|
|
2538
|
+
return filename.split(/[\\/]+/).filter(Boolean);
|
|
2539
|
+
}
|
|
2540
|
+
/**
|
|
2506
2541
|
* OpenSpec file watcher
|
|
2507
2542
|
* Watches the openspec/ directory for changes and emits events
|
|
2508
2543
|
*/
|
|
@@ -2533,33 +2568,36 @@ var OpenSpecWatcher = class extends EventEmitter {
|
|
|
2533
2568
|
start() {
|
|
2534
2569
|
this.stop();
|
|
2535
2570
|
this.watchDir(this.specsDir, (filename, eventType) => {
|
|
2536
|
-
const
|
|
2537
|
-
|
|
2571
|
+
const segments = watchedPathSegments(filename);
|
|
2572
|
+
const id = segments.length > 1 ? segments[0] : void 0;
|
|
2573
|
+
if (id) this.emitDebounced(`spec:${id}`, {
|
|
2538
2574
|
type: "spec",
|
|
2539
2575
|
action: eventType === "rename" ? "create" : "update",
|
|
2540
|
-
id
|
|
2541
|
-
path: join(this.specsDir,
|
|
2576
|
+
id,
|
|
2577
|
+
path: join(this.specsDir, ...segments),
|
|
2542
2578
|
timestamp: Date.now()
|
|
2543
2579
|
});
|
|
2544
2580
|
});
|
|
2545
2581
|
this.watchDir(this.changesDir, (filename, eventType) => {
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2582
|
+
const segments = watchedPathSegments(filename);
|
|
2583
|
+
if (segments[0] === "archive") return;
|
|
2584
|
+
const id = segments.length > 1 ? segments[0] : void 0;
|
|
2585
|
+
if (id) this.emitDebounced(`change:${id}`, {
|
|
2549
2586
|
type: "change",
|
|
2550
2587
|
action: eventType === "rename" ? "create" : "update",
|
|
2551
|
-
id
|
|
2552
|
-
path: join(this.changesDir,
|
|
2588
|
+
id,
|
|
2589
|
+
path: join(this.changesDir, ...segments),
|
|
2553
2590
|
timestamp: Date.now()
|
|
2554
2591
|
});
|
|
2555
2592
|
});
|
|
2556
2593
|
this.watchDir(this.archiveDir, (filename, eventType) => {
|
|
2557
|
-
const
|
|
2558
|
-
|
|
2594
|
+
const segments = watchedPathSegments(filename);
|
|
2595
|
+
const id = segments.length > 1 ? segments[0] : void 0;
|
|
2596
|
+
if (id) this.emitDebounced(`archive:${id}`, {
|
|
2559
2597
|
type: "archive",
|
|
2560
2598
|
action: eventType === "rename" ? "create" : "update",
|
|
2561
|
-
id
|
|
2562
|
-
path: join(this.archiveDir,
|
|
2599
|
+
id,
|
|
2600
|
+
path: join(this.archiveDir, ...segments),
|
|
2563
2601
|
timestamp: Date.now()
|
|
2564
2602
|
});
|
|
2565
2603
|
});
|
|
@@ -2577,11 +2615,22 @@ var OpenSpecWatcher = class extends EventEmitter {
|
|
|
2577
2615
|
* Stop watching for file changes
|
|
2578
2616
|
*/
|
|
2579
2617
|
stop() {
|
|
2580
|
-
for (const watcher of this.
|
|
2618
|
+
for (const watcher of this.takeWatchers()) watcher.close();
|
|
2619
|
+
}
|
|
2620
|
+
/** Close every watcher and wait until native filesystem handles are released. */
|
|
2621
|
+
async close() {
|
|
2622
|
+
await Promise.all(this.takeWatchers().map((watcher) => new Promise((resolve$1) => {
|
|
2623
|
+
watcher.once("close", resolve$1);
|
|
2624
|
+
watcher.close();
|
|
2625
|
+
})));
|
|
2626
|
+
}
|
|
2627
|
+
takeWatchers() {
|
|
2628
|
+
const watchers = this.watchers;
|
|
2581
2629
|
this.watchers = [];
|
|
2582
2630
|
for (const timer of this.debounceTimers.values()) clearTimeout(timer);
|
|
2583
2631
|
this.debounceTimers.clear();
|
|
2584
2632
|
this.emit("stopped");
|
|
2633
|
+
return watchers;
|
|
2585
2634
|
}
|
|
2586
2635
|
/**
|
|
2587
2636
|
* Watch a directory recursively
|
|
@@ -2682,6 +2731,218 @@ function sanitizePersistedSettings(value, rules) {
|
|
|
2682
2731
|
return sanitized;
|
|
2683
2732
|
}
|
|
2684
2733
|
|
|
2734
|
+
//#endregion
|
|
2735
|
+
//#region src/child-process-tree.ts
|
|
2736
|
+
const execFileAsync$1 = promisify$1(execFile$1);
|
|
2737
|
+
const WINDOWS_PROCESS_TABLE_MAX_BUFFER = 16 * 1024 * 1024;
|
|
2738
|
+
function hasChildExited(child) {
|
|
2739
|
+
return child.exitCode !== null || child.signalCode !== null;
|
|
2740
|
+
}
|
|
2741
|
+
function normalizeWindowsExecutablePath(path) {
|
|
2742
|
+
return win32.normalize(path).toLowerCase();
|
|
2743
|
+
}
|
|
2744
|
+
function isWindowsProcessRecord(value) {
|
|
2745
|
+
if (typeof value !== "object" || value === null) return false;
|
|
2746
|
+
const row = value;
|
|
2747
|
+
return typeof row.ProcessId === "number" && typeof row.ParentProcessId === "number" && (typeof row.ExecutablePath === "string" || row.ExecutablePath === null);
|
|
2748
|
+
}
|
|
2749
|
+
/** Read the current Windows process table used for exact ancestry and root ownership checks. */
|
|
2750
|
+
async function readWindowsProcessTable() {
|
|
2751
|
+
const { stdout } = await execFileAsync$1("powershell.exe", [
|
|
2752
|
+
"-NoLogo",
|
|
2753
|
+
"-NoProfile",
|
|
2754
|
+
"-NonInteractive",
|
|
2755
|
+
"-Command",
|
|
2756
|
+
"[Console]::OutputEncoding = [Text.UTF8Encoding]::new($false); Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,ExecutablePath | ConvertTo-Json -Compress"
|
|
2757
|
+
], {
|
|
2758
|
+
encoding: "utf8",
|
|
2759
|
+
maxBuffer: WINDOWS_PROCESS_TABLE_MAX_BUFFER,
|
|
2760
|
+
windowsHide: true
|
|
2761
|
+
});
|
|
2762
|
+
const json = stdout.trim();
|
|
2763
|
+
if (json.length === 0) return [];
|
|
2764
|
+
const parsed = JSON.parse(json);
|
|
2765
|
+
return (Array.isArray(parsed) ? parsed : [parsed]).filter(isWindowsProcessRecord);
|
|
2766
|
+
}
|
|
2767
|
+
/** Terminate a Windows tree only when the root PID still owns the expected executable. */
|
|
2768
|
+
async function terminateWindowsProcessTreeByIdentity(rootPid, expectedExecutablePath) {
|
|
2769
|
+
const root = (await readWindowsProcessTable()).find((row) => row.ProcessId === rootPid);
|
|
2770
|
+
if (!root) return;
|
|
2771
|
+
const expectedExecutable = normalizeWindowsExecutablePath(expectedExecutablePath);
|
|
2772
|
+
const actualExecutable = root.ExecutablePath ? normalizeWindowsExecutablePath(root.ExecutablePath) : null;
|
|
2773
|
+
if (actualExecutable !== expectedExecutable) throw new Error(`Refusing to terminate PID ${rootPid}: expected ${expectedExecutable}, observed ${actualExecutable ?? "no executable path"}.`);
|
|
2774
|
+
try {
|
|
2775
|
+
await execFileAsync$1("taskkill.exe", [
|
|
2776
|
+
"/PID",
|
|
2777
|
+
String(rootPid),
|
|
2778
|
+
"/T",
|
|
2779
|
+
"/F"
|
|
2780
|
+
], { windowsHide: true });
|
|
2781
|
+
} catch (error) {
|
|
2782
|
+
if (!(await readWindowsProcessTable()).some((row) => row.ProcessId === rootPid)) return;
|
|
2783
|
+
throw error;
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
async function terminateWindowsProcessTree(child) {
|
|
2787
|
+
const rootPid = child.pid;
|
|
2788
|
+
if (rootPid === void 0 || hasChildExited(child)) return;
|
|
2789
|
+
await terminateWindowsProcessTreeByIdentity(rootPid, child.spawnfile);
|
|
2790
|
+
}
|
|
2791
|
+
/** Request termination of one spawned child and every Windows descendant it owns. */
|
|
2792
|
+
async function terminateChildProcessTree(child, signal = "SIGTERM") {
|
|
2793
|
+
if (child.pid === void 0) {
|
|
2794
|
+
child.kill(signal);
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
if (process$1.platform === "win32") {
|
|
2798
|
+
await terminateWindowsProcessTree(child);
|
|
2799
|
+
return;
|
|
2800
|
+
}
|
|
2801
|
+
if (hasChildExited(child)) return;
|
|
2802
|
+
child.kill(signal);
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
//#endregion
|
|
2806
|
+
//#region src/command-invocation.ts
|
|
2807
|
+
/**
|
|
2808
|
+
* Orthogonal intents (created 2026-08-09 Asia/Shanghai):
|
|
2809
|
+
* 1. Resolve caller-environment Windows commands to native argv-preserving executable boundaries.
|
|
2810
|
+
* 2. Project standard npm-style shims and explicit Node shebang launchers onto their real Node executable.
|
|
2811
|
+
* 3. Prefer native executables, route shell-sensitive pnpm through Corepack, and reject opaque command shims.
|
|
2812
|
+
*
|
|
2813
|
+
* Original request (2026-08-04): "Make pnpm openspecui start and equivalent package scripts work on Windows."
|
|
2814
|
+
*/
|
|
2815
|
+
const WINDOWS_NATIVE_EXTENSIONS = new Set([".com", ".exe"]);
|
|
2816
|
+
function isBareCommand(command$1) {
|
|
2817
|
+
return !/[\\/]/.test(command$1);
|
|
2818
|
+
}
|
|
2819
|
+
function commandName(command$1) {
|
|
2820
|
+
return basename(command$1, extname(command$1)).toLowerCase();
|
|
2821
|
+
}
|
|
2822
|
+
function requiresShellIndependentInvocation(args) {
|
|
2823
|
+
return args.some((argument) => /[%^&|<>"]/.test(argument) || argument.endsWith("\\"));
|
|
2824
|
+
}
|
|
2825
|
+
function systemExecutable(name, env) {
|
|
2826
|
+
return resolve(env.SystemRoot ?? env.SYSTEMROOT ?? process$1.env.SystemRoot ?? "C:\\Windows", "System32", name);
|
|
2827
|
+
}
|
|
2828
|
+
function findWindowsCommandCandidates(command$1, options) {
|
|
2829
|
+
const env = options.env ?? process$1.env;
|
|
2830
|
+
const result = spawnSync(systemExecutable("where.exe", env), [command$1], {
|
|
2831
|
+
cwd: options.cwd,
|
|
2832
|
+
encoding: "utf8",
|
|
2833
|
+
env,
|
|
2834
|
+
windowsHide: true
|
|
2835
|
+
});
|
|
2836
|
+
if (result.error) throw result.error;
|
|
2837
|
+
if (result.status !== 0) throw new Error(result.stderr.trim() || `Unable to resolve ${command$1} from PATH.`);
|
|
2838
|
+
return result.stdout.split(/\r?\n/).map((candidate) => candidate.trim()).filter(Boolean);
|
|
2839
|
+
}
|
|
2840
|
+
function tryFindWindowsCommandCandidates(command$1, options) {
|
|
2841
|
+
try {
|
|
2842
|
+
return findWindowsCommandCandidates(command$1, options);
|
|
2843
|
+
} catch {
|
|
2844
|
+
return [];
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
function explicitCommandCandidates(command$1, cwd) {
|
|
2848
|
+
const absolute = isAbsolute(command$1) ? command$1 : resolve(cwd, command$1);
|
|
2849
|
+
if (extname(absolute)) return [absolute];
|
|
2850
|
+
return [
|
|
2851
|
+
`${absolute}.exe`,
|
|
2852
|
+
`${absolute}.cmd`,
|
|
2853
|
+
absolute
|
|
2854
|
+
].filter(existsSync);
|
|
2855
|
+
}
|
|
2856
|
+
function commandCandidates(command$1, options) {
|
|
2857
|
+
if (isBareCommand(command$1)) return findWindowsCommandCandidates(command$1, options);
|
|
2858
|
+
return explicitCommandCandidates(command$1, options.cwd ?? process$1.cwd());
|
|
2859
|
+
}
|
|
2860
|
+
function findNativeExecutable(candidates) {
|
|
2861
|
+
return candidates.find((candidate) => WINDOWS_NATIVE_EXTENSIONS.has(extname(candidate).toLowerCase())) ?? null;
|
|
2862
|
+
}
|
|
2863
|
+
function findNodeExecutable(commandShim, options) {
|
|
2864
|
+
const siblingNode = resolve(dirname$1(commandShim), "node.exe");
|
|
2865
|
+
if (existsSync(siblingNode)) return siblingNode;
|
|
2866
|
+
const fromPath = findNativeExecutable(findWindowsCommandCandidates("node", options));
|
|
2867
|
+
if (fromPath) return fromPath;
|
|
2868
|
+
if (process$1.release.name === "node" && extname(process$1.execPath).toLowerCase() === ".exe") return process$1.execPath;
|
|
2869
|
+
throw new Error(`Unable to resolve the Node executable required by ${commandShim}.`);
|
|
2870
|
+
}
|
|
2871
|
+
function resolveNodeCommandShim(commandShim, args, options) {
|
|
2872
|
+
const source = readFileSync(commandShim, "utf8");
|
|
2873
|
+
if (!/(?:node(?:\.exe)?|node_exe|npm_node_execpath|_prog)/i.test(source)) return null;
|
|
2874
|
+
const entries = [];
|
|
2875
|
+
for (const match of source.matchAll(/%~dp0([^"\r\n]*?\.(?:c|m)?js)/gi)) {
|
|
2876
|
+
const relativeEntry = match[1]?.trim().replace(/^[\\/]+/, "");
|
|
2877
|
+
if (!relativeEntry) continue;
|
|
2878
|
+
const entry$1 = resolve(dirname$1(commandShim), relativeEntry);
|
|
2879
|
+
if (existsSync(entry$1)) entries.push(entry$1);
|
|
2880
|
+
}
|
|
2881
|
+
const entry = entries.at(-1);
|
|
2882
|
+
if (!entry) return null;
|
|
2883
|
+
return {
|
|
2884
|
+
command: findNodeExecutable(commandShim, options),
|
|
2885
|
+
args: [entry, ...args]
|
|
2886
|
+
};
|
|
2887
|
+
}
|
|
2888
|
+
function resolveCommandShim(candidates, args, options) {
|
|
2889
|
+
for (const candidate of candidates) {
|
|
2890
|
+
if (extname(candidate).toLowerCase() !== ".cmd") continue;
|
|
2891
|
+
const invocation = resolveNodeCommandShim(candidate, args, options);
|
|
2892
|
+
if (invocation) return invocation;
|
|
2893
|
+
}
|
|
2894
|
+
return null;
|
|
2895
|
+
}
|
|
2896
|
+
function resolveNodeShebangInvocation(candidates, args, options) {
|
|
2897
|
+
for (const candidate of candidates) {
|
|
2898
|
+
if (!existsSync(candidate) || extname(candidate).toLowerCase() === ".cmd") continue;
|
|
2899
|
+
const firstLine = readFileSync(candidate, "utf8").split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
2900
|
+
if (!/^#!.*(?:\/|\s)node(?:\.exe)?(?:\s|$)/i.test(firstLine)) continue;
|
|
2901
|
+
return {
|
|
2902
|
+
command: findNodeExecutable(candidate, options),
|
|
2903
|
+
args: [candidate, ...args]
|
|
2904
|
+
};
|
|
2905
|
+
}
|
|
2906
|
+
return null;
|
|
2907
|
+
}
|
|
2908
|
+
/** Resolve one Windows command without projecting argv through cmd.exe. */
|
|
2909
|
+
function resolveWindowsCommandInvocation(command$1, args, options = {}) {
|
|
2910
|
+
const candidates = commandCandidates(command$1, options);
|
|
2911
|
+
const name = commandName(command$1);
|
|
2912
|
+
const shellSensitive = requiresShellIndependentInvocation(args);
|
|
2913
|
+
if (name === "pnpm" && shellSensitive) {
|
|
2914
|
+
const corepack = findNativeExecutable(tryFindWindowsCommandCandidates("corepack", options));
|
|
2915
|
+
if (corepack) return {
|
|
2916
|
+
command: corepack,
|
|
2917
|
+
args: ["pnpm", ...args]
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
if (name === "npm" && shellSensitive) {
|
|
2921
|
+
const shimInvocation$1 = resolveCommandShim(candidates, args, options);
|
|
2922
|
+
if (shimInvocation$1) return shimInvocation$1;
|
|
2923
|
+
}
|
|
2924
|
+
const executable = findNativeExecutable(candidates);
|
|
2925
|
+
if (executable) return {
|
|
2926
|
+
command: executable,
|
|
2927
|
+
args: [...args]
|
|
2928
|
+
};
|
|
2929
|
+
const shimInvocation = resolveCommandShim(candidates, args, options);
|
|
2930
|
+
if (shimInvocation) return shimInvocation;
|
|
2931
|
+
const shebangInvocation = resolveNodeShebangInvocation(candidates, args, options);
|
|
2932
|
+
if (shebangInvocation) return shebangInvocation;
|
|
2933
|
+
const commandShim = candidates.find((candidate) => extname(candidate).toLowerCase() === ".cmd");
|
|
2934
|
+
if (commandShim) throw new Error(`${commandShim} is an opaque Windows command shim; refusing to reinterpret argv through cmd.exe.`);
|
|
2935
|
+
throw new Error(`${command$1} did not resolve to a native Windows executable or Node command shim.`);
|
|
2936
|
+
}
|
|
2937
|
+
/** Resolve one command using the caller's cwd and environment while preserving POSIX behavior. */
|
|
2938
|
+
function resolveCommandInvocation(command$1, args, options = {}) {
|
|
2939
|
+
if (process$1.platform !== "win32") return {
|
|
2940
|
+
command: command$1,
|
|
2941
|
+
args: [...args]
|
|
2942
|
+
};
|
|
2943
|
+
return resolveWindowsCommandInvocation(command$1, args, options);
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2685
2946
|
//#endregion
|
|
2686
2947
|
//#region src/spawn-safe.ts
|
|
2687
2948
|
function getSpawnErrorCode(err) {
|
|
@@ -2697,11 +2958,20 @@ function formatSpawnError(err) {
|
|
|
2697
2958
|
message: `${message}${code ? ` (${code})` : ""}`
|
|
2698
2959
|
};
|
|
2699
2960
|
}
|
|
2961
|
+
/** Spawn without a shell after resolving one caller-environment native argv boundary. */
|
|
2700
2962
|
function spawnSafe(command$1, args, options) {
|
|
2701
2963
|
try {
|
|
2964
|
+
const invocation = resolveCommandInvocation(command$1, args, {
|
|
2965
|
+
cwd: typeof options.cwd === "string" ? options.cwd : void 0,
|
|
2966
|
+
env: options.env
|
|
2967
|
+
});
|
|
2702
2968
|
return {
|
|
2703
2969
|
ok: true,
|
|
2704
|
-
child:
|
|
2970
|
+
child: spawn(invocation.command, invocation.args, {
|
|
2971
|
+
...options,
|
|
2972
|
+
shell: false,
|
|
2973
|
+
windowsHide: options.windowsHide ?? true
|
|
2974
|
+
})
|
|
2705
2975
|
};
|
|
2706
2976
|
} catch (err) {
|
|
2707
2977
|
return {
|
|
@@ -2710,12 +2980,7 @@ function spawnSafe(command$1, args, options) {
|
|
|
2710
2980
|
};
|
|
2711
2981
|
}
|
|
2712
2982
|
}
|
|
2713
|
-
|
|
2714
|
-
try {
|
|
2715
|
-
child.kill(signal);
|
|
2716
|
-
} catch {}
|
|
2717
|
-
}
|
|
2718
|
-
const EAGER_JSON_EXIT_GRACE_MS = 25;
|
|
2983
|
+
const EAGER_JSON_EXIT_GRACE_MS = 100;
|
|
2719
2984
|
const BUFFERED_FORCE_KILL_DELAY_MS = 1e3;
|
|
2720
2985
|
function runBufferedCommand(options) {
|
|
2721
2986
|
return new Promise((resolve$1) => {
|
|
@@ -2769,11 +3034,17 @@ function runBufferedCommand(options) {
|
|
|
2769
3034
|
let timedOut = false;
|
|
2770
3035
|
let settled = false;
|
|
2771
3036
|
let eagerJsonTimer = null;
|
|
3037
|
+
let eagerJsonImmediate = null;
|
|
2772
3038
|
let forceKillTimer = null;
|
|
2773
|
-
const
|
|
2774
|
-
if (
|
|
2775
|
-
|
|
2776
|
-
|
|
3039
|
+
const clearEagerJsonResolution = () => {
|
|
3040
|
+
if (eagerJsonTimer) {
|
|
3041
|
+
clearTimeout(eagerJsonTimer);
|
|
3042
|
+
eagerJsonTimer = null;
|
|
3043
|
+
}
|
|
3044
|
+
if (eagerJsonImmediate) {
|
|
3045
|
+
clearImmediate(eagerJsonImmediate);
|
|
3046
|
+
eagerJsonImmediate = null;
|
|
3047
|
+
}
|
|
2777
3048
|
};
|
|
2778
3049
|
const clearForceKillTimer = () => {
|
|
2779
3050
|
if (!forceKillTimer) return;
|
|
@@ -2785,11 +3056,11 @@ function runBufferedCommand(options) {
|
|
|
2785
3056
|
phases.terminationRequestedAt = performance.now();
|
|
2786
3057
|
observe("termination-requested", { reason });
|
|
2787
3058
|
}
|
|
2788
|
-
|
|
3059
|
+
terminateChildProcessTree(child).catch(() => void 0);
|
|
2789
3060
|
if (forceKillTimer) return;
|
|
2790
3061
|
forceKillTimer = setTimeout(() => {
|
|
2791
3062
|
forceKillTimer = null;
|
|
2792
|
-
if (!phases.exitAt && !phases.closeAt)
|
|
3063
|
+
if (!phases.exitAt && !phases.closeAt) terminateChildProcessTree(child, "SIGKILL").catch(() => void 0);
|
|
2793
3064
|
}, BUFFERED_FORCE_KILL_DELAY_MS);
|
|
2794
3065
|
};
|
|
2795
3066
|
let clearTimer = () => {};
|
|
@@ -2811,7 +3082,7 @@ function runBufferedCommand(options) {
|
|
|
2811
3082
|
if (settled) return;
|
|
2812
3083
|
settled = true;
|
|
2813
3084
|
clearTimer();
|
|
2814
|
-
|
|
3085
|
+
clearEagerJsonResolution();
|
|
2815
3086
|
if (reason !== "eager-json") clearForceKillTimer();
|
|
2816
3087
|
phases.resultResolvedAt = performance.now();
|
|
2817
3088
|
phases.resultReason = reason;
|
|
@@ -2835,14 +3106,18 @@ function runBufferedCommand(options) {
|
|
|
2835
3106
|
observe("json-complete-observed");
|
|
2836
3107
|
eagerJsonTimer = setTimeout(() => {
|
|
2837
3108
|
eagerJsonTimer = null;
|
|
2838
|
-
if (settled || phases.exitAt) return;
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
3109
|
+
if (settled || phases.exitAt || child.exitCode !== null || stderr.length > 0) return;
|
|
3110
|
+
eagerJsonImmediate = setImmediate(() => {
|
|
3111
|
+
eagerJsonImmediate = null;
|
|
3112
|
+
if (settled || phases.exitAt || child.exitCode !== null || stderr.length > 0) return;
|
|
3113
|
+
phases.eagerResolved = true;
|
|
3114
|
+
requestTermination("eager-json");
|
|
3115
|
+
finish("eager-json", {
|
|
3116
|
+
stdout,
|
|
3117
|
+
stderr,
|
|
3118
|
+
exitCode: 0,
|
|
3119
|
+
timedOut
|
|
3120
|
+
});
|
|
2846
3121
|
});
|
|
2847
3122
|
}, EAGER_JSON_EXIT_GRACE_MS);
|
|
2848
3123
|
} catch {}
|
|
@@ -2855,7 +3130,7 @@ function runBufferedCommand(options) {
|
|
|
2855
3130
|
stderr += data.toString();
|
|
2856
3131
|
});
|
|
2857
3132
|
child.on("exit", (exitCode, signal) => {
|
|
2858
|
-
|
|
3133
|
+
clearEagerJsonResolution();
|
|
2859
3134
|
clearForceKillTimer();
|
|
2860
3135
|
if (!phases.exitAt) {
|
|
2861
3136
|
phases.exitAt = performance.now();
|
|
@@ -2902,7 +3177,10 @@ function runBufferedCommand(options) {
|
|
|
2902
3177
|
* 4. Preserve reactive config reads and serialized config writes.
|
|
2903
3178
|
* 5. Resolve Windows `where` candidates by PATHEXT so the executable shim is preferred over the
|
|
2904
3179
|
* extension-less script (issue #209 hotfix).
|
|
3180
|
+
* 6. Hide runner-probe subprocess console windows (`windowsHide`) so a console-less Windows daemon
|
|
3181
|
+
* never flashes a cmd window while resolving or sniffing the CLI runner.
|
|
2905
3182
|
*
|
|
3183
|
+
* Original request (2026-08-14): "在Windows平台上,执行命令总是会弹出cmd窗口,这个可否统一隐藏,你先调查一下原因"
|
|
2906
3184
|
* Original request (2026-07-14): "openspec 1.6.0 已经放出,我们需要开始进行适配。"
|
|
2907
3185
|
* Independent review correction (2026-07-20): Global CLI installation must retire cached and
|
|
2908
3186
|
* in-flight runner authority.
|
|
@@ -3113,7 +3391,8 @@ async function resolveShellExecutablePath(command$1, cwd, env) {
|
|
|
3113
3391
|
cwd,
|
|
3114
3392
|
env,
|
|
3115
3393
|
encoding: "utf8",
|
|
3116
|
-
timeout: 5e3
|
|
3394
|
+
timeout: 5e3,
|
|
3395
|
+
windowsHide: true
|
|
3117
3396
|
});
|
|
3118
3397
|
return pickWindowsExecutablePath(stdout$1.split(/\r?\n/), env.PATHEXT);
|
|
3119
3398
|
}
|
|
@@ -3284,7 +3563,8 @@ async function sniffGlobalCli() {
|
|
|
3284
3563
|
const [localResult, latestVersion] = await Promise.all([execFileAsync(resolvedCommand, ["--version"], {
|
|
3285
3564
|
env,
|
|
3286
3565
|
timeout: 1e4,
|
|
3287
|
-
encoding: "utf8"
|
|
3566
|
+
encoding: "utf8",
|
|
3567
|
+
windowsHide: true
|
|
3288
3568
|
}).catch((err) => ({ error: err })), fetchLatestVersion()]);
|
|
3289
3569
|
if ("error" in localResult) {
|
|
3290
3570
|
const error = localResult.error instanceof Error ? localResult.error.message : String(localResult.error);
|
|
@@ -4461,14 +4741,17 @@ const ownersByChild = /* @__PURE__ */ new WeakMap();
|
|
|
4461
4741
|
//#endregion
|
|
4462
4742
|
//#region src/openspec-cli-worker.ts
|
|
4463
4743
|
/**
|
|
4464
|
-
* Orthogonal intents (updated 2026-
|
|
4744
|
+
* Orthogonal intents (updated 2026-08-06 Asia/Shanghai):
|
|
4465
4745
|
* 1. Resolve an installed OpenSpec package's importable CLI module from its configured runner and
|
|
4466
4746
|
* distinguish objective module absence from Worker startup/execution failure.
|
|
4467
4747
|
* 2. Execute one buffered OpenSpec command inside an isolated Node Worker with project cwd semantics.
|
|
4468
4748
|
* 3. Project Worker stdout, stderr, cancellation, and settlement through the buffered spawn contract.
|
|
4749
|
+
* 4. Treat observed Worker stderr as exit-owned evidence and settle it through the real Worker exit
|
|
4750
|
+
* instead of eager JSON retirement.
|
|
4469
4751
|
*
|
|
4470
4752
|
* Original request (2026-07-31): "直接寻址到本地 openspec 背后的 js,直接用 worker_thread 来运行它。"
|
|
4471
4753
|
* Original request (2026-07-31): "通过 OPENSPEC_SPAWN_MODE=process|worker 来进行区分两种模式。"
|
|
4754
|
+
* Original request (2026-08-06): "continue"
|
|
4472
4755
|
*/
|
|
4473
4756
|
const OPENSPEC_SPAWN_MODE_ENV = "OPENSPEC_SPAWN_MODE";
|
|
4474
4757
|
/** Objective signal that no importable OpenSpec CLI JavaScript module exists behind the runner. */
|
|
@@ -4597,6 +4880,18 @@ function runOpenSpecCliWorker(options) {
|
|
|
4597
4880
|
let completedExitCode = null;
|
|
4598
4881
|
let workerError;
|
|
4599
4882
|
let aborted = false;
|
|
4883
|
+
let eagerJsonTimer = null;
|
|
4884
|
+
let eagerJsonImmediate = null;
|
|
4885
|
+
const clearEagerJsonResolution = () => {
|
|
4886
|
+
if (eagerJsonTimer) {
|
|
4887
|
+
clearTimeout(eagerJsonTimer);
|
|
4888
|
+
eagerJsonTimer = null;
|
|
4889
|
+
}
|
|
4890
|
+
if (eagerJsonImmediate) {
|
|
4891
|
+
clearImmediate(eagerJsonImmediate);
|
|
4892
|
+
eagerJsonImmediate = null;
|
|
4893
|
+
}
|
|
4894
|
+
};
|
|
4600
4895
|
const observe = (phase, evidence = {}) => options.onPhase?.({
|
|
4601
4896
|
phase,
|
|
4602
4897
|
at: performance$1.now(),
|
|
@@ -4605,6 +4900,7 @@ function runOpenSpecCliWorker(options) {
|
|
|
4605
4900
|
const finish = (reason, exitCode) => {
|
|
4606
4901
|
if (settled) return;
|
|
4607
4902
|
settled = true;
|
|
4903
|
+
clearEagerJsonResolution();
|
|
4608
4904
|
phases.resultResolvedAt = performance$1.now();
|
|
4609
4905
|
phases.resultReason = reason;
|
|
4610
4906
|
observe("result-resolved", { reason });
|
|
@@ -4680,12 +4976,21 @@ function runOpenSpecCliWorker(options) {
|
|
|
4680
4976
|
observe("first-stdout-observed");
|
|
4681
4977
|
}
|
|
4682
4978
|
stdout += data.toString();
|
|
4683
|
-
if (options.eagerResolveJson && !phases.
|
|
4979
|
+
if (options.eagerResolveJson && !phases.jsonCompleteAt && stdout.trimStart().startsWith("{")) try {
|
|
4684
4980
|
JSON.parse(stdout);
|
|
4685
|
-
phases.eagerResolved = true;
|
|
4686
4981
|
phases.jsonCompleteAt = performance$1.now();
|
|
4687
4982
|
observe("json-complete-observed");
|
|
4688
|
-
|
|
4983
|
+
eagerJsonTimer = setTimeout(() => {
|
|
4984
|
+
eagerJsonTimer = null;
|
|
4985
|
+
if (settled || phases.exitAt || workerError || completedExitCode !== null || stderr.length > 0) return;
|
|
4986
|
+
eagerJsonImmediate = setImmediate(() => {
|
|
4987
|
+
eagerJsonImmediate = null;
|
|
4988
|
+
if (settled || phases.exitAt || workerError || completedExitCode !== null || stderr.length > 0) return;
|
|
4989
|
+
phases.eagerResolved = true;
|
|
4990
|
+
requestTermination("eager-json");
|
|
4991
|
+
finish("eager-json", 0);
|
|
4992
|
+
});
|
|
4993
|
+
}, EAGER_JSON_EXIT_GRACE_MS);
|
|
4689
4994
|
} catch {}
|
|
4690
4995
|
});
|
|
4691
4996
|
worker.stderr.on("data", (data) => {
|
|
@@ -4704,6 +5009,7 @@ function runOpenSpecCliWorker(options) {
|
|
|
4704
5009
|
});
|
|
4705
5010
|
worker.once("exit", (workerExitCode) => {
|
|
4706
5011
|
options.signal?.removeEventListener("abort", onAbort);
|
|
5012
|
+
clearEagerJsonResolution();
|
|
4707
5013
|
phases.exitAt = performance$1.now();
|
|
4708
5014
|
const exitCode = aborted ? null : phases.eagerResolved ? 0 : completedExitCode ?? workerExitCode;
|
|
4709
5015
|
observe("exit-observed", { exitCode });
|
|
@@ -4724,10 +5030,10 @@ function runOpenSpecCliWorker(options) {
|
|
|
4724
5030
|
//#endregion
|
|
4725
5031
|
//#region src/cli-executor.ts
|
|
4726
5032
|
/**
|
|
4727
|
-
* Orthogonal intents (updated 2026-08-
|
|
5033
|
+
* Orthogonal intents (updated 2026-08-08 Asia/Shanghai):
|
|
4728
5034
|
* 1. Execute buffered CLI work through process/Worker backends with runner recovery,
|
|
4729
5035
|
* observer-explicit OTel phase evidence, bounded probes, and owner-scoped disposal.
|
|
4730
|
-
* 2. Own streaming CLI
|
|
5036
|
+
* 2. Own streaming CLI process trees through cancellation request, escalation, and confirmed settlement.
|
|
4731
5037
|
* 3. Retain lifecycle helpers and add the fixed-path, tools-none project bootstrap stream.
|
|
4732
5038
|
* 4. Expose the physically separated OpenSpec 1.6 typed command facade.
|
|
4733
5039
|
* 5. Clear the Core-owned direct-child slot independently from stream settlement, and keep
|
|
@@ -4745,6 +5051,7 @@ function runOpenSpecCliWorker(options) {
|
|
|
4745
5051
|
* Original request (2026-07-31): "在主线程,通过 OPENSPEC_SPAWN_MODE=process|worker 来进行区分两种模式。"
|
|
4746
5052
|
* Original request (2026-08-02): initialize the Launch Project with `openspec init <path> --tools=none`.
|
|
4747
5053
|
* Review correction (2026-08-02): streamed command evidence must preserve argv boundaries.
|
|
5054
|
+
* Original request (2026-08-04): "Make pnpm openspecui start and equivalent package scripts work on Windows."
|
|
4748
5055
|
*/
|
|
4749
5056
|
/** Failure raised when even forced termination cannot confirm child-process close. */
|
|
4750
5057
|
var CliStreamTerminationError = class extends Error {
|
|
@@ -5321,14 +5628,10 @@ var CliExecutor = class {
|
|
|
5321
5628
|
const requestChildTermination = (child) => {
|
|
5322
5629
|
if (terminationStarted || settled) return;
|
|
5323
5630
|
terminationStarted = true;
|
|
5324
|
-
|
|
5325
|
-
child.kill("SIGTERM");
|
|
5326
|
-
} catch {}
|
|
5631
|
+
terminateChildProcessTree(child).catch(() => {});
|
|
5327
5632
|
terminationTimer = setTimeout(() => {
|
|
5328
5633
|
if (settled || !childOwner.owns(child)) return;
|
|
5329
|
-
|
|
5330
|
-
child.kill("SIGKILL");
|
|
5331
|
-
} catch {}
|
|
5634
|
+
terminateChildProcessTree(child, "SIGKILL").catch(() => {});
|
|
5332
5635
|
forceCloseTimer = setTimeout(() => {
|
|
5333
5636
|
if (!settled && childOwner.owns(child)) failTermination();
|
|
5334
5637
|
}, STREAM_FORCE_CLOSE_TIMEOUT_MS);
|
|
@@ -8085,4 +8388,4 @@ const PtyServerMessageSchema = z.discriminatedUnion("type", [
|
|
|
8085
8388
|
]);
|
|
8086
8389
|
|
|
8087
8390
|
//#endregion
|
|
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 };
|
|
8391
|
+
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, replaceFileAtomically, requireCanonicalOpenSpecEntityId, requireCanonicalOpenSpecSpecId, requireOpenSpecEntityRelativePath, resolveCommandInvocation, resolveHostedAppBaseUrl, resolveOpenSpecDataScope, resolveOpenSpecSpawnMode, resolveRootContext, resolveRuntimePackageInstallStrategy, resolveTerminalShellDefaults, resolveWindowsCommandInvocation, runControlledTranslationTask, runPhysicalReactivePathMutation, selectLocalDownloadGroup, shouldShowTranslationEngineInstallGate, snapshotHasAbsolutePath, sniffGlobalCli, sortMarkdownReadingPlugins, soundIdFromCustomHash, spawnSafe, specDocumentDisplayPath, specIdentityFromRoute, specIdentityKey, specRoutePath, subscribeWatcherRuntimeStatus, terminalNotificationEventToPublishInput, terminateChildProcessTree, terminateWindowsProcessTreeByIdentity, toCliProjectionCommandEvidence, toCliProjectionFailure, toCliProjectionNotice, toMarkdownFactKind, toOpsxDisplayPath, toPersistedGlobalSettings, toStoreFeatureResult, toggleMarkdownTask, trimMarkdownSlice, updateProjectBindingContent, updateReactiveFileCache, validateActiveRootRawYaml, writeAtomicPhysicalReactiveFile, writePhysicalReactiveFile };
|