Skip to content

Commit f203d72

Browse files
author
xlx1212
committed
fix(loopx): compact environment panel and clarify Node runtime status
- render the environment panel as a single compact column to avoid blank space - explain that an unknown Node runtime has not been probed yet - keep the probe/re-check action as the single follow-up
1 parent 77a0541 commit f203d72

19 files changed

Lines changed: 163 additions & 3526 deletions

File tree

‎docs/interactive-capabilities/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ OpenBitFun Playbook currently contains **22 features**, **21 settings pages**, a
2727
- Generated per-item interaction audit: `docs/interactive-capabilities/technical/product-control-open-audit.json`
2828
- Generated low-level audit map: `docs/interactive-capabilities/technical/tauri-command-map.json`
2929

30-
说明书、网站、搜索和 Agent 只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **673** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。
30+
说明书、网站、搜索和智能体只看“功能 + 设置 + 子能力”。每项子能力都必须引用已注册 Tauri Command 或可解析的源码标记;这些证据不会进入公开目录。当前 **664** 个 Tauri 命令只用于实现覆盖审计。产品 UI 交互源码会在生成和检查时扫描并校验,但不会保存成随普通 UI 改动频繁变化的版本化快照。
3131

32-
Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **673** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.
32+
Docs, website, search, and agents see only features, settings, and documented sub-capabilities. Every sub-capability must reference a registered Tauri command or a resolvable source marker; evidence is stripped from public projections. The **664** Tauri commands remain implementation-audit evidence only. Product UI interaction sources are scanned and validated during generation and checks, but are not stored as a versioned snapshot that churns with ordinary UI changes.
3333

3434
## 控制边界 / Control boundary
3535

