Tools & Capabilities

dsh-tool-encoding

omdsh-dev/dsh-tool-encoding · ★ 4

omdsh-devCurated

base64/url/hex encoding, common hashes, and UUID generation.

License
MIT
Added
2026-08-13
Maintenance
active
Install kind
github
Manifest status
Declared
Manifest path
package.json#dsh
Manifest checked
2026-08-19
Lifecycle scripts
None found

Static manifest checks report declarations only; they are not compatibility or security review.

安装

dsh plugin --profile web add github:omdsh-dev/dsh-tool-encoding

GitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试

For install and environment setup, plus plugin development tutorials, see DSH community docs ↗

README

Source README · body: en · Read Chinese README

Table of contents
  1. Motivation
  2. Security model
  3. Architecture
  4. Tool declaration
  5. Supported operations
  6. DSH 0.1.5-rc.1 compatibility (verified)
  7. Version adaptation
  8. Installation
  9. Profile Bundle (recommended)
  10. Install via npm pack tarball
  11. Verify installation
  12. Run verification
  13. Manual installation and legacy compatibility
  14. Known limitations
  15. Testing
  16. License

中文

DSH encoding/hash tool plugin — base64/base64url/url/hex encode/decode + hash + UUID for UTF-8 text. Zero dependencies, zero subprocesses, pure functions.

Package name: @deepseek-ai/dsh-tool-encoding (standalone bundle, not a monorepo-integrated form); the lib/ output is generated by npm run build (tsc) inside the repo and committed with the repository.

License

Motivation

Encoding/hashing is a high-frequency daily operation for agents: inspecting base64 fields in API responses (JWT payload), building query parameters, verifying file integrity (sha256), generating UUIDs. Problems with the current approach bash -c "echo ... | base64": subprocess overhead, quote-escaping hell (a base64 string embedded in a bash command then in a JSON argument — the double-escaping error rate is extremely high), and inconsistent cross-platform tool names (md5 vs md5sum vs shasum -a 256).

Security model

No eval, no new Function. All operations are pure-function compositions of Buffer/node:crypto/TextDecoder/encodeURIComponent:

  • UTF-8 integrity: decoding uses fatal mode (TextDecoder('utf-8', { fatal: true })); illegal bytes throw encoding: invalid UTF-8 output; legal U+FFFD/control characters are not rejected (00 NUL, 0a newline, efbfbd U+FFFD are all legal, ff is illegal)
  • Strict base64 validation: no whitespace, = only at the end and ≤2, length must be a multiple of 4, RFC 4648 canonical unused bits (non-canonical encodings such as Zh== are rejected, preventing multiple strings from mapping to the same text)
  • Unified rejection of lone surrogates: all text inputs pass through String.prototype.isWellFormed(), avoiding silent replacement and inconsistent URIError behavior
  • Byte limits: 1 MB input / 4 MB output (1,000,000 / 4,000,000 bytes each, Buffer.byteLength; the output limit is a fuse of pre-allocation estimate + final check)
  • Hash algorithm whitelist: Object.hasOwn lookup table (md5/sha1/sha256/sha512)
  • Errors uniformly use the encoding: prefix and never pass through the underlying URIError/TypeError

Architecture

DSH Agent
    │ ctx.tools.register()
    ▼
src/index.ts(Cordis 插件入口 + action 分发 + 独立校验)
    │
    ▼
src/encoding.ts
    ├── b64Encode/b64Decode — 标准 base64(严格校验)
    ├── b64UrlEncode/b64UrlDecode — base64url(canonical 无 padding,解码兼容)
    ├── urlEncode/urlDecode — component 语义(URIError 包装)
    ├── hexEncode/hexDecode — UTF-8 字节 hex(fatal 解码)
    ├── digest — 白名单哈希
    ├── newUuid — crypto.randomUUID()
    └── validateUnicode/assertInputBytes/decodeUtf8Strict — 校验器

Tool declaration

ctx.tools.register(defineTool({
  name: 'encoding',
  parameters: {
    action: {
      type: 'string', required: true,
      enum: ['base64_encode','base64_decode','base64url_encode','base64url_decode',
             'url_encode','url_decode','hex_encode','hex_decode','hash','uuid'],
    },
    input:     { type: 'string', description: 'Input string for encode/decode/hash' },
    algorithm: { type: 'string', enum: ['md5','sha1','sha256','sha512'], description: 'For hash' },
  },
  output: { schema: { type: 'json' }, render: (_a, v) => [{ type: 'text', text: JSON.stringify(v) }] },
  execute: (args) => Promise.resolve(executeAction(args.action, args) as JsonValue),
  timeoutMs: 1000,
}))

Supported operations

