@zhin.js/host-http 1.1.6 → 1.1.7

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/README.md CHANGED
@@ -70,3 +70,12 @@ path; links outside the root, blocked path segments, and dangling links are deni
70
70
  checked through their nearest existing parent and checked again after parent creation. File-tree
71
71
  and environment-file inventory use the same boundary. This covers existing symlink layouts; it does
72
72
  not provide an OS sandbox against a local process concurrently replacing directories during access.
73
+
74
+
75
+ ### Saved configuration explanations
76
+
77
+ The full-scope `config:explain` Console RPC reuses the composition root's
78
+ `PluginManagementPort.explainConfiguration(instanceKey, expectedRevision)` authority.
79
+ The route returns metadata only, rejects demo before reading configuration, and normalizes
80
+ errors without forwarding validator details or causes. It does not apply/restart the Runtime,
81
+ expand values for clients, execute plugin code, or perform platform/network actions.
@@ -1,6 +1,6 @@
1
1
  import type { AuthScope } from './token-registry.js';
2
2
  import type { DatabaseHostConsole } from '@zhin.js/plugin-runtime';
3
- import { type ConsoleConfigSource, type ConsoleEndpointSummary } from '@zhin.js/console-protocol';
3
+ import { type ConsoleConfigSource, type ConsoleConfigExplanation, type ConsoleEndpointSummary } from '@zhin.js/console-protocol';
4
4
  import { type ConsoleRpcExtendedCtx } from './console-rpc-extended/index.js';
5
5
  /**
6
6
  * Console RPC 请求结构:未锚定 endpoint 的会话地址(结构对齐
@@ -99,6 +99,7 @@ export interface PluginVerificationResult {
99
99
  readonly evidence: readonly string[];
100
100
  }
101
101
  export interface PluginManagementPort {
102
+ explainConfiguration?(instanceKey: string, expectedRevision: string): Promise<ConsoleConfigExplanation>;
102
103
  inspect?(packageName: string): Promise<PluginManagementState>;
103
104
  apply?(packageName: string, expectedProjectRevision?: string): Promise<{
104
105
  readonly requested: boolean;
@@ -75,6 +75,29 @@ export async function dispatchRuntimeConsoleRpc(message, ctx) {
75
75
  emit({ requestId, data: pages });
76
76
  return payloads;
77
77
  }
78
+ case CONFIG_RPC.EXPLAIN: {
79
+ if (ctx.authScope !== 'full') {
80
+ emit({ requestId, error: 'Full scope required' });
81
+ return payloads;
82
+ }
83
+ const { instanceKey, expectedRevision } = message;
84
+ if (typeof instanceKey !== 'string' || instanceKey.length > 128 || !/^[a-z0-9][a-z0-9-]*$/u.test(instanceKey)
85
+ || typeof expectedRevision !== 'string' || !/^[a-f0-9]{64}$/u.test(expectedRevision)) {
86
+ emit({ requestId, error: '精确 instanceKey 与已读取的 expectedRevision 必填' });
87
+ return payloads;
88
+ }
89
+ if (!ctx.pluginManagement?.explainConfiguration) {
90
+ emit({ requestId, error: '配置解释尚未配置' });
91
+ return payloads;
92
+ }
93
+ try {
94
+ emit({ requestId, data: await ctx.pluginManagement.explainConfiguration(instanceKey, expectedRevision) });
95
+ }
96
+ catch {
97
+ emit({ requestId, error: '配置解释未确认,请重新读取文件版本与当前运行状态;原配置未改动。' });
98
+ }
99
+ return payloads;
100
+ }
78
101
  case CONFIG_RPC.GET_SOURCE: {
79
102
  try {
80
103
  const config = ctx.readConfigSource
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/host-http",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "Minimal HTTP and WebSocket host for Plugin Runtime (no Koa)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -17,11 +17,11 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "ws": "^8.21.1",
20
- "@zhin.js/console-protocol": "1.1.9",
20
+ "@zhin.js/console-protocol": "1.1.10",
21
21
  "@zhin.js/host-http-contract": "1.1.1",
22
22
  "@zhin.js/logger": "1.1.2",
23
23
  "@zhin.js/schedule": "1.1.3",
24
- "@zhin.js/plugin-runtime": "1.1.14"
24
+ "@zhin.js/plugin-runtime": "1.1.15"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/node": "^26.1.2",
@@ -4,6 +4,7 @@ import {
4
4
  CONFIG_RPC,
5
5
  ENDPOINT_RPC,
6
6
  type ConsoleConfigSource,
7
+ type ConsoleConfigExplanation,
7
8
  type ConsoleEndpointSummary,
8
9
  assertDemoConsoleRpcAllowed,
9
10
  } from '@zhin.js/console-protocol';
@@ -136,6 +137,7 @@ export interface PluginVerificationResult {
136
137
  }
137
138
 
138
139
  export interface PluginManagementPort {
140
+ explainConfiguration?(instanceKey: string, expectedRevision: string): Promise<ConsoleConfigExplanation>;
139
141
  inspect?(packageName: string): Promise<PluginManagementState>;
140
142
  apply?(packageName: string, expectedProjectRevision?: string): Promise<{ readonly requested: boolean; readonly state: PluginManagementState }>;
141
143
  verificationPlan?(packageName: string): Promise<PluginVerificationPlan>;
@@ -332,6 +334,18 @@ export async function dispatchRuntimeConsoleRpc(
332
334
  emit({ requestId, data: pages });
333
335
  return payloads;
334
336
  }
337
+ case CONFIG_RPC.EXPLAIN: {
338
+ if (ctx.authScope !== 'full') { emit({ requestId, error: 'Full scope required' }); return payloads; }
339
+ const { instanceKey, expectedRevision } = message;
340
+ if (typeof instanceKey !== 'string' || instanceKey.length > 128 || !/^[a-z0-9][a-z0-9-]*$/u.test(instanceKey)
341
+ || typeof expectedRevision !== 'string' || !/^[a-f0-9]{64}$/u.test(expectedRevision)) {
342
+ emit({ requestId, error: '精确 instanceKey 与已读取的 expectedRevision 必填' }); return payloads;
343
+ }
344
+ if (!ctx.pluginManagement?.explainConfiguration) { emit({ requestId, error: '配置解释尚未配置' }); return payloads; }
345
+ try { emit({ requestId, data: await ctx.pluginManagement.explainConfiguration(instanceKey, expectedRevision) }); }
346
+ catch { emit({ requestId, error: '配置解释未确认,请重新读取文件版本与当前运行状态;原配置未改动。' }); }
347
+ return payloads;
348
+ }
335
349
  case CONFIG_RPC.GET_SOURCE: {
336
350
  try {
337
351
  const config: ConsoleConfigSource = ctx.readConfigSource