mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-10-26 16:55:08 +00:00
refactor(office): trim unused skill metadata and launcher input forwarding
This commit is contained in:
1 parent
908763515e
commit
310596f4aa
31 files changed
+37
-106
No files matched your search
+2
-2
@@ -9,8 +9,8 @@
|
||||
en: a9984a594cdac98d
|
||||
zh: 38768e7699bc8d39
|
||||
/agent-note-progressive-office-skills-with-ordinary-shell-execution/decision:
|
||||
en: 2853f160f97f418e
|
||||
zh: 5d32d39d0075399c
|
||||
en: de7a67877fc91188
|
||||
zh: dbfe4c2a33413372
|
||||
/agent-note-progressive-office-skills-with-ordinary-shell-execution/alternatives-considered:
|
||||
en: 6cdd4d8c54ac419a
|
||||
zh: 1cfeb74d50993632
|
||||
|
||||
@@ -10,7 +10,7 @@ Combined authoring and rendering instructions spend context on operations unrela
|
||||
|
||||
## Decision
|
||||
|
||||
The [skill registry](../../../../packages/skill/skill/README.md) preserves optional `modelCatalogVisibility` metadata and retains every winning candidate. Model catalogs filter `unlisted` entries after scope and same-name resolution; named loading and invocation permissions remain independent. Filesystem frontmatter accepts the same field. Loaded skill instructions can name deferred skills without making a tool registration or activation state.
|
||||
The [skill registry](../../../../packages/skill/skill/README.md) preserves optional `modelCatalogVisibility` metadata and retains every winning candidate. Model catalogs filter `unlisted` entries after scope and same-name resolution; named loading and invocation permissions remain independent. Loaded skill instructions can name deferred skills without making a tool registration or activation state.
|
||||
|
||||
The [Office provider](../../../../packages/skill/skill-office/README.md) advertises only a compact router. Format-specific authoring and rendering, recalculation, and PDF export are separately callable unlisted skills. The model loads them by name and selects rendering for appearance-focused changes unless the user explicitly skips it. Rendering uses a private, randomly named temporary directory inside the task workspace and removes it after inspection. Skills invoke `office-check` and `dsoffice` through ordinary Bash or PowerShell. Common base composition enables immutable skills, the Office command plugin, and the general dependency query only for a supplied runtime. Ordinary Web does not supply or download interpreters. Web presets own tool exposure and minimal presets retain only shell tools.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Status: implemented
|
||||
|
||||
## 决策
|
||||
|
||||
[技能注册表](../../../../packages/skill/skill/README.zh.md) 保留可选的 `modelCatalogVisibility` 元数据,并保留全部胜出候选项。模型目录在作用域和同名解析后过滤 `unlisted` 条目;具名加载与调用权限保持独立。文件系统 frontmatter 接受同一字段。已加载技能说明可以指向延后加载的技能,无需注册工具或引入激活状态。
|
||||
[技能注册表](../../../../packages/skill/skill/README.zh.md) 保留可选的 `modelCatalogVisibility` 元数据,并保留全部胜出候选项。模型目录在作用域和同名解析后过滤 `unlisted` 条目;具名加载与调用权限保持独立。已加载技能说明可以指向延后加载的技能,无需注册工具或引入激活状态。
|
||||
|
||||
[Office 提供者](../../../../packages/skill/skill-office/README.zh.md) 仅展示精简路由。各格式创作以及渲染、重计算、PDF 导出分别作为可具名调用的 unlisted 技能。模型按名称加载;以外观为目标的修改会选择渲染,除非用户明确要求跳过。渲染使用任务工作区内随机命名的私有临时目录,并在检查后删除。技能通过普通 Bash 或 PowerShell 调用 `office-check` 和 `dsoffice`。公共基础组合仅在提供运行时时启用不可变技能、Office 命令插件和通用依赖查询。普通 Web 不提供或下载解释器。Web 预设负责工具展示,minimal 预设仍只保留 shell 工具。
|
||||
|
||||
|
||||
@@ -115,12 +115,6 @@ describe('dsh badge assembled snapshot', () => {
|
||||
},
|
||||
],
|
||||
"isError": false,
|
||||
"meta": {
|
||||
"skill": {
|
||||
"name": "dsh-badge",
|
||||
"provider": "dsh-badge",
|
||||
},
|
||||
},
|
||||
"value": {
|
||||
"content": "# dsh Badge
|
||||
|
||||
|
||||
@@ -3016,7 +3016,7 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-skill-filesystem`
|
||||
|
||||
- `inject`: `skills`
|
||||
- `source`: [`packages/skill/skill-filesystem/src/index.ts:49`](../packages/skill/skill-filesystem/src/index.ts)
|
||||
- `source`: [`packages/skill/skill-filesystem/src/index.ts:48`](../packages/skill/skill-filesystem/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Local filesystem skill provider configuration. */
|
||||
|
||||
@@ -3018,7 +3018,7 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-skill-filesystem`
|
||||
|
||||
- `inject`: `skills`
|
||||
- `source`: [`packages/skill/skill-filesystem/src/index.ts:49`](../packages/skill/skill-filesystem/src/index.ts)
|
||||
- `source`: [`packages/skill/skill-filesystem/src/index.ts:48`](../packages/skill/skill-filesystem/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Local filesystem skill provider configuration. */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
en: e0af59069c89278b
|
||||
zh: 913d0088b2a7296d
|
||||
/deepseek-ai-dsh-skill-filesystem/summary:
|
||||
en: bdcd9ccd7a1b58e5
|
||||
en: ef659bb1fd748f41
|
||||
zh: 9d40999be52526f5
|
||||
/deepseek-ai-dsh-skill-filesystem/table-of-contents:
|
||||
en: d152484eb41ac6b4
|
||||
@@ -21,8 +21,8 @@
|
||||
en: 012a123601c7d8f2
|
||||
zh: 0e13f5e0d2e4ea7a
|
||||
/deepseek-ai-dsh-skill-filesystem/use-this-package/skill-format:
|
||||
en: 46f7c278b2424c4b
|
||||
zh: 06b354fc9b80e539
|
||||
en: 78ac4e731c6a24c1
|
||||
zh: e8c33db4aa0cc527
|
||||
/deepseek-ai-dsh-skill-filesystem/use-this-package/roots-and-priority:
|
||||
en: 265594f30ba5d848
|
||||
zh: 5de6a94864cab8d6
|
||||
@@ -33,7 +33,7 @@
|
||||
en: 77acbd43e89b6043
|
||||
zh: 8169bbbc55f3f114
|
||||
/deepseek-ai-dsh-skill-filesystem/use-this-package/observable-success-and-failures:
|
||||
en: a980728e4d8b3cad
|
||||
en: 272693c35012ffb5
|
||||
zh: bbbe788b11ef567f
|
||||
/deepseek-ai-dsh-skill-filesystem/understand-the-implementation:
|
||||
en: a95eb63f5a570c79
|
||||
|
||||
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
||||
|
||||
## Summary
|
||||
|
||||
Agents can use local skills from the repository, a custom directory, or the user's agent configuration: author a skill as a directory bundle with a `SKILL.md` or a flat `<name>.md` file under any scanned root, and listed, model-invocable skills appear in the session catalog. The provider discovers the project, custom, and user roots, parses each skill's YAML frontmatter, and watches the directories, so new, renamed, or deleted skills reach agents without a restart. Choose it when skills live on disk — the registry (`dsh-skill`) accepts any provider, and another provider can supply skills from elsewhere.
|
||||
Agents can use local skills from the repository, a custom directory, or the user's agent configuration: author a skill as a directory bundle with a `SKILL.md` or a flat `<name>.md` file under any scanned root, and it appears in the session catalog. The provider discovers the project, custom, and user roots, parses each skill's YAML frontmatter, and watches the directories, so new, renamed, or deleted skills reach agents without a restart. Choose it when skills live on disk — the registry (`dsh-skill`) accepts any provider, and another provider can supply skills from elsewhere.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -41,8 +41,6 @@ Catalog entries and loaded skills expose the resolved instruction-file path, so
|
||||
|
||||
The catalog and the body have separate lifecycles: discovery parses frontmatter into the catalog entry, and every load re-reads the current file, so editing a skill body needs no versioning or cache invalidation.
|
||||
|
||||
`modelCatalogVisibility: unlisted` hides a skill from the model catalog while preserving named tool and explicit user invocation. Omission defaults to `listed` in the registry. Only `listed` and `unlisted` are accepted; invalid values skip the skill with a warning. Invocation permission fields remain independent.
|
||||
|
||||
### Roots and priority
|
||||
|
||||
Default roots are scanned in this provider's rank order:
|
||||
@@ -84,7 +82,7 @@ Existing roots are watched, so adding, renaming, or deleting a skill (or editing
|
||||
|
||||
### Observable success and failures
|
||||
|
||||
A valid listed, model-invocable skill under any scanned root appears in the session catalog sorted by name, and loading it returns the current file body. A file without valid frontmatter, an invalid name, or an invalid invocation value is skipped with a warning, so the model catalog receives no per-skill diagnostic and cannot distinguish an absent skill from an invalid one. Unexpected discovery or read failures leave the catalog observation incomplete rather than replacing the last-good view with a misleading deletion.
|
||||
A valid skill under any scanned root appears in the session catalog sorted by name, and loading it returns the current file body. A file without valid frontmatter, an invalid name, or an invalid invocation value is skipped with a warning, so the model catalog receives no per-skill diagnostic and cannot distinguish an absent skill from an invalid one. Unexpected discovery or read failures leave the catalog observation incomplete rather than replacing the last-good view with a misleading deletion.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -41,8 +41,6 @@ skill 可以是被扫描根目录顶层的目录 bundle `<name>/SKILL.md`,也
|
||||
|
||||
目录与正文具有独立的生命周期:发现阶段把 frontmatter 解析进目录条目,每次加载都会重新读取当前文件,因此编辑 skill 正文无需版本化或缓存失效。
|
||||
|
||||
`modelCatalogVisibility: unlisted` 将技能从模型目录隐藏,但保留具名工具调用和用户显式调用。省略时由注册表默认成 `listed`。仅接受 `listed` 与 `unlisted`;无效值会跳过技能并发出警告。调用权限字段保持独立。
|
||||
|
||||
### 根目录与优先级
|
||||
|
||||
默认根按该提供方的 rank 顺序扫描:
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
isSkillName,
|
||||
type SkillCandidate,
|
||||
type SkillDefinition,
|
||||
type ModelCatalogVisibility,
|
||||
type SkillInvocationPolicy,
|
||||
type SkillLookupOptions,
|
||||
type SkillProvider,
|
||||
@@ -113,7 +112,6 @@ interface ParsedSkill extends SkillText {
|
||||
description: string
|
||||
whenToUse?: string
|
||||
invocation: SkillInvocationPolicy
|
||||
modelCatalogVisibility?: ModelCatalogVisibility
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
@@ -217,7 +215,6 @@ export class FileSystemSkillProvider implements SkillProvider {
|
||||
description: parsed.description,
|
||||
...parsed.whenToUse !== undefined ? { whenToUse: parsed.whenToUse } : {},
|
||||
invocation: parsed.invocation,
|
||||
...parsed.modelCatalogVisibility !== undefined ? { modelCatalogVisibility: parsed.modelCatalogVisibility } : {},
|
||||
source: candidate.source,
|
||||
provider: this.name,
|
||||
resourceBase: { kind: 'directory', path: locator.directory },
|
||||
@@ -748,7 +745,6 @@ async function discoverRoot(root: SkillRoot, ctx: Context, provider: string): Pr
|
||||
description: parsed.description,
|
||||
...parsed.whenToUse !== undefined ? { whenToUse: parsed.whenToUse } : {},
|
||||
invocation: parsed.invocation,
|
||||
...parsed.modelCatalogVisibility !== undefined ? { modelCatalogVisibility: parsed.modelCatalogVisibility } : {},
|
||||
provider,
|
||||
source: root.source,
|
||||
rank: root.rank,
|
||||
@@ -833,13 +829,8 @@ async function parseSkillFile(path: string, ctx: Context, signal?: AbortSignal,
|
||||
return undefined
|
||||
}
|
||||
let invocation
|
||||
let modelCatalogVisibility
|
||||
try {
|
||||
invocation = parseInvocationPolicy(parsed.data)
|
||||
modelCatalogVisibility = parsed.data.modelCatalogVisibility
|
||||
if (modelCatalogVisibility !== undefined && modelCatalogVisibility !== 'listed' && modelCatalogVisibility !== 'unlisted') {
|
||||
throw new TypeError('frontmatter field "modelCatalogVisibility" must be listed or unlisted')
|
||||
}
|
||||
} catch (error) {
|
||||
ctx.logger.warn(`skill file ${path} ignored: invalid invocation frontmatter: ${errorMessage(error)}`)
|
||||
return undefined
|
||||
@@ -849,7 +840,6 @@ async function parseSkillFile(path: string, ctx: Context, signal?: AbortSignal,
|
||||
description,
|
||||
...optionalString(parsed.data, 'whenToUse'),
|
||||
invocation,
|
||||
...modelCatalogVisibility !== undefined ? { modelCatalogVisibility } : {},
|
||||
...optionalMetadata(parsed.data),
|
||||
path: raw.path,
|
||||
content: parsed.body.trim(),
|
||||
|
||||
@@ -366,8 +366,6 @@ describe('FileSystemSkillProvider', () => {
|
||||
['legacy-user', 'userInvocable: false'],
|
||||
['bad-string', 'disable-model-invocation: maybe'],
|
||||
['bad-value', 'user-invocable: null'],
|
||||
['bad-visibility', 'modelCatalogVisibility: hidden'],
|
||||
['null-visibility', 'modelCatalogVisibility: null'],
|
||||
] as const
|
||||
for (const [name, field] of invalid) {
|
||||
await writeFile(join(root, `${name}.md`), `---\nname: ${name}\ndescription: ${name}\n${field}\n---\n\nBad.\n`)
|
||||
@@ -922,15 +920,3 @@ describe('FileSystemSkillProvider', () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it.each(['listed', 'unlisted'])('parses %s catalog visibility independently of invocation permissions', async (visibility) => {
|
||||
const home = await tempDir('skill-visibility')
|
||||
const root = join(home, '.dsh/skills')
|
||||
await mkdir(root, { recursive: true })
|
||||
await writeFile(join(root, 'nested.md'), `---\nname: nested\ndescription: Nested operation\nmodelCatalogVisibility: ${visibility}\n---\nBody.\n`)
|
||||
const ctx = await setupLocal(home)
|
||||
expect((await ctx.skills.list())[0]).toMatchObject({
|
||||
modelCatalogVisibility: visibility, invocation: { modelInvocable: true, userInvocable: true },
|
||||
})
|
||||
expect(await ctx.skills.get('nested')).toMatchObject({ modelCatalogVisibility: visibility, content: 'Body.' })
|
||||
})
|
||||
@@ -15,8 +15,8 @@
|
||||
en: c361195a73cf5755
|
||||
zh: 745b04e7be0be369
|
||||
/deepseek-ai-dsh-skill-office/use-this-package:
|
||||
en: a88b2c7c0c9abfa1
|
||||
zh: 0ac3353ba767635d
|
||||
en: f9dfa0282f0aacfd
|
||||
zh: 989a91e5f63b757f
|
||||
/deepseek-ai-dsh-skill-office/use-this-package/progressive-loading:
|
||||
en: 4a7b735989c18499
|
||||
zh: 0116d85b408816c9
|
||||
@@ -24,8 +24,8 @@
|
||||
en: 81efb4310276e7a9
|
||||
zh: 7c7a0fa8f2512c08
|
||||
/deepseek-ai-dsh-skill-office/understand-the-implementation:
|
||||
en: f3218cfa7753f707
|
||||
zh: 799eef2b5ed26bae
|
||||
en: 9c519e2b590c59b1
|
||||
zh: 7cf7e1808d4a7cfd
|
||||
/deepseek-ai-dsh-skill-office/further-exploration:
|
||||
en: a93f275e608a6bab
|
||||
zh: 191e8d36c433e8a2
|
||||
|
||||
@@ -47,7 +47,7 @@ The command plugin accepts separate configuration:
|
||||
| `checkCommand` | Configured Python checker | Executable and fixed arguments for `office-check`; `false` omits that command. |
|
||||
| `assetRoot` | Carrier resources or packaged `assets/` | Directory containing the shared checker and skills. |
|
||||
|
||||
Command overrides require an absolute executable as their first argument. Launchers receive the caller's remaining arguments unchanged and live only while the command plugin is mounted. Windows launchers preserve empty arguments, embedded quotes, trailing backslashes, Unicode paths, and shell pipelines on Windows PowerShell 5.1 and PowerShell 7; PowerShell arrays supplied as one argument become comma-separated text, and pipeline text uses UTF-8 without a byte-order mark. A missing executable returns a nonzero exit code. The shell environment prepends their private directory to each tool call's `PATH`; it does not change the process or user's shell configuration. Disabling a command does not prevent skill loading. `office-check` directly runs the Python checker with the selected carrier interpreter or explicit `checkCommand`; it is omitted when neither is supplied. The checker uses only Python standard-library modules. Command registration and execution neither prepare nor copy a runtime. The general `load_workspace_dependencies` tool supplies authoring interpreters and libraries independently.
|
||||
Command overrides require an absolute executable as their first argument. Launchers receive the caller's remaining arguments unchanged and live only while the command plugin is mounted. Windows launchers preserve empty arguments, embedded quotes, trailing backslashes, and Unicode paths on Windows PowerShell 5.1 and PowerShell 7; PowerShell arrays supplied as one argument become comma-separated text. Launchers accept input file paths and do not forward pipeline input. A missing executable returns a nonzero exit code. The shell environment prepends their private directory to each tool call's `PATH`; it does not change the process or user's shell configuration. Disabling a command does not prevent skill loading. `office-check` directly runs the Python checker with the selected carrier interpreter or explicit `checkCommand`; it is omitted when neither is supplied. The checker uses only Python standard-library modules. Command registration and execution neither prepare nor copy a runtime. The general `load_workspace_dependencies` tool supplies authoring interpreters and libraries independently.
|
||||
|
||||
`DSH_PRIMARY_RUNTIME` selects authoring and checker resources. Kit commands use the carrier's Node.js when supplied, otherwise the host Node.js, so Python-only authoring payloads are supported.
|
||||
|
||||
@@ -103,8 +103,6 @@ The provider reads descriptions at registration and bodies on demand. Only `offi
|
||||
|
||||
The provider registers no tools or activation projection. Loaded skill results remain logged through the generic skill loader. Resume and fork use existing session history and tool declaration reconciliation. The command plugin hides carrier-specific executable paths behind local launchers and registers their directory with the shell environment; disposal removes both the contribution and the directory. Windows launcher directories support long `DSH_HOME` paths; `PATH` entries use ordinary absolute paths. When an executable path exceeds the Windows process launch limit, the plugin temporarily links its parent directory through a short path under the system temporary directory and removes that link on disposal.
|
||||
|
||||
PowerShell 5.1 pipeline launches temporarily replace and restore .NET Framework's cached input encoding to prevent its native-process writer from prepending a byte-order mark. Setting UTF-8 through the public encoding setter requires a console and resets buffered input; the launcher preserves the existing input reader.
|
||||
|
||||
| File | Responsibility |
|
||||
|---|---|
|
||||
| [`src/index.ts`](src/index.ts) | Resource registration and unchanged skill bodies. |
|
||||
|
||||
@@ -47,7 +47,7 @@ kind: "package-reference"
|
||||
| `checkCommand` | 配置的 Python 检查器 | `office-check` 的可执行程序及固定参数;`false` 不提供该命令。 |
|
||||
| `assetRoot` | 载体资源或包内 `assets/` | 包含共享检查器和技能的目录。 |
|
||||
|
||||
命令覆盖的首个参数必须是可执行程序的绝对路径。启动器原样接收调用方的其余参数,仅在命令插件挂载期间存在。Windows 启动器在 Windows PowerShell 5.1 和 PowerShell 7 下保留空参数、内嵌引号、末尾反斜杠、Unicode 路径和 shell 管道;作为单个参数传入的 PowerShell 数组会转为逗号分隔文本,管道文本使用不带字节顺序标记的 UTF-8。可执行程序不存在时,命令返回非零退出码。shell 环境将启动器的私有目录前置到每次工具调用的 `PATH`;不修改进程或用户 shell 配置。禁用命令不阻止技能加载。`office-check` 使用所选载体解释器或显式 `checkCommand` 直接运行 Python 检查器;两者均未提供时不注册该命令。检查器只使用 Python 标准库。命令注册和执行均不准备或复制运行时。通用 `load_workspace_dependencies` 工具独立提供创作解释器和库。
|
||||
命令覆盖的首个参数必须是可执行程序的绝对路径。启动器原样接收调用方的其余参数,仅在命令插件挂载期间存在。Windows 启动器在 Windows PowerShell 5.1 和 PowerShell 7 下保留空参数、内嵌引号、末尾反斜杠和 Unicode 路径;作为单个参数传入的 PowerShell 数组会转为逗号分隔文本。启动器通过文件路径接收输入,不转发管道输入。可执行程序不存在时,命令返回非零退出码。shell 环境将启动器的私有目录前置到每次工具调用的 `PATH`;不修改进程或用户 shell 配置。禁用命令不阻止技能加载。`office-check` 使用所选载体解释器或显式 `checkCommand` 直接运行 Python 检查器;两者均未提供时不注册该命令。检查器只使用 Python 标准库。命令注册和执行均不准备或复制运行时。通用 `load_workspace_dependencies` 工具独立提供创作解释器和库。
|
||||
|
||||
`DSH_PRIMARY_RUNTIME` 选择创作和检查器资源。Kit 命令使用载体提供的 Node.js,否则使用宿主 Node.js,因此支持仅含 Python 的创作载荷。
|
||||
|
||||
@@ -103,8 +103,6 @@ flowchart TD
|
||||
|
||||
提供者不注册工具或激活投影。通用技能加载器记录已加载技能的结果。恢复和 fork 使用现有会话历史及工具声明更新机制。命令插件用本地启动器封装载体专属可执行路径,并将其目录注册到 shell 环境;释放时移除该贡献与目录。Windows 启动器目录支持较长的 `DSH_HOME` 路径;`PATH` 条目使用普通绝对路径。可执行程序路径超过 Windows 进程启动长度限制时,插件在系统临时目录下建立通往其父目录的短路径链接,并在释放时移除该链接。
|
||||
|
||||
PowerShell 5.1 管道调用临时替换并恢复 .NET Framework 缓存的输入编码,防止其原生进程写入器添加字节顺序标记。通过公开的编码设置器设置 UTF-8 需要控制台并会重置已缓冲的输入;启动器保留现有输入读取器。
|
||||
|
||||
| 文件 | 职责 |
|
||||
|---|---|
|
||||
| [`src/index.ts`](src/index.ts) | 注册资源并返回原始技能正文。 |
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: office-docx
|
||||
description: Create, read, edit, and validate Word documents (.docx).
|
||||
modelCatalogVisibility: unlisted
|
||||
---
|
||||
|
||||
# Word documents
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: office-export-pdf
|
||||
description: Convert an Office document to a requested PDF with LibreOffice Kit.
|
||||
modelCatalogVisibility: unlisted
|
||||
---
|
||||
|
||||
# Export an Office document to PDF
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: office-pptx
|
||||
description: Create, read, edit, and validate PowerPoint presentations (.pptx).
|
||||
modelCatalogVisibility: unlisted
|
||||
---
|
||||
|
||||
# PowerPoint presentations
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: office-recalculate
|
||||
description: Refresh spreadsheet formula caches and verify calculated values with LibreOffice Kit.
|
||||
modelCatalogVisibility: unlisted
|
||||
---
|
||||
|
||||
# Recalculate spreadsheet formulas
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: office-render
|
||||
description: Render requested document images or inspect visual layout with LibreOffice Kit.
|
||||
modelCatalogVisibility: unlisted
|
||||
---
|
||||
|
||||
# Document images and visual inspection
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
name: office-xlsx
|
||||
description: Read, create, edit, and validate Excel workbooks, data, and formulas (.xlsx).
|
||||
modelCatalogVisibility: unlisted
|
||||
---
|
||||
|
||||
# Excel workbooks
|
||||
|
||||
@@ -48,21 +48,10 @@ $nativeArgs = @(foreach ($argument in $commandArgs) {
|
||||
$value = if ($argument -is [array]) { $argument -join ',' } else { [string]$argument }
|
||||
'"' + ($value -replace '(\\*)"', $quoteReplacement -replace '(\\+)$', '$1$1') + '"'
|
||||
})`
|
||||
// Framework Process.Start flushes Console.InputEncoding's preamble before PowerShell writes pipeline text.
|
||||
// The private cache avoids the public setter's no-console failure and leaves Console.In's buffered data intact.
|
||||
const inputEncoding = `$inputEncodingField = $null
|
||||
if ($MyInvocation.ExpectingInput -and $PSVersionTable.PSVersion.Major -le 5) {
|
||||
$inputEncodingField = [Console].GetField('_inputEncoding', 'NonPublic,Static')
|
||||
if ($null -eq $inputEncodingField) { throw 'office-commands: Windows PowerShell input encoding field is unavailable' }
|
||||
$savedInputEncoding = $inputEncodingField.GetValue($null)
|
||||
}`
|
||||
writeFileSync(`${script}.ps1`, '\ufeff$PSNativeCommandArgumentPassing = \'Legacy\'\n'
|
||||
+ '$OutputEncoding = [System.Text.UTF8Encoding]::new($false)\n'
|
||||
+ `$commandArgs = @(${args}) + $args\n${nativeArguments}\n${inputEncoding}\n$global:LASTEXITCODE = 127\ntry {\n`
|
||||
+ ' if ($null -ne $inputEncodingField) { $inputEncodingField.SetValue($null, $OutputEncoding) }\n'
|
||||
+ ` if ($MyInvocation.ExpectingInput) { $input | & ${literal(executable)} @nativeArgs }\n`
|
||||
+ ` else { & ${literal(executable)} @nativeArgs }\n`
|
||||
+ '} finally {\n if ($null -ne $inputEncodingField) { $inputEncodingField.SetValue($null, $savedInputEncoding) }\n}\n'
|
||||
+ `$commandArgs = @(${args}) + $args\n${nativeArguments}\n$global:LASTEXITCODE = 127\n`
|
||||
+ `& ${literal(executable)} @nativeArgs\n`
|
||||
+ 'exit $LASTEXITCODE\n', { flag: 'wx' })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ it('removes short executable paths without removing the original interpreter', a
|
||||
})
|
||||
|
||||
it.skipIf(process.platform !== 'win32').each([undefined, 'powershell.exe'])(
|
||||
'preserves native arguments and pipelines through the Windows shell executor: %s', async (pwshPath) => {
|
||||
'preserves native arguments through the Windows shell executor: %s', async (pwshPath) => {
|
||||
const { LocalSubprocessRuntime } = await import('@deepseek-ai/dsh-subprocess-local')
|
||||
const { PwshLocalExecutor } = await import('@deepseek-ai/dsh-pwsh-local')
|
||||
const runtime = join(root, 'runtime 中文', 'a'.repeat(220))
|
||||
@@ -202,7 +202,7 @@ it.skipIf(process.platform !== 'win32').each([undefined, 'powershell.exe'])(
|
||||
const node = join(runtime, 'node.exe'), fixture = join(runtime, 'arguments.mjs')
|
||||
expect(node.length).toBeGreaterThan(260)
|
||||
await copyFile(process.execPath, toNamespacedPath(node))
|
||||
await writeFile(toNamespacedPath(fixture), "import { readFileSync } from 'node:fs'; process.stdout.write(JSON.stringify({ args: process.argv.slice(2), stdin: readFileSync(0, 'utf8') })); process.stderr.write('fixture stderr'); process.exitCode = 7;\n")
|
||||
await writeFile(toNamespacedPath(fixture), "process.stdout.write(JSON.stringify({ args: process.argv.slice(2) })); process.stderr.write('fixture stderr'); process.exitCode = 7;\n")
|
||||
const argumentsToPreserve = ['', 'space and 中文', "apostrophe'value", 'double"quote', 'quote" with space',
|
||||
'slash\\" quote', 'trailing\\', 'space trailing\\', '%PATH%', '!literal!', '&<|>']
|
||||
const quoted = argumentsToPreserve.map(value => `'${value.replaceAll("'", "''")}'`).join(' ')
|
||||
@@ -213,25 +213,14 @@ it.skipIf(process.platform !== 'win32').each([undefined, 'powershell.exe'])(
|
||||
const commands = await ctx.plugin(Commands, { command: [node, fixture, ...argumentsToPreserve], checkCommand: false })
|
||||
const commandDirectory = directory(ctx)
|
||||
if (pwshPath === undefined) expect(commandDirectory.length).toBeGreaterThan(260)
|
||||
// Seeding the Framework cache forces its BOM independently of the runner's code page and attached console.
|
||||
const result = await (await ctx.shell.execute(ctx.shell.resolve({
|
||||
command: `$OutputEncoding = [System.Text.UTF8Encoding]::new($true)
|
||||
if ($PSVersionTable.PSVersion.Major -le 5) {
|
||||
[Console].GetField('_inputEncoding', 'NonPublic,Static').SetValue($null, $OutputEncoding)
|
||||
}
|
||||
$originalInputEncoding = [Console]::InputEncoding
|
||||
$originalInputReader = [Console]::In
|
||||
'piped 中文' | dsoffice ${quoted} | Out-String
|
||||
if (-not [object]::ReferenceEquals($originalInputEncoding, [Console]::InputEncoding)) { throw 'Input encoding was not restored' }
|
||||
if (-not [object]::ReferenceEquals($originalInputReader, [Console]::In)) { throw 'Input reader was replaced' }
|
||||
exit $LASTEXITCODE`,
|
||||
command: `dsoffice ${quoted}; exit $LASTEXITCODE`,
|
||||
env: { PSExecutionPolicyPreference: 'Restricted' }, dshEnv: ctx.shellEnv.collect(execution),
|
||||
}))).result()
|
||||
expect(result.exitCode, result.stderr.text).toBe(7)
|
||||
expect(result.stderr.text).toContain('fixture stderr')
|
||||
const output = JSON.parse(result.stdout.text) as { args: string[]; stdin: string }
|
||||
const output = JSON.parse(result.stdout.text) as { args: string[] }
|
||||
expect(output.args).toEqual([...argumentsToPreserve, ...argumentsToPreserve])
|
||||
expect(output.stdin.trimEnd()).toBe('piped 中文')
|
||||
const pages = await (await ctx.shell.execute(ctx.shell.resolve({
|
||||
command: 'dsoffice --pages 1,3,4; exit $LASTEXITCODE',
|
||||
dshEnv: ctx.shellEnv.collect(execution),
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
en: 440b17442e431e27
|
||||
zh: f8e6d8ef9a954e86
|
||||
/deepseek-ai-dsh-tool-skill/use-this-package/what-the-model-gets:
|
||||
en: 9a257d6161fb2a36
|
||||
zh: 8b9c169cd583d500
|
||||
en: 90e0dd59fa8ebdb0
|
||||
zh: b2275b5eeddb726a
|
||||
/deepseek-ai-dsh-tool-skill/use-this-package/observable-success-and-failures:
|
||||
en: 650872474d12bfcd
|
||||
zh: ecd3e04703975cb3
|
||||
|
||||
@@ -56,7 +56,7 @@ The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-a
|
||||
- **Explicit user invocation.** A `/name` token in direct user input that names a user-invocable skill injects that skill's instructions into the step, without the model having to load it.
|
||||
- **Live catalog updates.** Later membership, description, or visibility changes append a complete replacement catalog; removing every skill appends an empty catalog that retires older names.
|
||||
|
||||
Successful direct loads persist `meta.skill` with the resolved name and provider. `/name` invocations and nested tool loads record the skill name in their `skill-invocation` source; nested loads defer the full instructions until the enclosing result commits.
|
||||
`/name` invocations and nested tool loads record the skill name in their `skill-invocation` source; nested loads defer the full instructions until the enclosing result commits.
|
||||
|
||||
### Observable success and failures
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ agent 可以在会话期间发现并加载 skill。在首次请求前,如果
|
||||
- **用户显式调用。** 直接用户输入中的 `/name` token 若指名某个用户可调用 skill,会把该 skill 的指令注入该步骤,而无需模型自行加载。
|
||||
- **实时目录更新。** 后续成员关系、描述或可见性变化会追加完整的替换目录;删除全部 skill 时会追加空目录,停用较早的名称。
|
||||
|
||||
成功的直接加载在 `meta.skill` 中持久化实际名称和提供方。`/name` 调用及嵌套工具加载在 `skill-invocation` 来源中记录技能名称;嵌套加载将完整指令延迟到外层结果提交后。
|
||||
`/name` 调用及嵌套工具加载在 `skill-invocation` 来源中记录技能名称;嵌套加载将完整指令延迟到外层结果提交后。
|
||||
|
||||
### 可观察的成功与失败
|
||||
|
||||
|
||||
@@ -124,7 +124,6 @@ export function apply(ctx: Context, config: Config = {}): void {
|
||||
},
|
||||
},
|
||||
render: (_args, value) => [{ type: 'text', text: renderSkillContent(value) }],
|
||||
presentationMeta: (_args, value) => ({ skill: { name: value.name, provider: value.provider } }),
|
||||
},
|
||||
async execute(args, exec) {
|
||||
if (!isSkillName(args.name)) {
|
||||
|
||||
@@ -1153,13 +1153,11 @@ describe('user-explicit invocation injection', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('records resolved providers and carries nested skill instructions on the enclosing result', async () => {
|
||||
it('carries nested skill instructions on the enclosing result', async () => {
|
||||
const home = await tempDir('nested-skill')
|
||||
const ctx = await setup(home)
|
||||
try {
|
||||
ctx.skills.register({ name: 'nested-demo', description: 'Nested fixture', source: 'runtime', provider: 'fixture', content: 'Follow these instructions.' })
|
||||
const direct = await ctx.tools.execute({ name: 'skill', callId: ToolCallId('direct'), arguments: { name: 'nested-demo' }, signal: testToolSignal })
|
||||
expect(direct.meta).toEqual({ skill: { name: 'nested-demo', provider: 'fixture' } })
|
||||
ctx.tools.register(defineContentToolFixture({
|
||||
name: 'nested-loader', description: 'Nested fixture', parameters: {},
|
||||
async execute(_args, exec) {
|
||||
|
||||
@@ -15,17 +15,17 @@
|
||||
{"type":"session/title","data":{"title":"Load the Office Word, PowerPoint,","messageSeqs":[8],"source":{"kind":"fallback"}}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_skill","name":"skill","arguments":"{\"name\":\"office-docx\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"stream":[{"type":"chunk","time":1790753571607,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571608,"index":0,"dt":[],"id":"call_office_skill","name":"skill","args":["{\"name\":\"office-docx\"}"]},{"type":"chunk","time":1790753571608,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_skill","name":"skill","arguments":"{\"name\":\"office-docx\"}"}}},{"type":"chunk","time":1790753571608,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_office_skill","name":"skill","arguments":"{\"name\":\"office-docx\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_skill"},"toolCallId":"call_office_skill","content":[{"type":"text","text":"<skill_content name=\"office-docx\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-docx\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Word documents\n\nUse `python-docx` for DOCX creation and ordinary edits. Follow an explicit user or applicable AGENTS.md requirement for a project environment or another library. Otherwise call `load_workspace_dependencies` and execute the returned Python path with its bundled libraries. Do not install packages or discover a system Python for the default workflow. If the tool is unavailable, use an already configured environment and report a missing dependency only when it prevents the requested operation.\n\nKeep source scripts, intermediate files, and final documents in the task workspace; the runtime and this skill directory are read-only resources. Use the user's requested language and preserve an existing document's design unless a redesign is requested.\n\n## Create and edit\n\nFor existing files, inspect paragraphs, runs, tables, sections, headers, and footers before changing the affected content. Save to a new file unless the user requests an in-place edit. Replacing a paragraph's `.text` destroys its run formatting; change the relevant runs when formatting must survive. Reconstructing the whole document can lose features outside python-docx's supported editing API.\n\nUse paragraph styles for headings and body text. Size tables for the section that contains them, and account for merged cells and nested tables. Chinese, Japanese, and Korean text may need an explicit `w:eastAsia` font assignment in addition to `run.font.name`; font names alone do not establish glyph availability or rendered appearance.\n\nFor a new document, use the selected Python executable:\n\n```python\nfrom docx import Document\n\ndocument = Document()\ndocument.add_heading(\"Project report\", level=0)\ndocument.add_paragraph(\"Summary\", style=\"Heading 1\")\ndocument.add_paragraph(\"The requested findings go here.\")\ndocument.save(\"report.docx\")\n```\n\npython-docx does not paginate or render documents. Do not represent ordinary replacement, colored text, or comments as tracked changes. When real revisions or unsupported OOXML features matter, preserve their package parts and verify the requested operation rather than silently discarding them.\n\n## Check and deliver\n\nRun the shared structural checker when `office-check` is available:\n\n```text\noffice-check <document.docx> --out <checks.json>\n```\n\nIt checks ZIP/XML integrity and internal relationships, and reports paragraphs, logical table dimensions, and sections. Optional `--contains TEXT` arguments assert required text. A successful structural check does not verify pagination, clipping, fonts, or visual appearance. Compare the summary and reopened document with the user's request, including unchanged content that matters to an edit.\n\nIf `office-check` is unavailable, use an already configured environment to check the ZIP/XML package and internal relationships. Report the missing environment if those checks cannot run; do not claim structural validation.\n\nDeliver after the requested content and structural checks pass. Creating a file or changing content with incidental basic formatting does not require additional operations. Load `office-render` for requested images or visual inspection and for appearance-focused styling, spacing, sizing, or alignment changes unless the user explicitly skips rendering. For selected pages in PowerShell, use `dsoffice render --input \"report.docx\" --output-dir \"<new-directory>\" --pages \"1,3,4\"`; quote the comma-separated page list. For PDF output load `office-export-pdf`.\n\nCall `present({\"files\":[{\"path\":\"report.docx\"}]})` with the actual final DOCX path. It exposes the current source file without copying or preserving its bytes, so keep that file in place and do not present temporary QA reports unless requested. If `present` is unavailable, provide the final workspace path using the session's supported file delivery method.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:6}}"},"meta":{"skill":{"name":"office-docx","provider":"dsh-office"}}},"sourceEventSeqs":[15],"surfaceOp":"append"}
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_skill"},"toolCallId":"call_office_skill","content":[{"type":"text","text":"<skill_content name=\"office-docx\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-docx\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Word documents\n\nUse `python-docx` for DOCX creation and ordinary edits. Follow an explicit user or applicable AGENTS.md requirement for a project environment or another library. Otherwise call `load_workspace_dependencies` and execute the returned Python path with its bundled libraries. Do not install packages or discover a system Python for the default workflow. If the tool is unavailable, use an already configured environment and report a missing dependency only when it prevents the requested operation.\n\nKeep source scripts, intermediate files, and final documents in the task workspace; the runtime and this skill directory are read-only resources. Use the user's requested language and preserve an existing document's design unless a redesign is requested.\n\n## Create and edit\n\nFor existing files, inspect paragraphs, runs, tables, sections, headers, and footers before changing the affected content. Save to a new file unless the user requests an in-place edit. Replacing a paragraph's `.text` destroys its run formatting; change the relevant runs when formatting must survive. Reconstructing the whole document can lose features outside python-docx's supported editing API.\n\nUse paragraph styles for headings and body text. Size tables for the section that contains them, and account for merged cells and nested tables. Chinese, Japanese, and Korean text may need an explicit `w:eastAsia` font assignment in addition to `run.font.name`; font names alone do not establish glyph availability or rendered appearance.\n\nFor a new document, use the selected Python executable:\n\n```python\nfrom docx import Document\n\ndocument = Document()\ndocument.add_heading(\"Project report\", level=0)\ndocument.add_paragraph(\"Summary\", style=\"Heading 1\")\ndocument.add_paragraph(\"The requested findings go here.\")\ndocument.save(\"report.docx\")\n```\n\npython-docx does not paginate or render documents. Do not represent ordinary replacement, colored text, or comments as tracked changes. When real revisions or unsupported OOXML features matter, preserve their package parts and verify the requested operation rather than silently discarding them.\n\n## Check and deliver\n\nRun the shared structural checker when `office-check` is available:\n\n```text\noffice-check <document.docx> --out <checks.json>\n```\n\nIt checks ZIP/XML integrity and internal relationships, and reports paragraphs, logical table dimensions, and sections. Optional `--contains TEXT` arguments assert required text. A successful structural check does not verify pagination, clipping, fonts, or visual appearance. Compare the summary and reopened document with the user's request, including unchanged content that matters to an edit.\n\nIf `office-check` is unavailable, use an already configured environment to check the ZIP/XML package and internal relationships. Report the missing environment if those checks cannot run; do not claim structural validation.\n\nDeliver after the requested content and structural checks pass. Creating a file or changing content with incidental basic formatting does not require additional operations. Load `office-render` for requested images or visual inspection and for appearance-focused styling, spacing, sizing, or alignment changes unless the user explicitly skips rendering. For selected pages in PowerShell, use `dsoffice render --input \"report.docx\" --output-dir \"<new-directory>\" --pages \"1,3,4\"`; quote the comma-separated page list. For PDF output load `office-export-pdf`.\n\nCall `present({\"files\":[{\"path\":\"report.docx\"}]})` with the actual final DOCX path. It exposes the current source file without copying or preserving its bytes, so keep that file in place and do not present temporary QA reports unless requested. If `present` is unavailable, provide the final workspace path using the session's supported file delivery method.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:6}}"}},"sourceEventSeqs":[15],"surfaceOp":"append"}
|
||||
{"type":"step/end","data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_2","name":"skill","arguments":"{\"name\":\"office-pptx\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"stream":[{"type":"chunk","time":1790753571639,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571639,"index":0,"dt":[],"id":"call_office_2","name":"skill","args":["{\"name\":\"office-pptx\"}"]},{"type":"chunk","time":1790753571639,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_2","name":"skill","arguments":"{\"name\":\"office-pptx\"}"}}},{"type":"chunk","time":1790753571639,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":2,"callId":"call_office_2","name":"skill","arguments":"{\"name\":\"office-pptx\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":2,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_2"},"toolCallId":"call_office_2","content":[{"type":"text","text":"<skill_content name=\"office-pptx\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-pptx\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# PowerPoint presentations\n\nFollow an explicit user or applicable AGENTS.md requirement for an environment or library. Otherwise call `load_workspace_dependencies` and use its Python executable and bundled presentation libraries. Do not install npm or pip packages or locate a system interpreter for the default workflow. If the tool is unavailable, use an already configured environment and report a missing dependency only when it prevents the requested operation.\n\nKeep scripts and output files in the task workspace. The runtime and skill directory contain shared read-only resources. Match the requested slide language and the supplied presentation's design when editing it.\n\n## Create and edit\n\nUse `python-pptx` to inspect or modify an existing presentation. Inspect slide layouts, text runs, images, tables, and charts before editing. Change only the requested content, preserve mixed text formatting, and save to a new file unless the user requests an in-place edit. Rebuilding slides can discard unsupported animation, SmartArt, or other extension content.\n\nFor a new deck, use `python-pptx` with editable text, tables, and charts. Use local image assets rather than network-dependent image URLs. Set slide dimensions, text sizes, and chart data explicitly.\n\nA minimal editable deck, run with the selected Python executable:\n\n```python\nfrom pptx import Presentation\nfrom pptx.chart.data import CategoryChartData\nfrom pptx.enum.chart import XL_CHART_TYPE\nfrom pptx.util import Inches, Pt\n\npresentation = Presentation()\npresentation.slide_width = Inches(13.333)\npresentation.slide_height = Inches(7.5)\nslide = presentation.slides.add_slide(presentation.slide_layouts[6])\ntitle = slide.shapes.add_textbox(Inches(0.6), Inches(0.4), Inches(12), Inches(0.8))\nrun = title.text_frame.paragraphs[0].add_run()\nrun.text = \"Quarterly report\"\nrun.font.size = Pt(30)\ndata = CategoryChartData()\ndata.categories = [\"Q1\", \"Q2\"]\ndata.add_series(\"Revenue\", [12, 18])\nslide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED,\n Inches(0.8), Inches(1.6), Inches(11.5), Inches(4.8), data)\npresentation.save(\"report.pptx\")\n```\n\nUse `Inches` or `Cm` for positions and sizes and `Pt` for font sizes. To edit a generated title while retaining its other slides and charts:\n\n```python\nfrom pptx import Presentation\n\npresentation = Presentation(\"report.pptx\")\nfor shape in presentation.slides[0].shapes:\n if shape.has_text_frame and shape.text == \"Quarterly report\":\n shape.text_frame.paragraphs[0].runs[0].text = \"Quarterly results\"\npresentation.save(\"report-edited.pptx\")\n```\n\nCheck that text and images fit the slide dimensions, titles form a useful sequence, and chart labels agree with source values. Paragraph alignment does not move a text box: when a title must be centered on the slide, center both its paragraph and the text box against `presentation.slide_width`, then reopen to verify both. A native chart's embedded workbook is part of the deliverable and must contain the intended data. Library support for writing PPTX is not a rendering engine or a guarantee that every PowerPoint feature survives editing.\n\n## Check and deliver\n\nRun the shared structural checker when `office-check` is available:\n\n```text\noffice-check <presentation.pptx> --out <checks.json>\n```\n\nIt checks ZIP/XML integrity and internal relationships and reports slide count and extracted text. Use repeated `--contains TEXT` arguments for required slide text and `--count N` for a requested slide count; `--contains` excludes chart text and speaker notes. Reopen the file to check the requested edits, chart data, and notes. Structural success does not establish text fit, alignment, readable contrast, or rendering fidelity.\n\nIf `office-check` is unavailable, use an already configured environment to check the ZIP/XML package and internal relationships. Report the missing environment if those checks cannot run; do not claim structural validation.\n\nDeliver after the requested content and structural checks pass. Creating a file or changing content with incidental basic formatting does not require additional operations. Load `office-render` for requested images or visual inspection and for appearance-focused styling, spacing, sizing, or alignment changes unless the user explicitly skips rendering. For selected slides in PowerShell, use `dsoffice render --input \"report-edited.pptx\" --output-dir \"<new-directory>\" --pages \Line truncated
|
||||
{"type":"tool/result","data":{"turn":1,"step":2,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_2"},"toolCallId":"call_office_2","content":[{"type":"text","text":"<skill_content name=\"office-pptx\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-pptx\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# PowerPoint presentations\n\nFollow an explicit user or applicable AGENTS.md requirement for an environment or library. Otherwise call `load_workspace_dependencies` and use its Python executable and bundled presentation libraries. Do not install npm or pip packages or locate a system interpreter for the default workflow. If the tool is unavailable, use an already configured environment and report a missing dependency only when it prevents the requested operation.\n\nKeep scripts and output files in the task workspace. The runtime and skill directory contain shared read-only resources. Match the requested slide language and the supplied presentation's design when editing it.\n\n## Create and edit\n\nUse `python-pptx` to inspect or modify an existing presentation. Inspect slide layouts, text runs, images, tables, and charts before editing. Change only the requested content, preserve mixed text formatting, and save to a new file unless the user requests an in-place edit. Rebuilding slides can discard unsupported animation, SmartArt, or other extension content.\n\nFor a new deck, use `python-pptx` with editable text, tables, and charts. Use local image assets rather than network-dependent image URLs. Set slide dimensions, text sizes, and chart data explicitly.\n\nA minimal editable deck, run with the selected Python executable:\n\n```python\nfrom pptx import Presentation\nfrom pptx.chart.data import CategoryChartData\nfrom pptx.enum.chart import XL_CHART_TYPE\nfrom pptx.util import Inches, Pt\n\npresentation = Presentation()\npresentation.slide_width = Inches(13.333)\npresentation.slide_height = Inches(7.5)\nslide = presentation.slides.add_slide(presentation.slide_layouts[6])\ntitle = slide.shapes.add_textbox(Inches(0.6), Inches(0.4), Inches(12), Inches(0.8))\nrun = title.text_frame.paragraphs[0].add_run()\nrun.text = \"Quarterly report\"\nrun.font.size = Pt(30)\ndata = CategoryChartData()\ndata.categories = [\"Q1\", \"Q2\"]\ndata.add_series(\"Revenue\", [12, 18])\nslide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED,\n Inches(0.8), Inches(1.6), Inches(11.5), Inches(4.8), data)\npresentation.save(\"report.pptx\")\n```\n\nUse `Inches` or `Cm` for positions and sizes and `Pt` for font sizes. To edit a generated title while retaining its other slides and charts:\n\n```python\nfrom pptx import Presentation\n\npresentation = Presentation(\"report.pptx\")\nfor shape in presentation.slides[0].shapes:\n if shape.has_text_frame and shape.text == \"Quarterly report\":\n shape.text_frame.paragraphs[0].runs[0].text = \"Quarterly results\"\npresentation.save(\"report-edited.pptx\")\n```\n\nCheck that text and images fit the slide dimensions, titles form a useful sequence, and chart labels agree with source values. Paragraph alignment does not move a text box: when a title must be centered on the slide, center both its paragraph and the text box against `presentation.slide_width`, then reopen to verify both. A native chart's embedded workbook is part of the deliverable and must contain the intended data. Library support for writing PPTX is not a rendering engine or a guarantee that every PowerPoint feature survives editing.\n\n## Check and deliver\n\nRun the shared structural checker when `office-check` is available:\n\n```text\noffice-check <presentation.pptx> --out <checks.json>\n```\n\nIt checks ZIP/XML integrity and internal relationships and reports slide count and extracted text. Use repeated `--contains TEXT` arguments for required slide text and `--count N` for a requested slide count; `--contains` excludes chart text and speaker notes. Reopen the file to check the requested edits, chart data, and notes. Structural success does not establish text fit, alignment, readable contrast, or rendering fidelity.\n\nIf `office-check` is unavailable, use an already configured environment to check the ZIP/XML package and internal relationships. Report the missing environment if those checks cannot run; do not claim structural validation.\n\nDeliver after the requested content and structural checks pass. Creating a file or changing content with incidental basic formatting does not require additional operations. Load `office-render` for requested images or visual inspection and for appearance-focused styling, spacing, sizing, or alignment changes unless the user explicitly skips rendering. For selected slides in PowerShell, use `dsoffice render --input \"report-edited.pptx\" --output-dir \"<new-directory>\" --pages \Line truncated
|
||||
{"type":"step/end","data":{"turn":1,"step":2}}
|
||||
{"type":"step/start","data":{"turn":1,"step":3}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_3","name":"skill","arguments":"{\"name\":\"office-xlsx\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"stream":[{"type":"chunk","time":1790753571666,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571666,"index":0,"dt":[],"id":"call_office_3","name":"skill","args":["{\"name\":\"office-xlsx\"}"]},{"type":"chunk","time":1790753571666,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_3","name":"skill","arguments":"{\"name\":\"office-xlsx\"}"}}},{"type":"chunk","time":1790753571666,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":3,"callId":"call_office_3","name":"skill","arguments":"{\"name\":\"office-xlsx\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":3,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_3"},"toolCallId":"call_office_3","content":[{"type":"text","text":"<skill_content name=\"office-xlsx\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-xlsx\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Excel workbooks\n\nFollow an explicit user or applicable AGENTS.md requirement for an environment or library. Otherwise call `load_workspace_dependencies` and run its Python executable with bundled `openpyxl` and `pandas`. Do not install packages or search for a system Python for the default workflow. If the tool is unavailable, use an already configured environment and report a missing dependency only when it prevents the requested operation.\n\nKeep scripts, working files, and outputs in the task workspace. The runtime and skill directory are shared read-only resources. Save to a new workbook unless the user requests an in-place edit.\n\n## Read and modify\n\nUse `openpyxl` for existing XLSX workbooks and targeted cell or style changes. Load with `data_only=False` when formulas must survive. Inspect sheet names, the affected cell types, formulas, styles, merged ranges, and referenced ranges before editing. Check the saved file by reopening it, including unchanged content that the request requires preserving.\n\nUse pandas for data analysis and transformations. A DataFrame is not the workbook: exporting it over an existing file can lose sheets, formulas, charts, and formatting. Write analysis results back to the intended ranges with openpyxl. `XlsxWriter` can create new workbooks, but cannot read or modify existing ones.\n\nFor a new workbook, the selected Python environment can write editable values, styles, and formulas directly:\n\n```python\nfrom openpyxl import Workbook\nfrom openpyxl.styles import Font\n\nworkbook = Workbook()\nsheet = workbook.active\nsheet.title = \"Revenue\"\nfor row in [(\"Quarter\", \"Revenue\"), (\"Q1\", 12), (\"Q2\", 18), (\"Total\", \"=SUM(B2:B3)\")]:\n sheet.append(row)\nfor cell in sheet[1]:\n cell.font = Font(bold=True)\nsheet.column_dimensions[\"A\"].width = 18\nsheet.column_dimensions[\"B\"].width = 18\nworkbook.save(\"report.xlsx\")\n```\n\nPreserve numbers, dates, booleans, and identifiers as the intended cell types; formatting is not a type conversion. For modifications, load the existing file with `openpyxl.load_workbook(\"input.xlsx\", data_only=False)`, change the requested ranges, and save a separate result. Avoid a DataFrame round trip when workbook features must survive.\n\nWriting a formula does not calculate its result. openpyxl and XlsxWriter do not evaluate formulas; `data_only=True` returns cached values that may be absent or stale. When calculated results must be refreshed, load `office-recalculate`. Do not replace requested formulas with constants or report stale values as newly calculated results.\n\nDo not rename `.xls`, `.xlsb`, encrypted files, or macro-enabled files to `.xlsx`. They need an appropriate supported operation. `keep_vba=True` can preserve VBA package content in an XLSM workflow, but does not execute or edit macros and does not guarantee every advanced workbook feature survives. Preserve the original and verify such requirements explicitly.\n\n## Check and deliver\n\nRun the shared structural checker when `office-check` is available:\n\n```text\noffice-check <workbook.xlsx> --out <checks.json>\n```\n\nIt checks ZIP/XML integrity and internal relationships, and reports sheet names, populated-cell counts, and formula counts. Repeated `--contains TEXT` arguments check string cells and sheet names, and `--count N` checks sheet count. `--contains` excludes numeric cells and does not validate formula results; verify those separately with openpyxl. The checker does not calculate formulas or judge workbook appearance. Compare relevant values, types, formulas, styles, and totals with the task's source data.\n\nIf `office-check` is unavailable, use an already configured environment to check the ZIP/XML package and internal relationships. Report the missing environment if those checks cannot run; do not claim structural validation.\n\nLoad `office-render` for requested images or visual inspection and whenever the user's primary task targets appearance, including cell fill colors, text alignment, spacing, or sizing. These appearance changes require rendering even without a separate visual-check request, unless the user explicitly skips it. New workbooks and data or formula edits do not require rendering solely because they include incidental basic formatting. In particular, bold headers and number formats accompanying data edits do not require loading `office-render` or running its commands.\n\nLoad `office-recalculate` when refreshed calculated values are needeLine truncated
|
||||
{"type":"tool/result","data":{"turn":1,"step":3,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_3"},"toolCallId":"call_office_3","content":[{"type":"text","text":"<skill_content name=\"office-xlsx\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-xlsx\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Excel workbooks\n\nFollow an explicit user or applicable AGENTS.md requirement for an environment or library. Otherwise call `load_workspace_dependencies` and run its Python executable with bundled `openpyxl` and `pandas`. Do not install packages or search for a system Python for the default workflow. If the tool is unavailable, use an already configured environment and report a missing dependency only when it prevents the requested operation.\n\nKeep scripts, working files, and outputs in the task workspace. The runtime and skill directory are shared read-only resources. Save to a new workbook unless the user requests an in-place edit.\n\n## Read and modify\n\nUse `openpyxl` for existing XLSX workbooks and targeted cell or style changes. Load with `data_only=False` when formulas must survive. Inspect sheet names, the affected cell types, formulas, styles, merged ranges, and referenced ranges before editing. Check the saved file by reopening it, including unchanged content that the request requires preserving.\n\nUse pandas for data analysis and transformations. A DataFrame is not the workbook: exporting it over an existing file can lose sheets, formulas, charts, and formatting. Write analysis results back to the intended ranges with openpyxl. `XlsxWriter` can create new workbooks, but cannot read or modify existing ones.\n\nFor a new workbook, the selected Python environment can write editable values, styles, and formulas directly:\n\n```python\nfrom openpyxl import Workbook\nfrom openpyxl.styles import Font\n\nworkbook = Workbook()\nsheet = workbook.active\nsheet.title = \"Revenue\"\nfor row in [(\"Quarter\", \"Revenue\"), (\"Q1\", 12), (\"Q2\", 18), (\"Total\", \"=SUM(B2:B3)\")]:\n sheet.append(row)\nfor cell in sheet[1]:\n cell.font = Font(bold=True)\nsheet.column_dimensions[\"A\"].width = 18\nsheet.column_dimensions[\"B\"].width = 18\nworkbook.save(\"report.xlsx\")\n```\n\nPreserve numbers, dates, booleans, and identifiers as the intended cell types; formatting is not a type conversion. For modifications, load the existing file with `openpyxl.load_workbook(\"input.xlsx\", data_only=False)`, change the requested ranges, and save a separate result. Avoid a DataFrame round trip when workbook features must survive.\n\nWriting a formula does not calculate its result. openpyxl and XlsxWriter do not evaluate formulas; `data_only=True` returns cached values that may be absent or stale. When calculated results must be refreshed, load `office-recalculate`. Do not replace requested formulas with constants or report stale values as newly calculated results.\n\nDo not rename `.xls`, `.xlsb`, encrypted files, or macro-enabled files to `.xlsx`. They need an appropriate supported operation. `keep_vba=True` can preserve VBA package content in an XLSM workflow, but does not execute or edit macros and does not guarantee every advanced workbook feature survives. Preserve the original and verify such requirements explicitly.\n\n## Check and deliver\n\nRun the shared structural checker when `office-check` is available:\n\n```text\noffice-check <workbook.xlsx> --out <checks.json>\n```\n\nIt checks ZIP/XML integrity and internal relationships, and reports sheet names, populated-cell counts, and formula counts. Repeated `--contains TEXT` arguments check string cells and sheet names, and `--count N` checks sheet count. `--contains` excludes numeric cells and does not validate formula results; verify those separately with openpyxl. The checker does not calculate formulas or judge workbook appearance. Compare relevant values, types, formulas, styles, and totals with the task's source data.\n\nIf `office-check` is unavailable, use an already configured environment to check the ZIP/XML package and internal relationships. Report the missing environment if those checks cannot run; do not claim structural validation.\n\nLoad `office-render` for requested images or visual inspection and whenever the user's primary task targets appearance, including cell fill colors, text alignment, spacing, or sizing. These appearance changes require rendering even without a separate visual-check request, unless the user explicitly skips it. New workbooks and data or formula edits do not require rendering solely because they include incidental basic formatting. In particular, bold headers and number formats accompanying data edits do not require loading `office-render` or running its commands.\n\nLoad `office-recalculate` when refreshed calculated values are needeLine truncated
|
||||
{"type":"step/end","data":{"turn":1,"step":3}}
|
||||
{"type":"step/start","data":{"turn":1,"step":4}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_4","name":"read","arguments":"{\"file_path\":\"office-skills/office/references/sidecar.md\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"stream":[{"type":"chunk","time":1790753571694,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571694,"index":0,"dt":[],"id":"call_office_4","name":"read","args":["{\"file_path\":\"office-skills/office/references/sidecar.md\"}"]},{"type":"chunk","time":1790753571695,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_4","name":"read","arguments":"{\"file_path\":\"office-skills/office/references/sidecar.md\"}"}}},{"type":"chunk","time":1790753571695,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
|
||||
@@ -15,17 +15,17 @@
|
||||
{"type":"session/title","data":{"title":"Load the Office rendering, PDF","messageSeqs":[8],"source":{"kind":"fallback"}}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_skill","name":"skill","arguments":"{\"name\":\"office-render\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"stream":[{"type":"chunk","time":1790753571607,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571608,"index":0,"dt":[],"id":"call_office_skill","name":"skill","args":["{\"name\":\"office-render\"}"]},{"type":"chunk","time":1790753571608,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_skill","name":"skill","arguments":"{\"name\":\"office-render\"}"}}},{"type":"chunk","time":1790753571608,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_office_skill","name":"skill","arguments":"{\"name\":\"office-render\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_skill"},"toolCallId":"call_office_skill","content":[{"type":"text","text":"<skill_content name=\"office-render\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-render\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Document images and visual inspection\n\nUse the installed LibreOffice Kit CLI through the shell with `dsoffice`. Prefer bundled LibreOffice unless the user requests another installation. If the Office sidecar is missing, follow [sidecar setup](../office/references/sidecar.md): ask whether the user wants to download it and install only after they agree. Do not invoke system soffice, use npx, install a replacement renderer, or build an alternative rendering pipeline to work around a failed render with an installed sidecar.\n\nBefore generating images only for inspection, establish that the current model accepts images. Otherwise finish the applicable content and structure checks and report the requested visual check as unavailable. Do not generate unreadable previews, retry image reads, or choose a second model. Requested image exports can still be delivered.\n\n## Render the saved deliverable\n\nKeep the saved deliverable in the task workspace. Create a private, uniquely named temporary parent inside that workspace and pass a child path that does not yet exist as `--output-dir`; the CLI creates that child. On POSIX, use `preview_root=$(mktemp -d \"./.dsh-office.XXXXXXXX\")` (owner-only permissions) and `--output-dir \"$preview_root/render\"`. On PowerShell, create a parent named `.dsh-office-` plus `[guid]::NewGuid().ToString('N')` under the task workspace and pass an uncreated `render` child; it inherits the workspace ACL. Quote each input and output path. Retain the parent until image inspection finishes, then remove only that parent, including after a failed render. Never use a fixed directory name or remove the workspace itself.\n\n```text\ndsoffice render --input <final-file> --output-dir <new-directory> --pages \"1,3,4\"\ndsoffice render --input <final-workbook.xlsx> --output-dir <new-directory> --sheet <exact-name> --range <A1-range>\n```\n\nFor DOCX, PPTX, or PDF, batch requested pages/slides in one call. In PowerShell, quote comma-separated `--pages` values so they remain one argument. Inspect all pages only for a requested whole-document review. For worksheets, choose the exact affected range, including chart/drawing regions; worksheet numbers are not PDF page numbers. Inspect the final saved file, reuse existing images for an unchanged source, and rerender only after requested source changes or for previously unrendered regions. Change print areas or scaling only when the user requests print layout.\n\nRead the returned JSON manifest for image paths, page counts, fragment rectangles, and missing-font diagnostics. Use the session's image-reading tool to inspect the requested images. Check clipping, alignment, headings, table widths, contrast, chart labels, and number formats as relevant to the task. A successful command or image read alone does not establish a usable preview; guessed text geometry does not establish overflow.\n\n## Failed or blank previews\n\nFor populated content, a fully transparent or uniformly blank image is a renderer failure. If a pixel check is needed, composite RGBA onto white first; raw RGB under transparent pixels can look nonblank. Check once and do not reread the same image. Stop visual checks for the task immediately after a blank result. This overrides the rerender-after-edit guidance above: do not render or read images again, even after editing or copying the source, or try another range, page, sheet, DPI, output format, diagnostic export, or print setting. Preserve the usable source and requested outputs and finish applicable content/data checks.\n\nIf content and structure checks pass, name the saved file and verified edits as needed, then include exactly one visual-status sentence: \"Content and structure checks passed; visual inspection was not completed.\" in English, or \"内容与结构检查通过;视觉检查未完成。\" in Chinese. Do not add a render or preview bullet, explain why inspection stopped, or describe the image or pixels. Report content or structure failures separately; never say all checks passed or claim visual verification.\n\nLibreOffice output can differ from Word, PowerPoint, or Excel. Images do not certify animation/media playback, refresh formula caches in the source workbook, or guarantee native application fidelity. Deliver requested files through `present` when available; keep the files in place. Do not deliver inspection images or reports unless requested.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:6}}Line truncated
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_skill"},"toolCallId":"call_office_skill","content":[{"type":"text","text":"<skill_content name=\"office-render\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-render\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Document images and visual inspection\n\nUse the installed LibreOffice Kit CLI through the shell with `dsoffice`. Prefer bundled LibreOffice unless the user requests another installation. If the Office sidecar is missing, follow [sidecar setup](../office/references/sidecar.md): ask whether the user wants to download it and install only after they agree. Do not invoke system soffice, use npx, install a replacement renderer, or build an alternative rendering pipeline to work around a failed render with an installed sidecar.\n\nBefore generating images only for inspection, establish that the current model accepts images. Otherwise finish the applicable content and structure checks and report the requested visual check as unavailable. Do not generate unreadable previews, retry image reads, or choose a second model. Requested image exports can still be delivered.\n\n## Render the saved deliverable\n\nKeep the saved deliverable in the task workspace. Create a private, uniquely named temporary parent inside that workspace and pass a child path that does not yet exist as `--output-dir`; the CLI creates that child. On POSIX, use `preview_root=$(mktemp -d \"./.dsh-office.XXXXXXXX\")` (owner-only permissions) and `--output-dir \"$preview_root/render\"`. On PowerShell, create a parent named `.dsh-office-` plus `[guid]::NewGuid().ToString('N')` under the task workspace and pass an uncreated `render` child; it inherits the workspace ACL. Quote each input and output path. Retain the parent until image inspection finishes, then remove only that parent, including after a failed render. Never use a fixed directory name or remove the workspace itself.\n\n```text\ndsoffice render --input <final-file> --output-dir <new-directory> --pages \"1,3,4\"\ndsoffice render --input <final-workbook.xlsx> --output-dir <new-directory> --sheet <exact-name> --range <A1-range>\n```\n\nFor DOCX, PPTX, or PDF, batch requested pages/slides in one call. In PowerShell, quote comma-separated `--pages` values so they remain one argument. Inspect all pages only for a requested whole-document review. For worksheets, choose the exact affected range, including chart/drawing regions; worksheet numbers are not PDF page numbers. Inspect the final saved file, reuse existing images for an unchanged source, and rerender only after requested source changes or for previously unrendered regions. Change print areas or scaling only when the user requests print layout.\n\nRead the returned JSON manifest for image paths, page counts, fragment rectangles, and missing-font diagnostics. Use the session's image-reading tool to inspect the requested images. Check clipping, alignment, headings, table widths, contrast, chart labels, and number formats as relevant to the task. A successful command or image read alone does not establish a usable preview; guessed text geometry does not establish overflow.\n\n## Failed or blank previews\n\nFor populated content, a fully transparent or uniformly blank image is a renderer failure. If a pixel check is needed, composite RGBA onto white first; raw RGB under transparent pixels can look nonblank. Check once and do not reread the same image. Stop visual checks for the task immediately after a blank result. This overrides the rerender-after-edit guidance above: do not render or read images again, even after editing or copying the source, or try another range, page, sheet, DPI, output format, diagnostic export, or print setting. Preserve the usable source and requested outputs and finish applicable content/data checks.\n\nIf content and structure checks pass, name the saved file and verified edits as needed, then include exactly one visual-status sentence: \"Content and structure checks passed; visual inspection was not completed.\" in English, or \"内容与结构检查通过;视觉检查未完成。\" in Chinese. Do not add a render or preview bullet, explain why inspection stopped, or describe the image or pixels. Report content or structure failures separately; never say all checks passed or claim visual verification.\n\nLibreOffice output can differ from Word, PowerPoint, or Excel. Images do not certify animation/media playback, refresh formula caches in the source workbook, or guarantee native application fidelity. Deliver requested files through `present` when available; keep the files in place. Do not deliver inspection images or reports unless requested.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:6}}Line truncated
|
||||
{"type":"step/end","data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_2","name":"skill","arguments":"{\"name\":\"office-export-pdf\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"stream":[{"type":"chunk","time":1790753571639,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571639,"index":0,"dt":[],"id":"call_office_2","name":"skill","args":["{\"name\":\"office-export-pdf\"}"]},{"type":"chunk","time":1790753571639,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_2","name":"skill","arguments":"{\"name\":\"office-export-pdf\"}"}}},{"type":"chunk","time":1790753571639,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":2,"callId":"call_office_2","name":"skill","arguments":"{\"name\":\"office-export-pdf\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":2,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_2"},"toolCallId":"call_office_2","content":[{"type":"text","text":"<skill_content name=\"office-export-pdf\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-export-pdf\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Export an Office document to PDF\n\nUse the installed LibreOffice Kit CLI through the shell with `dsoffice`. Prefer bundled LibreOffice unless the user requests another installation. If the Office sidecar is missing, follow [sidecar setup](../office/references/sidecar.md): ask whether the user wants to download it and install only after they agree. Do not invoke system soffice, use npx, or install a replacement to work around a failed conversion with an installed sidecar.\n\nConvert the final saved Office file to a new PDF in the task workspace. Preserve the source. Quote each input and output path.\n\n```text\ndsoffice convert --input <final-office-file> --output <new-file.pdf>\n```\n\nCheck the command result, nonempty output, and `%PDF-` file signature. If a PDF reader library is already available, compare page count and extractable text with the requested content. If it is unavailable, report the extent of validation; do not generate images or install extra tools to validate a conversion. Spreadsheet PDF pages follow workbook print settings; change those settings only when requested. Conversion may differ from the native application's pagination or fonts.\n\nIf export fails, preserve the usable source and report the export limitation. Do not repeatedly convert an unchanged source or use conversion to investigate a failed preview. For PDF export alone, stop after these checks. Only a request for images or visual inspection calls for `office-render`; load it before that separate operation. Deliver the requested PDF through `present` when available, keeping the file in place.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:8}}"},"meta":{"skill":{"name":"office-export-pdf","provider":"dsh-office"}}},"sourceEventSeqs":[20],"surfaceOp":"append"}
|
||||
{"type":"tool/result","data":{"turn":1,"step":2,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_2"},"toolCallId":"call_office_2","content":[{"type":"text","text":"<skill_content name=\"office-export-pdf\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-export-pdf\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Export an Office document to PDF\n\nUse the installed LibreOffice Kit CLI through the shell with `dsoffice`. Prefer bundled LibreOffice unless the user requests another installation. If the Office sidecar is missing, follow [sidecar setup](../office/references/sidecar.md): ask whether the user wants to download it and install only after they agree. Do not invoke system soffice, use npx, or install a replacement to work around a failed conversion with an installed sidecar.\n\nConvert the final saved Office file to a new PDF in the task workspace. Preserve the source. Quote each input and output path.\n\n```text\ndsoffice convert --input <final-office-file> --output <new-file.pdf>\n```\n\nCheck the command result, nonempty output, and `%PDF-` file signature. If a PDF reader library is already available, compare page count and extractable text with the requested content. If it is unavailable, report the extent of validation; do not generate images or install extra tools to validate a conversion. Spreadsheet PDF pages follow workbook print settings; change those settings only when requested. Conversion may differ from the native application's pagination or fonts.\n\nIf export fails, preserve the usable source and report the export limitation. Do not repeatedly convert an unchanged source or use conversion to investigate a failed preview. For PDF export alone, stop after these checks. Only a request for images or visual inspection calls for `office-render`; load it before that separate operation. Deliver the requested PDF through `present` when available, keeping the file in place.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:8}}"}},"sourceEventSeqs":[20],"surfaceOp":"append"}
|
||||
{"type":"step/end","data":{"turn":1,"step":2}}
|
||||
{"type":"step/start","data":{"turn":1,"step":3}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_3","name":"skill","arguments":"{\"name\":\"office-recalculate\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:9}}"},"stream":[{"type":"chunk","time":1790753571666,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571666,"index":0,"dt":[],"id":"call_office_3","name":"skill","args":["{\"name\":\"office-recalculate\"}"]},{"type":"chunk","time":1790753571666,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_3","name":"skill","arguments":"{\"name\":\"office-recalculate\"}"}}},{"type":"chunk","time":1790753571666,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":3,"callId":"call_office_3","name":"skill","arguments":"{\"name\":\"office-recalculate\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":3,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_3"},"toolCallId":"call_office_3","content":[{"type":"text","text":"<skill_content name=\"office-recalculate\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-recalculate\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Recalculate spreadsheet formulas\n\nUse the installed LibreOffice Kit CLI through the shell with `dsoffice`. Prefer bundled LibreOffice unless the user requests another installation. If the Office sidecar is missing, follow [sidecar setup](../office/references/sidecar.md): ask whether the user wants to download it and install only after they agree. Do not invoke system soffice, use npx, or install a replacement to work around a failed recalculation with an installed sidecar.\n\nKeep the original workbook and write a new file in the task workspace. Quote each input and output path.\n\n```text\ndsoffice recalculate --input <workbook.xlsx> --output <recalculated.xlsx>\n```\n\nVerify the saved result with openpyxl, using `load_workspace_dependencies` for the Python path unless a project environment is required. Open it with both `data_only=False` and `data_only=True`. Check that formulas survive and cached results match the requested logic, expected totals, and cell types. Check required unchanged sheets, styles, and data. Recalculation does not validate business logic or guarantee Excel-specific feature compatibility.\n\nIf no supported recalculation engine is available or the command fails, preserve the workbook and explain that calculated values could not be refreshed. Do not replace requested formulas with constants or present stale/absent caches as fresh results. Deliver the verified output through `present` when available, keeping the file in place.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:10}}"},"meta":{"skill":{"name":"office-recalculate","provider":"dsh-office"}}},"sourceEventSeqs":[25],"surfaceOp":"append"}
|
||||
{"type":"tool/result","data":{"turn":1,"step":3,"message":{"role":"tool","source":{"kind":"tool","callId":"call_office_3"},"toolCallId":"call_office_3","content":[{"type":"text","text":"<skill_content name=\"office-recalculate\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/office-skills/office-recalculate\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Recalculate spreadsheet formulas\n\nUse the installed LibreOffice Kit CLI through the shell with `dsoffice`. Prefer bundled LibreOffice unless the user requests another installation. If the Office sidecar is missing, follow [sidecar setup](../office/references/sidecar.md): ask whether the user wants to download it and install only after they agree. Do not invoke system soffice, use npx, or install a replacement to work around a failed recalculation with an installed sidecar.\n\nKeep the original workbook and write a new file in the task workspace. Quote each input and output path.\n\n```text\ndsoffice recalculate --input <workbook.xlsx> --output <recalculated.xlsx>\n```\n\nVerify the saved result with openpyxl, using `load_workspace_dependencies` for the Python path unless a project environment is required. Open it with both `data_only=False` and `data_only=True`. Check that formulas survive and cached results match the requested logic, expected totals, and cell types. Check required unchanged sheets, styles, and data. Recalculation does not validate business logic or guarantee Excel-specific feature compatibility.\n\nIf no supported recalculation engine is available or the command fails, preserve the workbook and explain that calculated values could not be refreshed. Do not replace requested formulas with constants or present stale/absent caches as fresh results. Deliver the verified output through `present` when available, keeping the file in place.\n</skill_instructions>\n</skill_content>"}],"isError":false,"id":"{{message:10}}"}},"sourceEventSeqs":[25],"surfaceOp":"append"}
|
||||
{"type":"step/end","data":{"turn":1,"step":3}}
|
||||
{"type":"step/start","data":{"turn":1,"step":4}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_office_4","name":"read","arguments":"{\"file_path\":\"office-skills/office/references/sidecar.md\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:11}}"},"stream":[{"type":"chunk","time":1790753571694,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1790753571694,"index":0,"dt":[],"id":"call_office_4","name":"read","args":["{\"file_path\":\"office-skills/office/references/sidecar.md\"}"]},{"type":"chunk","time":1790753571695,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_office_4","name":"read","arguments":"{\"file_path\":\"office-skills/office/references/sidecar.md\"}"}}},{"type":"chunk","time":1790753571695,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{"type":"session/title","data":{"title":"Load the editing-cordis-compositions ski","messageSeqs":[8],"source":{"kind":"fallback"}}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"Load the requested skill."},{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"editing-cordis-compositions\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5},"stream":[{"type":"chunk","time":1788699430688,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788699430688,"index":0,"dt":[],"texts":["Load the requested skill."]},{"type":"chunk","time":1788699430688,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788699430688,"index":1,"dt":[],"id":"call_skill_load","name":"skill","args":["{\"name\":\"editing-cordis-compositions\"}"]},{"type":"chunk","time":1788699430688,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Load the requested skill."}}},{"type":"chunk","time":1788699430688,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"editing-cordis-compositions\"}"}}},{"type":"chunk","time":1788699430688,"chunk":{"type":"usage","usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5}}},{"type":"chunk","time":1788699430688,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_skill_load","name":"skill","arguments":"{\"name\":\"editing-cordis-compositions\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_skill_load"},"toolCallId":"call_skill_load","content":[{"type":"text","text":"<skill_content name=\"editing-cordis-compositions\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/.dsh/skills/editing-cordis-compositions\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Editing Cordis compositions\n\nAgent presets are ordinary `@deepseek-ai/dsh-agent-preset` declarations carried by bundle patches. Nothing edits a declaration in place: a preset is created or changed by installing a bundle whose patch declares or overrides it. This file states the declaration format; when it leaves a question open, read the `@deepseek-ai/dsh-agent-preset` README and `lib/types` declarations under the `packageDir` that `cordis_inspect_query` `Config.listConfigs` returns when queried with a `preset-<id>` row's `entry` id, or `packages/preset/agent-preset/src` in a source checkout.\n\n## Where declarations live\n\nThe shipped Web presets are `presets/<id>.patch.yml` files of the `@deepseek-ai/dsh-web-app` bundle, ids `standard`, `ptc`, `minimal` and `cordis`. Installed, the bundle resolves from the dsh installation, not the profile; querying `Config.listConfigs` with the `entry` id of any `preset-<id>` row it declares returns that `packageDir`. In a source checkout of DSH it is `packages/bundle/web-app/`. Read one file with the file-read tool when you need a template; `minimal.patch.yml` is the shortest. In Desktop the bundle sits inside `app.asar`, which shell commands cannot open. Load `cordis-composition-reference` for the patch dialect and the list of plugin packages a preset can mount.\n\nA declaration row has these `config` fields: `id` (required, lowercase letters, digits and hyphens), `plugins` (required Cordis entry list), and optional `name`, `description` and `order` (roster position). The Loader row `id` is `preset-<id>` by convention.\n\n## Create a preset\n\nWrite a bundle directory in the workspace with exactly two files, then install it.\n\n`review-preset/package.json`:\n\n```json\n{\n \"name\": \"@local/dsh-review-preset\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dsh\": { \"bundle\": { \"patch\": \"./cordis.patch.yml\" } }\n}\n```\n\n`review-preset/cordis.patch.yml`:\n\n```yaml\n- insert:\n - id: preset-review\n name: '@deepseek-ai/dsh-agent-preset'\n config:\n id: review\n name: Review\n description: Reviews changes with the shell only.\n order: 10\n plugins:\n - id: persona\n name: '@deepseek-ai/dsh-persona'\n config:\n prefix: You review software changes.\n - id: tool-bash\n name: '@deepseek-ai/dsh-tool-bash'\n```\n\nInstall with `plugin_manager`, `action: install_bundle`, `target` set to the absolute bundle directory. It runs package installation and bundle selection itself; do not reproduce those steps with shell commands.\n\n## Change a shipped preset\n\nOverride the declaration by its Loader row id instead of inserting. The override replaces the complete `config`, so restate `id`, `plugins` and every other field the shipped file carries:\n\n```yaml\n- id: preset-standard\n name: '@deepseek-ai/dsh-agent-preset'\n config:\n id: standard\n order: 1\n plugins:\n # the shipped list with your changes\n```\n\n## Migrate a legacy preset\n\nBefore declaration rows, a user preset was a directory `$DSH_HOME/.agent-presets/<id>/` holding `preset.yml` (display `name`, `description`, `order`) and `agent.cordis.yml` (the plugin entry list). Nothing reads that directory any more. To migrate one, create a bundle as above whose declaration takes `id` from the directory name, `name`, `description`, and `order` from `preset.yml`, and `plugins` from `agent.cordis.yml` verbatim; check each plugin name against `cordis-composition-reference` because packages renamed since the preset was written fail at activation. Install it, verify the row, then delete the legacy directory.\n\n## Verify\n\n`plugin_manager` `list_bundles` lists the installed bundle; `list_plugins` shows the `preset-<id>` row with its activation state. A declaration whose activation fails stays on the roster with its diagnostic and cannot compose a session until the bundle is fixed and reinstalled. Existing sessions and their children keep the plugin revision they started with; validate changed behavior in a new session. Installing a bundle executes plugin code in the Host process, so it requires Full access or approval.\n\n## Choose plugin placement\n\nHost plugins supply shared services: tools and prompt registries, the Agent loop, sessions, persistence, settings, sandbox policy, model routes, and subagent backends. Preset plugins contribute scopLine truncated
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_skill_load"},"toolCallId":"call_skill_load","content":[{"type":"text","text":"<skill_content name=\"editing-cordis-compositions\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/.dsh/skills/editing-cordis-compositions\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Editing Cordis compositions\n\nAgent presets are ordinary `@deepseek-ai/dsh-agent-preset` declarations carried by bundle patches. Nothing edits a declaration in place: a preset is created or changed by installing a bundle whose patch declares or overrides it. This file states the declaration format; when it leaves a question open, read the `@deepseek-ai/dsh-agent-preset` README and `lib/types` declarations under the `packageDir` that `cordis_inspect_query` `Config.listConfigs` returns when queried with a `preset-<id>` row's `entry` id, or `packages/preset/agent-preset/src` in a source checkout.\n\n## Where declarations live\n\nThe shipped Web presets are `presets/<id>.patch.yml` files of the `@deepseek-ai/dsh-web-app` bundle, ids `standard`, `ptc`, `minimal` and `cordis`. Installed, the bundle resolves from the dsh installation, not the profile; querying `Config.listConfigs` with the `entry` id of any `preset-<id>` row it declares returns that `packageDir`. In a source checkout of DSH it is `packages/bundle/web-app/`. Read one file with the file-read tool when you need a template; `minimal.patch.yml` is the shortest. In Desktop the bundle sits inside `app.asar`, which shell commands cannot open. Load `cordis-composition-reference` for the patch dialect and the list of plugin packages a preset can mount.\n\nA declaration row has these `config` fields: `id` (required, lowercase letters, digits and hyphens), `plugins` (required Cordis entry list), and optional `name`, `description` and `order` (roster position). The Loader row `id` is `preset-<id>` by convention.\n\n## Create a preset\n\nWrite a bundle directory in the workspace with exactly two files, then install it.\n\n`review-preset/package.json`:\n\n```json\n{\n \"name\": \"@local/dsh-review-preset\",\n \"version\": \"1.0.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dsh\": { \"bundle\": { \"patch\": \"./cordis.patch.yml\" } }\n}\n```\n\n`review-preset/cordis.patch.yml`:\n\n```yaml\n- insert:\n - id: preset-review\n name: '@deepseek-ai/dsh-agent-preset'\n config:\n id: review\n name: Review\n description: Reviews changes with the shell only.\n order: 10\n plugins:\n - id: persona\n name: '@deepseek-ai/dsh-persona'\n config:\n prefix: You review software changes.\n - id: tool-bash\n name: '@deepseek-ai/dsh-tool-bash'\n```\n\nInstall with `plugin_manager`, `action: install_bundle`, `target` set to the absolute bundle directory. It runs package installation and bundle selection itself; do not reproduce those steps with shell commands.\n\n## Change a shipped preset\n\nOverride the declaration by its Loader row id instead of inserting. The override replaces the complete `config`, so restate `id`, `plugins` and every other field the shipped file carries:\n\n```yaml\n- id: preset-standard\n name: '@deepseek-ai/dsh-agent-preset'\n config:\n id: standard\n order: 1\n plugins:\n # the shipped list with your changes\n```\n\n## Migrate a legacy preset\n\nBefore declaration rows, a user preset was a directory `$DSH_HOME/.agent-presets/<id>/` holding `preset.yml` (display `name`, `description`, `order`) and `agent.cordis.yml` (the plugin entry list). Nothing reads that directory any more. To migrate one, create a bundle as above whose declaration takes `id` from the directory name, `name`, `description`, and `order` from `preset.yml`, and `plugins` from `agent.cordis.yml` verbatim; check each plugin name against `cordis-composition-reference` because packages renamed since the preset was written fail at activation. Install it, verify the row, then delete the legacy directory.\n\n## Verify\n\n`plugin_manager` `list_bundles` lists the installed bundle; `list_plugins` shows the `preset-<id>` row with its activation state. A declaration whose activation fails stays on the roster with its diagnostic and cannot compose a session until the bundle is fixed and reinstalled. Existing sessions and their children keep the plugin revision they started with; validate changed behavior in a new session. Installing a bundle executes plugin code in the Host process, so it requires Full access or approval.\n\n## Choose plugin placement\n\nHost plugins supply shared services: tools and prompt registries, the Agent loop, sessions, persistence, settings, sandbox policy, model routes, and subagent backends. Preset plugins contribute scopLine truncated
|
||||
{"type":"step/end","data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The skill is loaded."},{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4},"stream":[{"type":"chunk","time":1788699430709,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788699430709,"index":0,"dt":[],"texts":["The skill is loaded."]},{"type":"chunk","time":1788699430709,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788699430709,"index":1,"dt":[],"texts":["DONE"]},{"type":"chunk","time":1788699430709,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The skill is loaded."}}},{"type":"chunk","time":1788699430709,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"DONE"}}},{"type":"chunk","time":1788699430709,"chunk":{"type":"usage","usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4}}},{"type":"chunk","time":1788699430709,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
{"type":"session/title","data":{"title":"Load the diagnose-windows-sandbox-acl sk","messageSeqs":[8],"source":{"kind":"fallback"}}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"Load the requested skill."},{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"diagnose-windows-sandbox-acl\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:5}}"},"usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5},"stream":[{"type":"chunk","time":1788699430688,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788699430688,"index":0,"dt":[],"texts":["Load the requested skill."]},{"type":"chunk","time":1788699430688,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}},{"type":"tool-call-chunks","time0":1788699430688,"index":1,"dt":[],"id":"call_skill_load","name":"skill","args":["{\"name\":\"diagnose-windows-sandbox-acl\"}"]},{"type":"chunk","time":1788699430688,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Load the requested skill."}}},{"type":"chunk","time":1788699430688,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"diagnose-windows-sandbox-acl\"}"}}},{"type":"chunk","time":1788699430688,"chunk":{"type":"usage","usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5}}},{"type":"chunk","time":1788699430688,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}]},"surfaceOp":"append"}
|
||||
{"type":"tool/call","data":{"turn":1,"step":1,"callId":"call_skill_load","name":"skill","arguments":"{\"name\":\"diagnose-windows-sandbox-acl\"}"}}
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_skill_load"},"toolCallId":"call_skill_load","content":[{"type":"text","text":"<skill_content name=\"diagnose-windows-sandbox-acl\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/.dsh/skills/diagnose-windows-sandbox-acl\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Diagnose Windows sandbox ACL failures\n\n**Write every approval request in plain words, in the user's language.** The prompt is all the user reads before widening access, so it must stand alone: which folder the script touches, that it adds the signed-in user's full-control entry where a right is missing and removes foreign package entries, that file contents and owners are unchanged, and that the printed recovery command undoes each change. Keep error codes, `WRITE_DAC`/`WRITE_OWNER`, `S-1-15-2-*` SIDs, `icacls`, ACL, ACE, verdict names and switches out of the request: write Windows file permissions, not ACL or ACE. Ask once, for one command.\n\n## One command diagnoses and repairs\n\nThe script has no modes. `-Path`, `-AllowRoot` and `-Out` read the path and every ancestor and repair what the observations prove, in the same run:\n\n- directories on that chain that lack effective `WRITE_DAC` or `WRITE_OWNER` receive a full-control allow ACE for the signed-in user, because DSH cannot provision its workspace grant without them;\n- explicit AppContainer package allow ACEs (`S-1-15-2-*`, except the well-known groups ending in 1 or 2) are removed at their sources, ancestor first, which also removes those packages' access;\n- a directory the sandbox cannot provision — the state its provisioning error reports on the workspace root — or the authorized root itself also has its subtree searched for those ACEs in the same run, so a deeper entry needs no second request. That bounded walk reports `truncated` and unreadable directories; if truncated, pass the still-failing deeper path once more.\n\nEvery change is backed up, then verified by re-reading it. `-AllowRoot` bounds all of it: an object is changed only when it is that directory or strictly inside it, so a workspace root can repair itself. Never split this into a diagnostic call and a repair call, never ask twice for one repair, and never pass a mode switch that does not exist.\n\n```powershell\n& '<skill-directory>\\scripts\\diagnose-windows-sandbox-acl.ps1' -Path '<failing-path>' -AllowRoot '<authorized-directory>' -Out '<recovery-directory>'\nexit $LASTEXITCODE\n```\n\nSubstitute full, quoted paths. Keep `-Out` persistent and user-owned, preferably beside the failing workspace; never use the skill resource directory, which is deleted when the skill unloads. Pass one path per invocation.\n\n## Run it\n\nRepeat the failing operation once confined. The script writes permissions, which the confined token cannot do — run it there and it would report the sandbox's own restriction as a missing right — so request approval for that one command and run it unconfined. A confined run of the script is never useful. Unconfined does not elevate the Windows token.\n\nDiagnose unexpected denials of workspace writes, listing, or plainly readable paths; explain expected ones instead: writes outside the workspace, any write in `read-only`, piped grandchild `spawn EPERM`, ConstrainedLanguage errors. If approval is refused or unavailable, report the path as undiagnosed and stop.\n\n## Read the output\n\nEvery record reaches stdout, the `acl-report-*.jsonl` file under `-Out`, and the final `RECAP` line, which carries the verdicts, changes, verifications, refusals and scans. Tool output keeps only its tail, so read the recap first, and read specific records from the report when it is not enough. Trust `verification` records, never `completed` actions. Decide from `details.nextAction`:\n\n| `nextAction` | Meaning |\n|---|---|\n| `verify_original_confined_operation` | Repairs verified; repeat the original operation confined. |\n| `stop` | Nothing repaired, or a refusal ended the run. Report and stop. |\n| `restore_pending_then_stop` | Rollback unverified. Run the printed recovery commands in order, then stop. |\n\nA deny ACE's presence alone does not establish causation, and the script never removes one; DSH's `S-1-4-*` grants and the Everyone `DeleteSubdirectoriesAndFiles` deny are expected, not conflicts. A deny that blocks the repair ends the run without a repair (`REPAIR_REFUSED`, or `GRANT_FAILED`) after restoring what it attempted. Each change leaves two files in `-Out` (`acl-backup-<id>.json` and its `.ps1`), and the run prints the matching `ROLLBACK` command.\n\n## After a repair, and when it stops\n\nRepeat the original failed operation confined. A verified repair is not undone because the original operation fails for a further reason: continue fromLine truncated
|
||||
{"type":"tool/result","data":{"turn":1,"step":1,"message":{"role":"tool","source":{"kind":"tool","callId":"call_skill_load"},"toolCallId":"call_skill_load","content":[{"type":"text","text":"<skill_content name=\"diagnose-windows-sandbox-acl\">\n<skill_resources>\nBase directory for this skill: {{cwd}}/.dsh/skills/diagnose-windows-sandbox-acl\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\n# Diagnose Windows sandbox ACL failures\n\n**Write every approval request in plain words, in the user's language.** The prompt is all the user reads before widening access, so it must stand alone: which folder the script touches, that it adds the signed-in user's full-control entry where a right is missing and removes foreign package entries, that file contents and owners are unchanged, and that the printed recovery command undoes each change. Keep error codes, `WRITE_DAC`/`WRITE_OWNER`, `S-1-15-2-*` SIDs, `icacls`, ACL, ACE, verdict names and switches out of the request: write Windows file permissions, not ACL or ACE. Ask once, for one command.\n\n## One command diagnoses and repairs\n\nThe script has no modes. `-Path`, `-AllowRoot` and `-Out` read the path and every ancestor and repair what the observations prove, in the same run:\n\n- directories on that chain that lack effective `WRITE_DAC` or `WRITE_OWNER` receive a full-control allow ACE for the signed-in user, because DSH cannot provision its workspace grant without them;\n- explicit AppContainer package allow ACEs (`S-1-15-2-*`, except the well-known groups ending in 1 or 2) are removed at their sources, ancestor first, which also removes those packages' access;\n- a directory the sandbox cannot provision — the state its provisioning error reports on the workspace root — or the authorized root itself also has its subtree searched for those ACEs in the same run, so a deeper entry needs no second request. That bounded walk reports `truncated` and unreadable directories; if truncated, pass the still-failing deeper path once more.\n\nEvery change is backed up, then verified by re-reading it. `-AllowRoot` bounds all of it: an object is changed only when it is that directory or strictly inside it, so a workspace root can repair itself. Never split this into a diagnostic call and a repair call, never ask twice for one repair, and never pass a mode switch that does not exist.\n\n```powershell\n& '<skill-directory>\\scripts\\diagnose-windows-sandbox-acl.ps1' -Path '<failing-path>' -AllowRoot '<authorized-directory>' -Out '<recovery-directory>'\nexit $LASTEXITCODE\n```\n\nSubstitute full, quoted paths. Keep `-Out` persistent and user-owned, preferably beside the failing workspace; never use the skill resource directory, which is deleted when the skill unloads. Pass one path per invocation.\n\n## Run it\n\nRepeat the failing operation once confined. The script writes permissions, which the confined token cannot do — run it there and it would report the sandbox's own restriction as a missing right — so request approval for that one command and run it unconfined. A confined run of the script is never useful. Unconfined does not elevate the Windows token.\n\nDiagnose unexpected denials of workspace writes, listing, or plainly readable paths; explain expected ones instead: writes outside the workspace, any write in `read-only`, piped grandchild `spawn EPERM`, ConstrainedLanguage errors. If approval is refused or unavailable, report the path as undiagnosed and stop.\n\n## Read the output\n\nEvery record reaches stdout, the `acl-report-*.jsonl` file under `-Out`, and the final `RECAP` line, which carries the verdicts, changes, verifications, refusals and scans. Tool output keeps only its tail, so read the recap first, and read specific records from the report when it is not enough. Trust `verification` records, never `completed` actions. Decide from `details.nextAction`:\n\n| `nextAction` | Meaning |\n|---|---|\n| `verify_original_confined_operation` | Repairs verified; repeat the original operation confined. |\n| `stop` | Nothing repaired, or a refusal ended the run. Report and stop. |\n| `restore_pending_then_stop` | Rollback unverified. Run the printed recovery commands in order, then stop. |\n\nA deny ACE's presence alone does not establish causation, and the script never removes one; DSH's `S-1-4-*` grants and the Everyone `DeleteSubdirectoriesAndFiles` deny are expected, not conflicts. A deny that blocks the repair ends the run without a repair (`REPAIR_REFUSED`, or `GRANT_FAILED`) after restoring what it attempted. Each change leaves two files in `-Out` (`acl-backup-<id>.json` and its `.ps1`), and the run prints the matching `ROLLBACK` command.\n\n## After a repair, and when it stops\n\nRepeat the original failed operation confined. A verified repair is not undone because the original operation fails for a further reason: continue fromLine truncated
|
||||
{"type":"step/end","data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/message","data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The skill is loaded."},{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{message:7}}"},"usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4},"stream":[{"type":"chunk","time":1788699430709,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}},{"type":"reasoning-chunks","time0":1788699430709,"index":0,"dt":[],"texts":["The skill is loaded."]},{"type":"chunk","time":1788699430709,"chunk":{"type":"block-start","index":1,"blockType":"text"}},{"type":"text-chunks","time0":1788699430709,"index":1,"dt":[],"texts":["DONE"]},{"type":"chunk","time":1788699430709,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The skill is loaded."}}},{"type":"chunk","time":1788699430709,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"DONE"}}},{"type":"chunk","time":1788699430709,"chunk":{"type":"usage","usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4}}},{"type":"chunk","time":1788699430709,"chunk":{"type":"finish","reason":{"kind":"stop"}}}]},"surfaceOp":"append"}
|
||||
|
||||
Reference in new issue
Block a user