action description example
base64_encode / base64_decode RFC 4648 standard base64 (strict validation) "foobar" → "Zm9vYmFy"
base64url_encode / base64url_decode JWT-style, unpadded output, decoding accepts +/ and optional padding "\uFEFF" → "77u_"
url_encode / url_decode component semantics (not full query): space is %20 not +, !'()* not escaped, decode("+") → "+" "a b" → "a%20b"
hex_encode / hex_decode UTF-8 byte hex; the decoded result must be valid UTF-8 "AB" → "4142"
hash md5/sha1/sha256/sha512 hex digest; non-security use only sha256("") → e3b0c442...
uuid UUID v4 string (crypto.randomUUID()) "550e8400-..."

Semantic contract:

  • v1 is a UTF-8 text tool: all inputs and outputs are strings; binary content is represented as hex; decoded results must be valid UTF-8
  • All actions return strings (including uuid)
  • Do not use this tool on confidential material: tool arguments are recorded in session logs

DSH 0.1.5-rc.1 compatibility (verified)

This plugin has been migrated to the DSH 0.1.5-rc.1 harness and fully verified in an isolated consumer of local harness 0.1.5-rc.1:

  • Types/runtime: @deepseek-ai/cordis@^4.0.1 + @deepseek-ai/dsh-tools@>=0.0.1-rc.1 <0.2.0 + @deepseek-ai/dsh-invariants@>=0.0.1-rc.1 <0.2.0 (peer); no longer depends on unscoped cordis
  • Standalone build: npm install (devDependencies are self-contained: typescript/vitest/@types/node) → npm run typecheck → npm test → npm run build → npm pack
  • Consumption verification: tarball installed into the 0.1.5-rc.1 consumer → dsh --profile compat --dump-config shows this plugin's row → the tool actually registers and executes
  • Startup: npx -p @deepseek-ai/dsh@next dsh web (lib production mode; do not install -g globally)

Version adaptation

  • DSH version adapted: DSH 0.1.5-rc.1
  • Bundle declaration: dsh.bundle in package.json (patch points to cordis.patch.yml) + exports fields
  • Patch format: cordis.patch.yml uses the - insert: list (patches are id-targeted; a bare - id: entry reports entry not found)
  • files: the published tarball contains lib/, src/, cordis.patch.yml

Installation

Plugin source repository: https://github.com/omdsh-dev/dsh-tool-encoding (public).

Install this plugin as a standalone bundle into a profile (DSH 0.1.5-rc.1, npm):

# 交互式(web)profile
dsh plugin --profile web add github:omdsh-dev/dsh-tool-encoding
# 一次性任务(headless)profile —— dsh run 默认使用 headless
dsh plugin --profile headless add github:omdsh-dev/dsh-tool-encoding

The dsh.bundle.patch inside the package (pointing to cordis.patch.yml) automatically adds the plugin to the profile's layer stack after installation; the plugin's cordis.patch.yml inserts the tool-encoding entry via - insert:.

⚠️ web and headless are different profiles: installing into web does not automatically cover headless; dsh run uses the headless profile by default.

Install via npm pack tarball

npm pack    # generates dsh-tool-encoding-*.tgz
dsh plugin --profile web add ./dsh-tool-encoding-*.tgz
dsh plugin --profile headless add ./dsh-tool-encoding-*.tgz

Verify installation

dsh --profile web --dump-config | grep tool-encoding

Run verification

dsh run "使用 encoding 工具把 hello 做 base64 编码"

Manual installation and legacy compatibility

Only for legacy snapshots that do not support Profile Bundle, or plugin development/debugging environments:

  1. Place into the monorepo: cp -r encoding ~/.dsh/source/master/packages/tools/encoding (development/debugging)
  2. Add "@deepseek-ai/dsh-tool-encoding": "workspace:^" to apps/cli/package.json; add { "path": "./packages/tools/encoding" } to the references of tsconfig.host.json
  3. pnpm install && pnpm run build
  4. Insert the plugin in the profile's user-layer patch (~/.dsh/profiles/<name>/cordis.patch.yml):
- insert:
    - id: tool-encoding
      name: '@deepseek-ai/dsh-tool-encoding'
  1. Verify: dsh --profile <name> --dump-config | grep tool-encoding

Note: patches are id-targeted — a bare - id: entry reports entry "xxx" not found; it must be wrapped in an - insert: list.

Known limitations

  1. Arbitrary binary (non-printable bytes) encode/decode requires v2's output: "utf8" | "hex" mode
  2. hash provides digests only, no HMAC/salting/key derivation; MD5/SHA-1 are for compatibility/non-security integrity checks only
  3. URL uses component semantics; form encoding (space → +) needs a separate action (v2)

Testing

pnpm test

41 test cases covering functionality/errors/attack payloads (RFC 4648/1321/6234 known vectors, UTF-8 boundary distinctions, canonical padding boundaries, unified surrogate rejection, etc.). See the locally maintained design document for the full list.

License

MIT