@buddhilive/dsh-brand 0.1.2-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DeepSeek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
+ # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
+ # after editing either side, bring the other along and re-record with:
4
+ # pnpm run verify-translation-pairing --write packages/util/brand/README.md
5
+ README.md: 646a3e781ce8540277259f4ffd67b78f3049160b
6
+ README.zh.md: 68290b35b64b4f519e2da06fc519d9d008e23646
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ ---
2
+ description: "Nominal string types and stateless constructors for packages that own identifiers crossing package boundaries."
3
+ kind: "package-library"
4
+ ---
5
+
6
+ # @buddhilive/dsh-brand
7
+
8
+ English | [中文](README.zh.md)
9
+
10
+ ## Summary
11
+
12
+ `dsh-brand` makes structurally identical strings non-interchangeable at the type level: a `SessionId` cannot be passed where a `ToolCallId` is expected even though both are plain strings at runtime. `brandString<T>()` applies a nominal brand to one domain-owned string without shared runtime state and lets capability packages own their concrete id types without importing an unrelated capability.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Dev Note](#dev-note)
20
+
21
+ -----
22
+
23
+ <a id="use-this-package"></a>
24
+ ## Use this package
25
+
26
+ Brand the ids a package owns when they cross a package boundary and could plausibly be confused with another package's ids; not every string needs a brand. A branded id is a contract for TypeScript callers: it only ever enters the functions that expect it, and an id from another package is rejected at compile time.
27
+
28
+ ### Branding a string
29
+
30
+ Declare the branded type in the owning package and apply it at the point where that package admits a string:
31
+
32
+ ```ts
33
+ import { brandString, type Branded } from '@buddhilive/dsh-brand'
34
+
35
+ export type SessionId = Branded<'SessionId'>
36
+
37
+ const sessionId = brandString<SessionId>('session-1')
38
+ ```
39
+
40
+ `brandString()` changes only the static type and performs no runtime validation. Validate domain grammar before calling it when the owning type has one. Once branded, the id compares, logs, serializes to JSON, and crosses the wire as an ordinary string.
41
+
42
+ ### When to brand
43
+
44
+ Brand ids that cross package boundaries and could plausibly be confused — `ToolCallId` in `dsh-llm`, the shared agent/session `SessionId` in `dsh-session`, `JobId` in `dsh-jobs`, `LspProviderId` in `dsh-lsp`. Strings that never leave their owning package do not need this abstraction.
45
+
46
+ -----
47
+
48
+ <a id="understand-the-implementation"></a>
49
+ ## Understand the implementation
50
+
51
+ <details>
52
+ <summary>Implementation internals — click to expand</summary>
53
+
54
+ The primitive is one intersection type: `string & { readonly [BRAND]: B }`, where `BRAND` is a module-private `unique symbol`.
55
+
56
+ ### Source map
57
+
58
+ | File | Role |
59
+ |---|---|
60
+ | [`src/index.ts`](src/index.ts) | Branded string type and its stateless constructor |
61
+ | [`src/invariant.ts`](src/invariant.ts) | Invariant companion (no runtime invariant; erasure is enforced by the compiler) |
62
+
63
+ ### How values stay portable
64
+
65
+ The private symbol never exists at runtime: TypeScript erases it, so branded values have no tag or prototype. `brandString()` returns its input unchanged. Separate installed copies therefore produce interchangeable values without sharing a registry or constructor identity.
66
+
67
+ ### Why it stays dependency-free
68
+
69
+ Keeping these helpers in their own package means `dsh-jobs` can brand `JobId` without importing an unrelated capability package, while each capability still owns the meaning and validation of its concrete ids.
70
+
71
+ </details>
72
+
73
+ -----
74
+
75
+ <a id="further-exploration"></a>
76
+ ## Further Exploration
77
+
78
+ Read these pages when you need the ids this primitive brands or the type conventions around it.
79
+
80
+ - [Core subsystem](../../../docs/subsystems/core.md) — where the shared `SessionId` brand and the type rules are documented.
81
+ - [LSP subsystem](../../../docs/subsystems/lsp.md) — `LspProviderId`, a branded provider id built on this primitive.
82
+ - [Jobs package](../../jobs/jobs/README.md) — the `JobId` brand owned by the jobs capability.
83
+
84
+ -----
85
+
86
+ <a id="dev-note"></a>
87
+ ## Dev Note
88
+
89
+ <details>
90
+ <summary>Working context for maintainers — click to expand</summary>
91
+
92
+ None.
93
+
94
+ </details>
package/README.zh.md ADDED
@@ -0,0 +1,94 @@
1
+ ---
2
+ description: "供拥有跨包标识符的包使用的名义字符串类型与无状态构造函数。"
3
+ kind: "package-library"
4
+ ---
5
+
6
+ # @buddhilive/dsh-brand
7
+
8
+ [English](README.md) | 中文
9
+
10
+ ## 概述
11
+
12
+ `dsh-brand` 让结构相同的字符串在类型层面不可互换:即使 `SessionId` 与 `ToolCallId` 在运行时都是普通字符串,前者也无法传给期望后者的位置。`brandString<T>()` 为领域拥有的字符串应用名义品牌且不持有共享运行时状态,让能力包可以拥有自己的具体 id 类型,而无需导入不相关的能力。
13
+
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [理解实现](#understand-the-implementation)
18
+ - [进一步探索](#further-exploration)
19
+ - [开发备注](#dev-note)
20
+
21
+ -----
22
+
23
+ <a id="use-this-package"></a>
24
+ ## 使用本包
25
+
26
+ 当包拥有的 id 跨越包边界、并可能与其他包的 id 混淆时,为其添加品牌;并非每个字符串都需要品牌。品牌化 id 是给 TypeScript 调用方的约定:它只会进入期望它的函数,来自其他包的 id 会在编译期被拒绝。
27
+
28
+ ### 为字符串添加品牌
29
+
30
+ 在所属包中声明品牌化类型,并在该包准入字符串的位置应用品牌:
31
+
32
+ ```ts
33
+ import { brandString, type Branded } from '@buddhilive/dsh-brand'
34
+
35
+ export type SessionId = Branded<'SessionId'>
36
+
37
+ const sessionId = brandString<SessionId>('session-1')
38
+ ```
39
+
40
+ `brandString()` 只改变静态类型,不执行运行时校验。所属类型若有领域文法,应在调用前完成校验。添加品牌后,该 id 与普通字符串一样比较、记录日志、序列化为 JSON 和跨 wire 传输。
41
+
42
+ ### 何时添加品牌
43
+
44
+ 为跨包边界且可能被混淆的 id 添加品牌——`dsh-llm` 中的 `ToolCallId`、`dsh-session` 中共享的 agent/会话 `SessionId`、`dsh-jobs` 中的 `JobId`、`dsh-lsp` 中的 `LspProviderId`。从不离开所属包的字符串不需要这种抽象。
45
+
46
+ -----
47
+
48
+ <a id="understand-the-implementation"></a>
49
+ ## 理解实现
50
+
51
+ <details>
52
+ <summary>实现细节——点击展开</summary>
53
+
54
+ 该原语是一个交叉类型:`string & { readonly [BRAND]: B }`,其中 `BRAND` 是模块私有的 `unique symbol`。
55
+
56
+ ### 源码地图
57
+
58
+ | 文件 | 职责 |
59
+ |---|---|
60
+ | [`src/index.ts`](src/index.ts) | 品牌化字符串类型及其无状态构造函数 |
61
+ | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件(无运行时不变式;擦除由编译器保证) |
62
+
63
+ ### 值为何可移植
64
+
65
+ 私有 symbol 在运行时不存在:TypeScript 会将其擦除,因此品牌化值没有标签或 prototype。`brandString()` 原样返回输入。因此,彼此独立安装的副本无需共享注册表或 constructor identity,也会生成可互换的值。
66
+
67
+ ### 为何保持无依赖
68
+
69
+ 把这些 helper 放在独立包中,意味着 `dsh-jobs` 可以为 `JobId` 添加品牌,而无需导入不相关的能力包;每个能力仍然拥有其具体 id 的含义与校验。
70
+
71
+ </details>
72
+
73
+ -----
74
+
75
+ <a id="further-exploration"></a>
76
+ ## 进一步探索
77
+
78
+ 当你需要本原语所品牌化的 id 或围绕它的类型约定时,阅读以下页面。
79
+
80
+ - [核心子系统](../../../docs/subsystems/core.zh.md)——共享 `SessionId` 品牌与类型规则的记录位置。
81
+ - [LSP 子系统](../../../docs/subsystems/lsp.zh.md)——构建在本原语之上的品牌化提供方 id `LspProviderId`。
82
+ - [jobs 包](../../jobs/jobs/README.zh.md)——由 jobs 能力拥有的 `JobId` 品牌。
83
+
84
+ -----
85
+
86
+ <a id="dev-note"></a>
87
+ ## 开发备注
88
+
89
+ <details>
90
+ <summary>维护者的工作上下文——点击展开</summary>
91
+
92
+ 无。
93
+
94
+ </details>
package/lib/index.js ADDED
@@ -0,0 +1,24 @@
1
+ //#region lib/types/index.js
2
+ /**
3
+ * Duplicate-install-safe nominal string helpers.
4
+ *
5
+ * A brand makes structurally-identical strings non-interchangeable at the type
6
+ * level: a `SessionId` cannot be passed where a `ToolCallId` is expected, even
7
+ * though both are plain strings at runtime. Comparison, logging, and
8
+ * serialization all behave as ordinary strings.
9
+ *
10
+ * This package owns no concrete id and keeps no runtime identity or mutable
11
+ * state, so independently installed copies produce interchangeable values.
12
+ *
13
+ * @module @buddhilive/dsh-brand
14
+ */
15
+ /**
16
+ * Apply a compile-time string brand without changing the value.
17
+ * @param value - string admitted by the domain that owns the target brand.
18
+ * @returns the same string with the requested compile-time brand.
19
+ */
20
+ function brandString(value) {
21
+ return value;
22
+ }
23
+ //#endregion
24
+ export { brandString };
@@ -0,0 +1,22 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@buddhilive/dsh-brand`.
4
+ * @module @buddhilive/dsh-brand/invariant
5
+ */
6
+ const PACKAGE_NAME = "@buddhilive/dsh-brand";
7
+ /** Cordis companion plugin name. */
8
+ const name = "brand-invariant";
9
+ /** Service required before the companion can reserve package ownership. */
10
+ const inject = ["invariants"];
11
+ /**
12
+ * No runtime invariant: this utility owns no event stream, shared identity, or mutable module state.
13
+ */
14
+ const install = () => {};
15
+ /**
16
+ * Register this package's invariant companion.
17
+ * @param ctx - Cordis context carrying the invariant service.
18
+ * @returns the installed registration's disposer after setup succeeds.
19
+ */
20
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
21
+ //#endregion
22
+ export { apply, inject, name };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Duplicate-install-safe nominal string helpers.
3
+ *
4
+ * A brand makes structurally-identical strings non-interchangeable at the type
5
+ * level: a `SessionId` cannot be passed where a `ToolCallId` is expected, even
6
+ * though both are plain strings at runtime. Comparison, logging, and
7
+ * serialization all behave as ordinary strings.
8
+ *
9
+ * This package owns no concrete id and keeps no runtime identity or mutable
10
+ * state, so independently installed copies produce interchangeable values.
11
+ *
12
+ * @module @buddhilive/dsh-brand
13
+ */
14
+ declare const BRAND: unique symbol;
15
+ /** A string carrying a compile-time-only brand `B`. */
16
+ export type Branded<B extends string> = string & {
17
+ readonly [BRAND]: B;
18
+ };
19
+ /**
20
+ * Apply a compile-time string brand without changing the value.
21
+ * @param value - string admitted by the domain that owns the target brand.
22
+ * @returns the same string with the requested compile-time brand.
23
+ */
24
+ export declare function brandString<T extends Branded<string>>(value: string | T): T;
25
+ export {};
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@buddhilive/dsh-brand`.
3
+ * @module @buddhilive/dsh-brand/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "brand-invariant";
8
+ /** Service required before the companion can reserve package ownership. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@buddhilive/dsh-brand",
3
+ "description": "Stateless branded-string primitives for the DeepSeek Harness",
4
+ "version": "0.1.2-alpha.3",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Buddhilive/buddhi-ai-harness.git",
11
+ "directory": "packages/util/brand"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./invariant": {
22
+ "types": "./lib/types/invariant.d.ts",
23
+ "default": "./lib/invariant.js"
24
+ },
25
+ "./src/*": "./src/*",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "lib/index.js",
30
+ "lib/invariant.js",
31
+ "lib/types/**/*.d.ts"
32
+ ],
33
+ "license": "MIT",
34
+ "peerDependencies": {
35
+ "@buddhilive/dsh-invariants": "^0.1.2-alpha.3",
36
+ "@deepseek-ai/cordis": "^4.0.2"
37
+ },
38
+ "devDependencies": {
39
+ "@buddhilive/dsh-invariants": "^0.1.2-alpha.3",
40
+ "@deepseek-ai/cordis": "^4.0.2"
41
+ }
42
+ }