Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

- Add candidate-only benchmark component switches with conservative patch editing, composed-config verification and a bounded readiness turn. Archive effective switches, show them in reports, and reject comparisons across different candidate switch sets (#296).
- 收敛所有 DSH 产品类型、懒加载 scope 与 profile carrier 入口到项目自有 `adapter/dsh` 边界;保持现有 Cordis 工具注册、提示词、权限、subprocess、PTC、结果与 UI 行为不变,并将宿主兼容声明扩展至 `>=0.2.0-rc.2 <0.2.2-0`,覆盖已验证的 DSH 0.2.1-rc.4。
- Converge DSH product types, lazy scope loading and profile-carrier entrypoints behind the project-owned `adapter/dsh` boundary without changing existing Cordis tool, prompt, policy, subprocess, PTC, result or UI behavior; widen the bounded host range to `>=0.2.0-rc.2 <0.2.2-0`, including validated DSH 0.2.1-rc.4.
with conservative patch editing, composed-config verification and a bounded readiness turn. Archive effective switches, show them in reports, and reject comparisons across different candidate switch sets (#296).
- 为 benchmark 增加仅作用于 candidate 的组件开关,保守编辑补丁并核验合成配置及有时限的就绪 turn;归档实际开关、在报告中展示,并拒绝不同 candidate 开关集的混配(#296)。

- Make benchmark model/reasoning selections actual shared routing conditions, archive composed configuration, and record the condition in sealed evidence. Repeated selections produce separate condition groups and reports; cross-condition pairing is refused, while historical runs remain readable as unknown (#294).
Expand Down
8 changes: 1 addition & 7 deletions docs/host-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,7 @@ use the PTC SDK loader under the host's `run_code` presentation. Check the scope
assembled tools and presentation, not just a global registry or a prompt section
name. An empty discovery section alone does not identify the cause.

Host support declarations and component resource exports are addressed in
[PR #395](https://github.com/T-Auto/dsh-ops/pull/395), with explicit 0.2.0-rc.2 and
0.2.1-rc.2 coverage. The text-only PTC hook adaptation in
[PR #390](https://github.com/T-Auto/dsh-ops/pull/390) is not full 0.2.1-rc.3 support.
[PR #383](https://github.com/T-Auto/dsh-ops/pull/383) and #390 address unnecessary
session work and append-time Bash publication. Check whether the installed version
actually contains these changes before attributing its behavior to them.
Host support declarations and component resource exports are covered by the current adapter boundary. The package declares and tests the bounded range `>=0.2.0-rc.2 <0.2.2-0`, including rc2, rc3, rc4 and the 0.2.1 stable line; the isolated host matrix compares the rc4 graph against the locked rc2 control. The text-only PTC hook adaptation is not used as the sole compatibility proof.

The original #346 report also describes an enabled row and a stalled publication
chain. The profile checks above do not prove that failure fixed. If the row is
Expand Down
6 changes: 1 addition & 5 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,7 @@ The ordinary DSH CLI cannot manage the reserved `desktop` profile; do not confus

### Host compatibility and display metadata

The package declares **DSH 0.2.0-rc.2 and 0.2.1-rc.2** explicitly in both `engines.dsh`
and the legacy DSH peer dependency. DSH 0.2.1 uses `engines.dsh` in preference to peers.
Other prereleases, including 0.2.1-rc.3, are outside this declaration: accepting its
text-only prompt hook does not establish compatibility with all presentation and
official-tool replacement APIs.
The package declares the bounded DSH compatibility range `>=0.2.0-rc.2 <0.2.2-0` in both `engines.dsh` and the legacy DSH peer dependency. This includes `0.2.0-rc.2`, `0.2.1-rc.2`, `0.2.1-rc.3`, `0.2.1-rc.4` and the `0.2.1` stable line, while rejecting `0.2.0-rc.1`, `0.2.2` prereleases and `0.3.0`. The rc4 host graph is validated separately in the isolated host matrix; the plugin's native adapter preserves the existing Cordis tool, prompt, policy, subprocess, PTC and UI behavior.

The bundle icon comes from the root manifest. Each component exports its own
`dsh-ops/<component>/icon` and `locale/*.json`; DSH 0.2.1 does not use a component's
Expand Down
4 changes: 1 addition & 3 deletions docs/使用指南.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ dsh plugin --profile dsh-tui add dsh-ops

### 宿主兼容范围与展示元数据

包在 `engines.dsh` 和旧版 DSH peer 依赖中明确声明 **DSH 0.2.0-rc.2 与 0.2.1-rc.2**。
DSH 0.2.1 优先使用 `engines.dsh`。其他预发布版本(包括 0.2.1-rc.3)不在声明范围内:
适配只含文本的 prompt hook,并不代表所有展示与官方工具替换接口均已兼容。
包在 `engines.dsh` 和旧版 DSH peer 依赖中声明有界范围 `>=0.2.0-rc.2 <0.2.2-0`,覆盖 `0.2.0-rc.2`、`0.2.1-rc.2`、`0.2.1-rc.3`、`0.2.1-rc.4` 与 `0.2.1` 稳定线,同时拒绝 `0.2.0-rc.1`、`0.2.2` 预发布版本和 `0.3.0`。隔离宿主矩阵会单独验证 rc4;OPS 自有 DSH adapter 保持现有 Cordis 工具、提示词、权限、subprocess、PTC 与 UI 行为。

bundle 图标来自顶层清单。每个组件单独导出 `dsh-ops/<组件>/icon` 和 `locale/*.json`;
DSH 0.2.1 不再通过组件 `package.json` 读取这些资源。元数据门禁通过宿主 API 读取 PNG
Expand Down
6 changes: 1 addition & 5 deletions docs/宿主集成.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ dsh --profile ops-test --dump-config-schema
`run_code` 展示使用 PTC SDK loader。应检查具体作用域的装配工具和展示模式,不只查看
全局注册表或提示词段名称。discovery 段为空本身不足以确定原因。

[PR #395](https://github.com/T-Auto/dsh-ops/pull/395) 处理宿主兼容声明与组件资源导出,
明确覆盖 0.2.0-rc.2 和 0.2.1-rc.2。
[PR #390](https://github.com/T-Auto/dsh-ops/pull/390) 的纯文本 PTC hook 适配不代表完整
支持 0.2.1-rc.3。[PR #383](https://github.com/T-Auto/dsh-ops/pull/383) 与 #390 处理会话
重复工作及 append 期间 Bash 发布问题。判断行为前,先确认安装版本确实包含这些改动。
当前 adapter 边界覆盖有界范围 `>=0.2.0-rc.2 <0.2.2-0`,包括 rc2、rc3、rc4 与 0.2.1 稳定线;隔离宿主矩阵会将 rc4 依赖图与锁定的 rc2 对照。纯文本 PTC hook 不再作为唯一兼容性依据。

#346 原始报告也包含“行已启用,但发布链停滞”的情况,上述 profile 检查不能证明它已被
修复。若行已启用而预期的作用域工具仍缺失,应提供最小 profile、准确版本、Native/PTC
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@
"./compat/package.json": "./lib/components/compat/package.json",
"./compat/locale/*.json": "./lib/components/compat/locale/*.json",
"./compat/icon": "./lib/components/compat/icon.png",
"./adapter/dsh": {
"default": "./lib/adapter/dsh/host.js"
},
"./client": {
"default": "./lib/client.js"
}
Expand Down Expand Up @@ -193,7 +196,7 @@
},
"peerDependencies": {
"@deepseek-ai/cordis": "^4.0.4",
"@deepseek-ai/dsh": "0.2.0-rc.2 || 0.2.1-rc.2"
"@deepseek-ai/dsh": ">=0.2.0-rc.2 <0.2.2-0"
},
"peerDependenciesMeta": {
"@deepseek-ai/cordis": {
Expand Down Expand Up @@ -253,6 +256,6 @@
},
"engines": {
"node": "^22.19 || >=24",
"dsh": "0.2.0-rc.2 || 0.2.1-rc.2"
"dsh": ">=0.2.0-rc.2 <0.2.2-0"
}
}
5 changes: 4 additions & 1 deletion scripts/validate-manifest.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -562,9 +562,12 @@ check(
typeof pkg.engines?.dsh === 'string' && pkg.engines.dsh === pkg.peerDependencies?.['@deepseek-ai/dsh'],
'engines.dsh and the legacy DSH peer declare the same compatibility range',
)
for (const version of ['0.2.0-rc.2', '0.2.1-rc.2']) {
for (const version of ['0.2.0-rc.2', '0.2.1-rc.2', '0.2.1-rc.3', '0.2.1-rc.4', '0.2.1']) {
check(evaluatePluginCompatibility(pkg, {}, version) === undefined, `the declared range accepts DSH ${version}`)
}
for (const version of ['0.2.0-rc.1', '0.2.2-rc.1', '0.3.0']) {
check(evaluatePluginCompatibility(pkg, {}, version) !== undefined, `the declared range rejects DSH ${version}`)
}
for (const component of [...COMPONENTS, 'background']) {
const resource = pkg.exports?.[`./${component}/icon`]
check(typeof resource === 'string' && fs.existsSync(path.join(PACKAGE_ROOT, resource)),
Expand Down
32 changes: 32 additions & 0 deletions src/adapter/dsh/host.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/** Runtime half of the DSH product adapter. Optional host services stay optional. */
import { createRequire } from 'node:module'
import { pathToFileURL } from 'node:url'
import path from 'node:path'
import type { AtomicApi, BootApi, Context } from './types.js'

export interface CarrierHost { boot: BootApi; yaml: typeof import('yaml'); atomic: AtomicApi }

export function service<T>(ctx: Pick<Context, 'get'>, name: string): T | undefined {
try {
const value = ctx.get(name as never)
return value === undefined || value === null ? undefined : value as T
} catch { return undefined }
}

/** Scope helpers are deliberately lazy: load-time plugin evaluation needs no DSH scope package. */
export async function loadScopes(): Promise<typeof import('@deepseek-ai/dsh-scope')> {
return import('@deepseek-ai/dsh-scope')
}

export async function loadCarrierHost(anchor: string): Promise<CarrierHost> {
if (!path.isAbsolute(anchor)) throw new Error('--host-anchor must be an absolute path to the host package.json.')
const require = createRequire(anchor)
const editorRequire = createRequire(require.resolve('@deepseek-ai/dsh-config-editor'))
const boot = await import(pathToFileURL(require.resolve('@deepseek-ai/dsh-app-boot')).href) as unknown as BootApi
const yaml = await import(pathToFileURL(editorRequire.resolve('yaml')).href) as typeof import('yaml')
const atomic = await import(pathToFileURL(editorRequire.resolve('@deepseek-ai/dsh-atomic-write')).href) as unknown as AtomicApi
for (const name of ['loadProfileDirectory', 'composeEntries', 'readProfilePatches', 'resolveBundleDir', 'loadOverlayPatches'] as const) {
if (typeof boot[name] !== 'function') throw new Error(`Host profile API unavailable: ${name}`)
}
return { boot, yaml, atomic }
}
37 changes: 37 additions & 0 deletions src/adapter/dsh/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* The only source-level boundary to DSH product APIs.
*
* OPS owns its kernels and contracts; this module is the product adapter's type
* surface. It contains type-only exports, so importing OPS never evaluates a
* DSH package at load time. Runtime host lookups belong in host.ts.
*/
export type { Context, Fiber } from '@deepseek-ai/cordis'
export type { EntryOptions } from '@deepseek-ai/cordis-plugin-loader'
export type { Agent } from '@deepseek-ai/dsh-agent'
export type { FileSystem, FsTarget, FsInfo, FsObservation } from '@deepseek-ai/dsh-fs'
export type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm'
export type { Session } from '@deepseek-ai/dsh-session'
export type { SettingsPathOpView } from '@deepseek-ai/dsh-settings/types'
export type { AssembleContext, PromptAssembly, SystemPrompt } from '@deepseek-ai/dsh-system-prompt'
export type { SandboxPolicyService } from '@deepseek-ai/dsh-sandbox-policy'
export type { SubprocessHandle, SubprocessOutputRead, SubprocessOutputReader, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'
export type { InvocationDescriptor, RemoteResult, TypertCodec, TypertGatewayBinding } from '@deepseek-ai/dsh-typert-protocol'
export type { JsonSchemaNode, JsonSchemaType, ObjectJsonSchema, ToolDefinition, ToolExecution,
ToolExecutionResult, ToolExecutionToken, ToolGuard, ToolPresentationMode, ToolRunContext } from '@deepseek-ai/dsh-tools'
export type { default as ToolRuntime } from '@deepseek-ai/dsh-tools'
export type { ConfinedArgv, RunnerFailureRule, SandboxExecutionPolicy, SandboxMode, SandboxProvider } from '@deepseek-ai/dsh-sandbox'
export type { ConfigPageForm, PluginConfigViewProps } from '@deepseek-ai/dsh-client-ui-plugin-manager/client'
export type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'
export type { ProfileContext } from '@deepseek-ai/dsh-app-boot'
export type * as Atomic from '@deepseek-ai/dsh-atomic-write'
export type * as Boot from '@deepseek-ai/dsh-app-boot'
import type {} from '@deepseek-ai/dsh-api-gateway/client'
import type {} from '@deepseek-ai/dsh-client-locale/client'
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
import type {} from '@deepseek-ai/dsh-config-editor'
import type {} from '@deepseek-ai/dsh-typert-registry'

/** Narrow runtime shapes consumed by the profile carrier. */
export type BootApi = Pick<typeof import('@deepseek-ai/dsh-app-boot'),
'loadProfileDirectory' | 'composeEntries' | 'readProfilePatches' | 'resolveBundleDir' | 'loadOverlayPatches' | 'readProfilePlugins'>
export type AtomicApi = Pick<typeof import('@deepseek-ai/dsh-atomic-write'), 'withFileLock' | 'writeFileAtomic'>
2 changes: 1 addition & 1 deletion src/authority-paths.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** Resolve only host-owned anchors; caller-selected descendants retain native no-follow checks. */
import type { SandboxExecutionPolicy } from '@deepseek-ai/dsh-sandbox'
import type { SandboxExecutionPolicy } from './adapter/dsh/types.js'
import fs from 'node:fs'
import path from 'node:path'
import { tmpdir } from 'node:os'
Expand Down
2 changes: 1 addition & 1 deletion src/capabilities/discovery.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { JsonSchemaNode } from '@deepseek-ai/dsh-tools'
import type { JsonSchemaNode } from '../adapter/dsh/types.js'
import type { ParameterSchema } from './types.js'

/** Reviewed, currently implemented advanced operations. Future formats are absent. */
Expand Down
2 changes: 1 addition & 1 deletion src/capabilities/documents.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** Document schemas describe their bounded observation scope; registration remains catalogue-owned. */
import type { JsonSchemaNode } from '@deepseek-ai/dsh-tools'
import type { JsonSchemaNode } from '../adapter/dsh/types.js'
import type { ParameterSchema } from './types.js'
import { STORAGE_REFERENCE } from './result.js'
const string: JsonSchemaNode = { type: 'string' }
Expand Down
2 changes: 1 addition & 1 deletion src/capabilities/file.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** File capability data; no host services or registration side effects. */
import type { JsonSchemaNode } from '@deepseek-ai/dsh-tools'
import type { JsonSchemaNode } from '../adapter/dsh/types.js'
import { DOCUMENT_PARAMETERS, DOCUMENT_DESCRIPTIONS, documentOutput } from './documents.js'
import { STORAGE_REFERENCE } from './result.js'
import type { ParameterSchema } from './types.js'
Expand Down
2 changes: 1 addition & 1 deletion src/capabilities/ptc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** Batch and PTC result schemas; the same result capability also owns a Native projection. */
import type { JsonSchemaNode } from '@deepseek-ai/dsh-tools'
import type { JsonSchemaNode } from '../adapter/dsh/types.js'
import { STORAGE_REFERENCE, RESULT_PAGE_PARAMETERS } from './result.js'
import type { ParameterSchema } from './types.js'

Expand Down
2 changes: 1 addition & 1 deletion src/capabilities/result.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** Shared stored-reference wire metadata and the Native projection of the result capability. */
import type { JsonSchemaNode } from '@deepseek-ai/dsh-tools'
import type { JsonSchemaNode } from '../adapter/dsh/types.js'
import type { ParameterSchema } from './types.js'
const string: JsonSchemaNode = { type: 'string' }
const integer: JsonSchemaNode = { type: 'integer' }
Expand Down
2 changes: 1 addition & 1 deletion src/capabilities/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { JsonSchemaNode } from '@deepseek-ai/dsh-tools'
import type { JsonSchemaNode } from '../adapter/dsh/types.js'
import type { ParameterSchema, SchemaCapability } from './types.js'
export const SDK_PARAMETERS: ParameterSchema = { type: 'object', properties: {
tools: { type: 'array', items: { type: 'string' },
Expand Down
2 changes: 1 addition & 1 deletion src/capabilities/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { JsonSchemaNode, ObjectJsonSchema, ToolPresentationMode } from '@deepseek-ai/dsh-tools'
import type { JsonSchemaNode, ObjectJsonSchema, ToolPresentationMode } from '../adapter/dsh/types.js'

export type Component = 'file' | 'ptc' | 'shell' | 'discovery'
export type ParameterSchema = ObjectJsonSchema & Record<string, unknown> & {
Expand Down
4 changes: 2 additions & 2 deletions src/client/forms.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
import type { ConfigPageForm, PluginConfigViewProps } from '@deepseek-ai/dsh-client-ui-plugin-manager/client'
import type { SettingsPathOpView } from '@deepseek-ai/dsh-settings/types'
import type { ConfigPageForm, PluginConfigViewProps } from '../adapter/dsh/types.js'
import type { SettingsPathOpView } from '../adapter/dsh/types.js'
import type { Translator } from './locales.js'
export type SettingsProps = PluginConfigViewProps & { t: Translator }
export const strings = (value: unknown): string[] => Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []
Expand Down
8 changes: 4 additions & 4 deletions src/client/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Context } from '@deepseek-ai/cordis'
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
import type {} from '@deepseek-ai/dsh-client-locale/client'
import type {} from '@deepseek-ai/dsh-api-gateway/client'
import type { Context } from '../adapter/dsh/types.js'
import type {} from '../adapter/dsh/types.js'
import type {} from '../adapter/dsh/types.js'
import type {} from '../adapter/dsh/types.js'
import { RUNTIME_REMOTE } from '../settings/runtime-contract.js'
import { en, zh } from './locales.js'
import { DiscoveryForm } from './selections.js'
Expand Down
2 changes: 1 addition & 1 deletion src/client/locales.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'
import type { TranslateNS } from '../adapter/dsh/types.js'
export const en = {
replacements: 'Choose which official tools OPS replaces.', discovery: 'Choose discoverable and always-loaded capabilities.', shell: 'Manage Bash and the standard host PowerShell installation.',
modeMinimal: 'Preset enhancement: adds OPS tools to Minimal sessions and replaces the official Windows shell.', modeStandard: 'Preset enhancement: replaces the official read, glob and grep tools and the Windows shell for Standard sessions.',
Expand Down
2 changes: 1 addition & 1 deletion src/components/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Existing profiles still carry this row, so it keeps loading: it accepts any config without
* validating it, publishes nothing, and says once that the row can be deleted.
*/
import type { Context } from '@deepseek-ai/cordis'
import type { Context } from '../../adapter/dsh/types.js'
export const name = "dsh-ops-background"
export const REMOVED_MESSAGE = "dsh-ops: the dsh-ops/background component (FastCtx background jobs) was removed in this version; it publishes no tools. Delete this row from the profile configuration."
export function apply(ctx: Context | null | undefined, _config?: unknown): void {
Expand Down
2 changes: 1 addition & 1 deletion src/components/compat/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** Compatibility switch: keep the official tools exposed instead of replaced. */
import type { Context } from '@deepseek-ai/cordis'
import type { Context } from '../../adapter/dsh/types.js'
import { joinCompatibility } from '../../modes/registry.js'
export const name = 'dsh-ops-compat'
export function apply(ctx: Context): void {
Expand Down
2 changes: 1 addition & 1 deletion src/components/file/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Context } from '@deepseek-ai/cordis'
import type { Context } from '../../adapter/dsh/types.js'
import { applyComponent } from '../../index.js'
export { Config } from '../../settings/file-config.js'
export const name = 'dsh-ops-file'
Expand Down
2 changes: 1 addition & 1 deletion src/components/mode-cordis/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** One enhanced built-in preset. The row publishes OPS only for sessions of that preset. */
import type { Context } from '@deepseek-ai/cordis'
import type { Context } from '../../adapter/dsh/types.js'
import { applyMode } from '../../modes/apply.js'
import { modeConfigForm } from '../../modes/config.js'
export const name = 'dsh-ops-mode-cordis'
Expand Down
2 changes: 1 addition & 1 deletion src/components/mode-minimal/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** One enhanced built-in preset. The row publishes OPS only for sessions of that preset. */
import type { Context } from '@deepseek-ai/cordis'
import type { Context } from '../../adapter/dsh/types.js'
import { applyMode } from '../../modes/apply.js'
import { modeConfigForm } from '../../modes/config.js'
export const name = 'dsh-ops-mode-minimal'
Expand Down
2 changes: 1 addition & 1 deletion src/components/mode-ptc/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** One enhanced built-in preset. The row publishes OPS only for sessions of that preset. */
import type { Context } from '@deepseek-ai/cordis'
import type { Context } from '../../adapter/dsh/types.js'
import { applyMode } from '../../modes/apply.js'
import { modeConfigForm } from '../../modes/config.js'
export const name = 'dsh-ops-mode-ptc'
Expand Down
Loading