‎docs/interactive-capabilities/technical/tauri-command-map.json‎

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"schemaVersion": 2,
33
"generatedFrom": "src/shared/interactive-capabilities/catalog.json",
4-
"catalogDigest": "d7a7419ddd673eb733ae8bd33dbb3dcd3b4d1ce0acfc953067a3403fe26d6699",
5-
"commandCount": 673,
4+
"catalogDigest": "5473331e06ecd4bfafbf9b547d48b4fe1561ccf69d86fdfde51ea10dc919531c",
5+
"commandCount": 664,
66
"coverage": {
7-
"commandCount": 673,
8-
"documentedCommandCount": 633,
9-
"implementationCommandCount": 40,
10-
"implementationDigest": "c0a1edc760154624bd17f742f82fb66d08af6e8e2b32e99829e92ed6a75cd75e"
7+
"commandCount": 664,
8+
"documentedCommandCount": 613,
9+
"implementationCommandCount": 51,
10+
"implementationDigest": "233258957d404d017612c63fc57b2d6630543a50c4a10c059b5fb2623b621827"
1111
},
1212
"commands": [
1313
{
@@ -5836,38 +5836,6 @@
58365836
"signature": "fn miniapp_loopx_turn_output_since( app_state: State<'_, AppState>, controller: State<'_, LoopxControllerState>, request: MiniAppLoopxTurnOutputSinceRequest, ) -> Result<LoopxTurnOutputSinceResponse, String>",
58375837
"remoteWorkspacePolicy": "RemoteUnsupported"
58385838
},
5839-
{
5840-
"id": "miniapp_market_auth_poll",
5841-
"moduleId": "miniapp_market",
5842-
"capabilityId": "feature.miniapps",
5843-
"capabilityIds": [
5844-
"feature.miniapps"
5845-
],
5846-
"documentedItemIds": [
5847-
"feature.miniapps:market-account"
5848-
],
5849-
"visibility": "documented",
5850-
"rustPath": "api::miniapp_market_api::miniapp_market_auth_poll",
5851-
"sourceFile": "src/apps/desktop/src/api/miniapp_market_api.rs",
5852-
"signature": "fn miniapp_market_auth_poll( app: AppHandle, request: DesktopAuthPollViewRequest, ) -> Result<DesktopAuthPollViewResponse, String>",
5853-
"remoteWorkspacePolicy": "WorkspaceAgnostic"
5854-
},
5855-
{
5856-
"id": "miniapp_market_auth_start",
5857-
"moduleId": "miniapp_market",
5858-
"capabilityId": "feature.miniapps",
5859-
"capabilityIds": [
5860-
"feature.miniapps"
5861-
],
5862-
"documentedItemIds": [
5863-
"feature.miniapps:market-account"
5864-
],
5865-
"visibility": "documented",
5866-
"rustPath": "api::miniapp_market_api::miniapp_market_auth_start",
5867-
"sourceFile": "src/apps/desktop/src/api/miniapp_market_api.rs",
5868-
"signature": "fn miniapp_market_auth_start() -> Result<DesktopAuthStartView, String>",
5869-
"remoteWorkspacePolicy": "WorkspaceAgnostic"
5870-
},
58715839
{
58725840
"id": "miniapp_market_browse",
58735841
"moduleId": "miniapp_market",

‎scripts/check-core-boundaries.test.mjs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,11 @@ test('contract and AI adapter tests keep reviewed feature and failure-domain top
957957
path: 'tests/loopx_contracts.rs',
958958
requiredFeatures: ['miniapp'],
959959
},
960+
{
961+
name: 'legacy_migration_contracts',
962+
path: 'tests/legacy_migration_contracts.rs',
963+
requiredFeatures: ['legacy-migration'],
964+
},
960965
{
961966
name: 'plugin_source_contracts',
962967
path: 'tests/plugin_source_contracts.rs',

‎scripts/core-boundaries/cargo-dependency-boundaries.mjs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ const SERVICES_INTEGRATIONS_TOKIO_FEATURES = new Map([
153153
['function-agents', ['fs', 'io-util', 'macros', 'rt', 'time']],
154154
['mcp', ['fs', 'io-util', 'net', 'process', 'rt', 'sync', 'time']],
155155
['miniapp-loopx', ['fs', 'io-util', 'macros', 'process', 'rt', 'sync', 'time']],
156+
['miniapp-storage', ['fs', 'time']],
156157
['miniapp-runtime', ['fs', 'io-util', 'net', 'process', 'rt', 'sync', 'time']],
157158
['miniapp-market', ['fs', 'io-util', 'net', 'process', 'rt', 'sync', 'time']],
158159
['plugin-source', ['fs', 'rt', 'sync', 'time']],

‎scripts/core-boundaries/explicit-test-topology.mjs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ export const productDomainsIntegrationTestTargets = [
212212
path: 'tests/loopx_contracts.rs',
213213
requiredFeatures: ['miniapp'],
214214
},
215+
{
216+
name: 'legacy_migration_contracts',
217+
path: 'tests/legacy_migration_contracts.rs',
218+
requiredFeatures: ['legacy-migration'],
219+
},
215220
{
216221
name: 'plugin_source_contracts',
217222
path: 'tests/plugin_source_contracts.rs',

‎scripts/core-boundaries/rules/feature-rules.mjs‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ export const optionalDependencyFeatureOwnerRules = [
285285
depName: 'openbitfun-core-types',
286286
ownerFeatures: ['deep-research', 'remote-connect', 'remote-ssh-concrete', 'speech'],
287287
},
288-
{ depName: 'openbitfun-product-domains', ownerFeatures: ['canvas-runtime', 'function-agents', 'hook-import', 'miniapp-loopx', 'miniapp-market', 'miniapp-runtime', 'plugin-source'] },
288+
{ depName: 'openbitfun-product-domains', ownerFeatures: ['account-identity', 'canvas-runtime', 'function-agents', 'hook-import', 'miniapp-loopx', 'miniapp-market', 'miniapp-runtime', 'miniapp-storage', 'plugin-source', 'remote-connect'] },
289289
{ depName: 'openbitfun-runtime-ports', ownerFeatures: ['deep-research', 'git', 'remote-connect', 'remote-ssh', 'remote-ssh-concrete', 'script-tool-runtime', 'web-tools'] },
290290
{
291291
depName: 'openbitfun-services-core',
@@ -312,15 +312,15 @@ export const optionalDependencyFeatureOwnerRules = [
312312
],
313313
},
314314
{ depName: 'bzip2', ownerFeatures: ['speech'] },
315-
{ depName: 'chrono', ownerFeatures: ['git', 'miniapp-market', 'remote-connect', 'remote-ssh-concrete', 'review-platform', 'speech', 'web-tools'] },
316-
{ depName: 'dirs', ownerFeatures: ['browser-control', 'miniapp-runtime', 'remote-connect', 'remote-ssh-concrete'] },
315+
{ depName: 'chrono', ownerFeatures: ['account-identity', 'git', 'miniapp-market', 'remote-connect', 'remote-ssh-concrete', 'review-platform', 'speech', 'web-tools'] },
316+
{ depName: 'dirs', ownerFeatures: ['account-identity', 'browser-control', 'miniapp-runtime', 'remote-connect', 'remote-ssh-concrete'] },
317317
{ depName: 'dunce', ownerFeatures: ['miniapp-loopx', 'plugin-source', 'workspace-search'] },
318-
{ depName: 'fs2', ownerFeatures: ['plugin-source'] },
318+
{ depName: 'fs2', ownerFeatures: ['plugin-source', 'remote-persistence', 'remote-connect'] },
319319
{ depName: 'futures', ownerFeatures: ['mcp', 'remote-connect', 'review-platform'] },
320320
{ depName: 'futures-util', ownerFeatures: ['speech', 'web-tools'] },
321321
{ depName: 'git2', ownerFeatures: ['git'] },
322322
{ depName: 'hex', ownerFeatures: ['hook-import', 'mcp', 'miniapp-loopx', 'miniapp-market', 'plugin-source', 'remote-connect'] },
323-
{ depName: 'hostname', ownerFeatures: ['remote-connect'] },
323+
{ depName: 'hostname', ownerFeatures: ['remote-connect', 'remote-persistence'] },
324324
{ depName: 'image', ownerFeatures: ['miniapp-market', 'remote-connect'] },
325325
{ depName: 'local-ip-address', ownerFeatures: ['remote-connect'] },
326326
{ depName: 'libc', ownerFeatures: ['plugin-source'] },
@@ -341,20 +341,20 @@ export const optionalDependencyFeatureOwnerRules = [
341341
{ depName: 'rustls', ownerFeatures: ['remote-connect'] },
342342
{ depName: 'rustls-native-certs', ownerFeatures: ['remote-connect'] },
343343
{ depName: 'schannel', ownerFeatures: ['remote-connect'] },
344-
{ depName: 'sha2', ownerFeatures: ['canvas-runtime', 'hook-import', 'mcp', 'miniapp-loopx', 'miniapp-market', 'models-dev', 'plugin-source', 'remote-connect', 'remote-ssh', 'review-platform', 'speech'] },
344+
{ depName: 'sha2', ownerFeatures: ['canvas-runtime', 'hook-import', 'mcp', 'miniapp-loopx', 'miniapp-market', 'models-dev', 'plugin-source', 'remote-connect', 'remote-persistence', 'remote-ssh', 'review-platform', 'speech'] },
345345
{ depName: 'sherpa-onnx', ownerFeatures: ['speech'] },
346346
{ depName: 'shellexpand', ownerFeatures: ['remote-ssh-concrete'] },
347347
{ depName: 'sse-stream', ownerFeatures: ['mcp'] },
348348
{ depName: 'ssh_config', ownerFeatures: ['remote-ssh-concrete', 'ssh_config'] },
349349
{ depName: 'terminal-core', ownerFeatures: ['remote-ssh', 'remote-ssh-concrete'] },
350350
{ depName: 'tar', ownerFeatures: ['speech'] },
351-
{ depName: 'thiserror', ownerFeatures: ['browser-control', 'git', 'hook-import', 'miniapp-loopx', 'miniapp-market', 'plugin-source', 'remote-ssh', 'remote-ssh-concrete', 'review-platform', 'speech', 'web-tools', 'workspace-search'] },
351+
{ depName: 'thiserror', ownerFeatures: ['account-identity', 'browser-control', 'git', 'hook-import', 'miniapp-loopx', 'miniapp-market', 'plugin-source', 'remote-connect', 'remote-ssh', 'remote-ssh-concrete', 'review-platform', 'speech', 'web-tools', 'workspace-search'] },
352352
{ depName: 'tokio-tungstenite', ownerFeatures: ['remote-connect', 'speech-realtime'] },
353353
{ depName: 'tokio-util', ownerFeatures: ['miniapp-loopx', 'remote-ssh', 'speech'] },
354354
{ depName: 'urlencoding', ownerFeatures: ['canvas-runtime', 'miniapp-market', 'remote-connect', 'review-platform'] },
355-
{ depName: 'uuid', ownerFeatures: ['canvas-runtime', 'hook-import', 'miniapp-loopx', 'miniapp-runtime', 'plugin-source', 'remote-connect', 'remote-ssh-concrete', 'speech'] },
355+
{ depName: 'uuid', ownerFeatures: ['canvas-runtime', 'hook-import', 'miniapp-loopx', 'miniapp-runtime', 'miniapp-storage', 'plugin-source', 'remote-connect', 'remote-ssh-concrete', 'speech'] },
356356
{ depName: 'which', ownerFeatures: ['miniapp-loopx', 'miniapp-runtime', 'remote-connect', 'script-tool-runtime', 'workspace-search'] },
357-
{ depName: 'windows', ownerFeatures: ['models-dev', 'plugin-source', 'review-platform'] },
357+
{ depName: 'windows', ownerFeatures: ['models-dev', 'plugin-source', 'remote-connect', 'remote-persistence', 'remote-ssh-concrete', 'review-platform'] },
358358
{ depName: 'x25519-dalek', ownerFeatures: ['remote-connect'] },
359359
],
360360
},

‎scripts/desktop-tauri-build.mjs‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
writeFileSync,
1515
} from 'fs';
1616
import { buildLoopx } from './build-loopx.mjs';
17+
import { ensureFlashgrepBinary } from './prepare-flashgrep-resource.mjs';
1718
import { extractProductConfigArg } from './product-customization/cli.mjs';
1819
import { productBuildEnvironment } from './product-customization/projections.mjs';
1920
import { resolveProductDefinition } from './product-customization/resolver.mjs';
@@ -49,9 +50,12 @@ async function main() {
4950
console.log(`[release] channel=${releaseChannel.channel}`);
5051

5152
const desktopDir = join(ROOT, 'src', 'apps', 'desktop');
52-
preparePluginHost();
53-
// Flashgrep distribution is temporarily suspended.
54-
const flashgrepBinary = null;
53+
if (!bundleOnly) preparePluginHost();
54+
const flashgrepBinary = prepareMacOSFlashgrepForSigning(
55+
ensureFlashgrepBinary({ target: optionValue(forward, '--target') || rustHostTargetTriple() }),
56+
desktopDir,
57+
);
58+
process.env.FLASHGREP_DAEMON_BIN = flashgrepBinary;
5559
const loopxResourceDir = await prepareBundledLoopx(forward, desktopDir);
5660
// Tauri CLI reads CI and rejects numeric "1" (common in CI providers).
5761
process.env.CI = 'true';

‎scripts/dev.cjs‎

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ function runCommandPrefixed(prefix, cmd, args, cwd = ROOT_DIR, envOverrides = {}
154154
return new Promise((resolve) => {
155155
const spawnOptions = {
156156
cwd,
157+
windowsHide: true,
157158
stdio: ['ignore', 'pipe', 'pipe'],
158159
env: {
159160
...process.env,
@@ -681,7 +682,8 @@ async function main() {
681682
let currentStep = 1;
682683

683684
// Step 1: Run all independent preparation tasks in parallel.
684-
// copy-monaco / generate-version / mobile-web / plugin-host / loopx have no
685+
// copy-monaco / generate-version / mobile-web / flashgrep / plugin-host / loopx
686+
// have no
685687
// dependencies on each other; each task's output is line-prefixed so the
686688
// interleaved logs stay attributable. The DeepSeek bridge is not prepared
687689
// here: it is not a compile-time Tauri resource. Official desktop:build
@@ -690,7 +692,7 @@ async function main() {
690692
currentStep++,
691693
totalSteps,
692694
desktopMode
693-
? 'Prepare resources (parallel: monaco, version, mobile-web, plugin-host, loopx)'
695+
? 'Prepare resources (parallel: monaco, version, mobile-web, flashgrep, plugin-host, loopx)'
694696
: 'Prepare resources (parallel: monaco, version)'
695697
);
696698

@@ -720,6 +722,32 @@ async function main() {
720722
name: 'Prepare loopx CLI sidecar',
721723
promise: ensureLoopxSidecar(),
722724
});
725+
prepTasks.push({
726+
name: 'Prepare speech libraries',
727+
promise: (async () => {
728+
try {
729+
const { prepareSherpaDev } = await import('./prepare-sherpa-dev.mjs');
730+
prepareSherpaDev(ROOT_DIR);
731+
return { ok: true, code: 0 };
732+
} catch (error) {
733+
return { ok: false, code: null, error };
734+
}
735+
})(),
736+
});
737+
prepTasks.push({
738+
name: 'Prepare workspace search daemon',
739+
promise: (async () => {
740+
try {
741+
const { ensureFlashgrepBinary } = await import(
742+
pathToFileURL(path.join(__dirname, 'prepare-flashgrep-resource.mjs')).href
743+
);
744+
process.env.FLASHGREP_DAEMON_BIN = ensureFlashgrepBinary();
745+
return { ok: true, code: 0 };
746+
} catch (error) {
747+
return { ok: false, code: null, error };
748+
}
749+
})(),
750+
});
723751
prepTasks.push({
724752
name: 'Build mobile-web',
725753
promise: runCommandPrefixed('mobile-web', 'node', ['scripts/mobile-web-build.cjs', '--install']),

0 commit comments

Comments
 (0)