@stackstackstack/dsh-command-feedback 0.1.5

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/feedback/command-feedback/README.md
5
+ README.md: 3882d2a28c6f6f5165e6e1b432027aea3f982c21
6
+ README.zh.md: 2c745938c587d685138a60d970b47884a5943d0a
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @stackstackstack/dsh-command-feedback
2
+
3
+ English | [中文](README.zh.md)
4
+
5
+ Trigger-independent session feedback plus human-facing `/feedback` capture. The package exports `recordFeedback(session, text)`, which appends one log-only `feedback/record` event. Its plugin registers one global command through [`ctx.commands`](../../interaction/commands/README.md), so every composed command adapter discovers it; the shipped Web client executes it without a model turn.
6
+
7
+ ## Command contract
8
+
9
+ | Input | Result |
10
+ |---|---|
11
+ | `/feedback <text>` | Append `feedback/record` and acknowledge with `Feedback recorded for session {sessionId}`, `Anonymous user: {userId}`, plus the session-sharing disclosure. |
12
+ | `/feedback` | Return a direct usage error. Whitespace-only input is treated as empty. |
13
+
14
+ Surrounding whitespace is discarded, but feedback is otherwise unparsed: no truncation, case folding, or control words. Text that looks like another command, such as `/feedback /plan felt slow`, is feedback content. Repeated commands each produce their own event; nothing is replaced or merged.
15
+
16
+ ## Session-sharing disclosure
17
+
18
+ The acknowledgement names the receiving session id and reports how that session is shared, read from the mounted [`telemetry`](../../session/session-telemetry/README.md) service through the plugin context (`ctx.get('telemetry')`, never a declared injection). The disclosure is one sentence chosen from the backend's [`SessionTelemetrySharingStatus`](../../session/session-telemetry/README.md):
19
+
20
+ | Disclosed status | Acknowledgement sentence |
21
+ |---|---|
22
+ | `full` | `Session sharing is enabled.` |
23
+ | `feedback-only` | `Session sharing is feedback-gated; recording feedback releases the session prefix for sharing.` |
24
+ | `disabled` | `Session sharing is disabled.` |
25
+ | no service | `Session sharing is not configured.` |
26
+
27
+ The disclosure states the deployment's current sharing policy only; it never promises delivery or retention. With `full` or `feedback-only`, records are handed to the backend's non-blocking enqueue and the SDK owns batching, retry, and loss policy, so the sentence claims nothing about what reached a collector; `disabled` claims nothing about future reconfiguration. The disclosure adds no event and never enters the model surface.
28
+
29
+ ## What this plugin does and does not do
30
+
31
+ `recordFeedback(session, text)` is the command-independent write path. It rejects empty normalized text and appends `feedback/record { text }`; a different UI, hook, or host integration can call it without constructing a slash command. The `/feedback` handler uses that producer and starts no model work. The optional [`dsh-session-telemetry-otel`](../../session/session-telemetry-otel) consumer observes the event without changing its capture contract.
32
+
33
+ The feedback text appears in exactly one durable payload: `feedback/record`. [`dsh-commands`](../../interaction/commands/README.md) still appends its generic `command/run` / `command/done` pairing, but this definition sets `recordInput: false`, so `command/run` omits `args`; the paired `command/done` carries only the outcome. All three events are log-only and absent from the ordered surface, `deriveMessages()`, and model requests. These appends start persistence's ordinary eager drain, but neither producer forces `session/flush`, so acknowledgement means the feedback is in the log, not that it has reached disk. The acknowledgement identifies both the receiving session and the [shared anonymous user](../../identity/anonymous-user-id/); the first accepted feedback for a harness home can create `$DSH_HOME/.anonymous-user-id`. Rejected empty input leaves only the command pairing settled as `kind: 'error'`, with no `feedback/record` and no user-id lookup.
34
+
35
+ The event is authoritative rather than the command record because feedback may arrive through a trigger other than `/feedback`. Keeping the payload out of `command/run` avoids two records carrying the same text.
36
+
37
+ ## Composition
38
+
39
+ The producer injects only `commands`. A custom app mounts the registry plus this plugin:
40
+
41
+ ```yaml
42
+ - id: commands
43
+ name: '@stackstackstack/dsh-commands'
44
+ - id: command-feedback
45
+ name: '@stackstackstack/dsh-command-feedback'
46
+ ```
47
+
48
+ The shipped `dsh` base mounts this command unconditionally; it has no configuration and no dependency on the persisted-goal stack. The Web client exposes it through the command adapter. Headless mode, ACP automation, and JSON-RPC do not provide a command adapter, so they do not expose it.
49
+
50
+ ## Model Experience
51
+
52
+ ### Human `/feedback` capture
53
+
54
+ #### What the model sees
55
+
56
+ Nothing. The slash input, `feedback/record`, and the acknowledgement are absent from model requests. The feedback event and registry lifecycle records are log-only and carry no `surfaceOp`, so they never reach the ordered surface, `deriveMessages()`, or a system prompt. Recording feedback during a turn does not change that turn's remaining requests.
57
+
58
+ #### Token effect
59
+
60
+ Zero direct token effect. Neither an accepted entry nor a usage error adds model tokens, in the recording turn or any later one.
61
+
62
+ #### KV Cache effect
63
+
64
+ Independent of the model request path. Recording appends to the session log only, leaving an already-reusable request prefix untouched. Nothing this package contributes can invalidate cache reuse.
65
+
66
+ ## Known Limitations and Deferred Work
67
+
68
+ - **No feedback retrieval or management surface** — the optional OTel plugin uses the event only as a sharing trigger. There is no retrieval, aggregation, categorization, or model-facing tool for `feedback/record`.
69
+ - **No structured fields** — an entry is one free-text string with no category, severity, or referenced-event link, so feedback cannot be filtered by subject without re-reading its text.
70
+ - **No amend or withdraw** — the session log is append-only and this package adds no tombstone, so a mistaken entry stays recorded and can only be superseded by a later one.
71
+ - **No explicit durability barrier** — the acknowledgement follows the append, not a flush, so an entry recorded immediately before a crash can be lost with any other unflushed tail. Feedback is not worth forcing a synchronous disk write for; a consumer that needs one awaits `ctx.sessions.flush(session)`.
72
+ - **No visible acknowledgement on a fresh session** — the web transcript renders command rows only once a session is active, so `/feedback` on a still-blank session records the event but shows no acknowledgement row. Recording feedback after the first message renders normally.
73
+ - **Web only among the shipped entry points** — headless mode, ACP automation, and JSON-RPC do not provide a command adapter, so `/feedback` is unavailable there.
package/README.zh.md ADDED
@@ -0,0 +1,73 @@
1
+ # @stackstackstack/dsh-command-feedback
2
+
3
+ [English](README.md) | 中文
4
+
5
+ 与触发方式无关的会话反馈,以及面向用户的 `/feedback` 采集。本包导出 `recordFeedback(session, text)`;该函数会追加一个仅写入日志的 `feedback/record` 事件。该插件通过 [`ctx.commands`](../../interaction/commands/README.md) 注册一个全局命令,因此每个已组合的命令适配器都能发现它;随附的 Web 客户端无需模型轮次即可执行。
6
+
7
+ ## 命令约定
8
+
9
+ | 输入 | 结果 |
10
+ |---|---|
11
+ | `/feedback <text>` | 追加 `feedback/record`,并以 `Feedback recorded for session {sessionId}`、`Anonymous user: {userId}` 加会话共享披露确认。 |
12
+ | `/feedback` | 返回一个直接用法错误。仅含空白的输入视为空输入。 |
13
+
14
+ 前后空白会被丢弃,但除此之外,反馈内容不会被解析:不进行截断或大小写折叠,也不识别控制词。看起来像另一个命令的文本(例如 `/feedback /plan felt slow`)就是反馈内容。重复执行命令时,每次都会产生一个事件;不会发生替换或合并。
15
+
16
+ ## 会话共享披露
17
+
18
+ 确认文本会点名接收会话的 id,并报告该会话如何被共享;该信息通过插件上下文(`ctx.get('telemetry')`,绝不是声明的注入)从已挂载的 [`telemetry`](../../session/session-telemetry/README.md) 服务读取。披露是依据后端 [`SessionTelemetrySharingStatus`](../../session/session-telemetry/README.md) 选择的一句话:
19
+
20
+ | 披露的状态 | 确认文本中的句子 |
21
+ |---|---|
22
+ | `full` | `Session sharing is enabled.` |
23
+ | `feedback-only` | `Session sharing is feedback-gated; recording feedback releases the session prefix for sharing.` |
24
+ | `disabled` | `Session sharing is disabled.` |
25
+ | 无服务 | `Session sharing is not configured.` |
26
+
27
+ 披露只陈述部署当前的共享策略,绝不承诺投递或留存:在 `full` 或 `feedback-only` 下,记录被交给后端的非阻塞入队,批处理、重试与丢失策略归 SDK 负责,因此句子不声称任何内容已到达采集端;`disabled` 也不声称未来不会重新配置。披露不新增任何事件,也绝不会进入模型 surface。
28
+
29
+ ## 本插件做什么、不做什么
30
+
31
+ `recordFeedback(session, text)` 是不依赖命令的写入路径。它拒绝规范化后为空的文本,并追加 `feedback/record { text }`;其他 UI、钩子或 host 集成无需构造斜杠命令即可调用它。`/feedback` 处理器通过该函数写入,且不启动任何模型工作。可选的 [`dsh-session-telemetry-otel`](../../session/session-telemetry-otel) 消费方会观察该事件,但不改变它的采集约定。
32
+
33
+ 反馈文本只出现在一个持久载荷中:`feedback/record`。[`dsh-commands`](../../interaction/commands/README.md) 仍会追加通用的 `command/run` / `command/done` 配对,但此定义设置了 `recordInput: false`,因此 `command/run` 会省略 `args`;配对的 `command/done` 只携带结果。三个事件都仅写入日志,不出现在有序 surface、`deriveMessages()` 以及模型请求中。这些追加会启动持久化的常规即时排空,但两个生产方都不会强制 `session/flush`,因此确认文本表示反馈已进入日志,而不表示它已经落盘。确认文本同时标明接收反馈的会话和[共享匿名用户](../../identity/anonymous-user-id/);对于某个 harness home,首次接受反馈时可能创建 `$DSH_HOME/.anonymous-user-id`。被拒绝的空输入只会留下以 `kind: 'error'` 结算的命令配对,不会产生 `feedback/record`,也不会查找用户 id。
34
+
35
+ 权威记录是该事件,而不是命令记录,因为反馈可能来自 `/feedback` 之外的触发方式。让载荷不进入 `command/run`,可避免两条记录携带相同文本。
36
+
37
+ ## 组合
38
+
39
+ 生产方只注入 `commands`。自定义应用挂载注册表以及本插件:
40
+
41
+ ```yaml
42
+ - id: commands
43
+ name: '@stackstackstack/dsh-commands'
44
+ - id: command-feedback
45
+ name: '@stackstackstack/dsh-command-feedback'
46
+ ```
47
+
48
+ 随附的 `dsh` 基础组合无条件挂载此命令;它没有配置,也不依赖持久化 goal 栈。Web 客户端通过命令适配器暴露该命令。无头模式、ACP(Agent Client Protocol)自动化和 JSON-RPC 不提供命令适配器,因此不会暴露它。
49
+
50
+ ## 模型体验
51
+
52
+ ### 用户 `/feedback` 采集
53
+
54
+ #### 模型看到的内容
55
+
56
+ 无。斜杠输入、`feedback/record` 以及确认文本都不出现在模型请求中。反馈事件和注册表生命周期记录仅写入日志且不携带 `surfaceOp`,因此它们绝不会进入有序 surface、`deriveMessages()` 或系统提示词。在某个轮次中记录反馈不会改变该轮次剩余的请求。
57
+
58
+ #### Token 影响
59
+
60
+ 无直接 token 影响。无论是已接受的条目还是用法错误,都不会在记录所在轮次或此后任何轮次增加模型 token。
61
+
62
+ #### KV Cache 影响
63
+
64
+ 与模型请求路径无关。记录只追加到会话日志,不触碰已经可复用的请求前缀。本包贡献的任何内容都不会使缓存复用失效。
65
+
66
+ ## 已知限制与暂缓工作
67
+
68
+ - **没有反馈检索或管理 surface**:可选的 OTel 插件仅将该事件用作共享触发器。本包不为 `feedback/record` 提供检索、聚合、分类或面向模型的工具。
69
+ - **没有结构化字段**:一条条目就是一个自由文本字符串,没有类别、严重程度或关联事件链接,因此无法在不重读文本的情况下按主题过滤反馈。
70
+ - **不支持修改或撤回**:会话日志是仅追加的,本包也不新增 tombstone,因此错误的条目会一直保留在记录中,只能由后续条目取代。
71
+ - **没有显式持久化屏障**:确认文本紧随追加而非 flush,因此紧临崩溃前记录的条目可能与其他未 flush 的尾部一同丢失。为反馈强制同步写盘并不值得;需要该保证的消费方可自行等待 `ctx.sessions.flush(session)`。
72
+ - **新会话上没有可见的确认**:Web 转录只在会话激活后渲染命令行,因此在仍为空白的新会话上执行 `/feedback` 会记录事件但不会显示确认行。发送首条消息后再记录反馈即可正常渲染。
73
+ - **随附的产品入口中只有 Web 使用此命令**:无头模式、ACP(Agent Client Protocol)自动化和 JSON-RPC 不提供命令适配器,因此 `/feedback` 在那里不可用。
package/lib/index.js ADDED
@@ -0,0 +1,83 @@
1
+ import { getOrCreateAnonymousUserId } from "@stackstackstack/dsh-anonymous-user-id";
2
+ //#region lib/types/index.js
3
+ /**
4
+ * Session feedback event plus the human-facing `/feedback` producer. Recording
5
+ * appends one authoritative log-only event and does not start model work. The
6
+ * append is eager but unflushed, so acknowledgement reports that the entry is
7
+ * logged, not that it reached disk.
8
+ * @module @stackstackstack/dsh-command-feedback
9
+ */
10
+ const name = "command-feedback";
11
+ const inject = ["commands"];
12
+ const USAGE = "Usage: /feedback <text>";
13
+ /** Fail closed when a future sharing status reaches the sentence switch. */
14
+ /* v8 ignore next 3 -- only the ignored default arm calls this; the closed union cannot reach it via the public API. */
15
+ function assertNever(value) {
16
+ throw new Error(`command-feedback: unsupported sharing status ${JSON.stringify(value)}`);
17
+ }
18
+ /** The acknowledgement's sharing sentence for a disclosed policy. */
19
+ function sharingSentence(sharing) {
20
+ switch (sharing) {
21
+ case "full": return "Session sharing is enabled.";
22
+ case "feedback-only": return "Session sharing is feedback-gated; recording feedback releases the session prefix for sharing.";
23
+ case "disabled": return "Session sharing is disabled.";
24
+ /* v8 ignore next 2 -- the seam's closed union cannot reach the default; a future status must be given a sentence here. */
25
+ default: return assertNever(sharing);
26
+ }
27
+ }
28
+ /**
29
+ * The sharing disclosure appended to the acknowledgement: the mounted
30
+ * backend's disclosed policy, or a "not configured" notice when no backend
31
+ * is mounted. Read through the plugin context so the command still works
32
+ * when the telemetry service is absent.
33
+ * @param telemetry - the mounted telemetry service, or undefined.
34
+ * @returns one sentence describing this session's sharing policy.
35
+ */
36
+ function sharingDisclosure(telemetry) {
37
+ if (telemetry === void 0) return "Session sharing is not configured.";
38
+ return sharingSentence(telemetry.sharing);
39
+ }
40
+ /**
41
+ * Record feedback independently of any UI trigger.
42
+ * @param session - session the feedback describes.
43
+ * @param text - human-authored feedback; surrounding whitespace is discarded.
44
+ * @throws {TypeError} when the normalized text is empty.
45
+ */
46
+ function recordFeedback(session, text) {
47
+ const normalized = text.trim();
48
+ if (normalized.length === 0) throw new TypeError("feedback text must not be empty");
49
+ session.append("feedback/record", { text: normalized });
50
+ }
51
+ /**
52
+ * Validate, record, and acknowledge one feedback entry. Returning an error
53
+ * leaves no `feedback/record` event.
54
+ * @param invocation - receiving agent, raw command input, and UI cancellation.
55
+ * @param ctx - plugin context used to read the optional telemetry service.
56
+ * @returns an acknowledgement containing the receiving session and anonymous
57
+ * user ids plus the session-sharing disclosure, or a usage error when no
58
+ * feedback text was supplied.
59
+ */
60
+ function executeFeedbackCommand(invocation, ctx) {
61
+ if (invocation.rawInput.trim().length === 0) return {
62
+ kind: "error",
63
+ text: `Feedback text is required. ${USAGE}`
64
+ };
65
+ recordFeedback(invocation.agent.session, invocation.rawInput);
66
+ const telemetry = ctx.get("sessionTelemetry");
67
+ return {
68
+ kind: "success",
69
+ text: `Feedback recorded for session ${invocation.agent.session.id}\nAnonymous user: ${getOrCreateAnonymousUserId()}. ${sharingDisclosure(telemetry)}`
70
+ };
71
+ }
72
+ /** Register the global `/feedback` command for every composed command adapter. */
73
+ function apply(ctx) {
74
+ ctx.commands.register({
75
+ name: "feedback",
76
+ description: "record feedback about this session",
77
+ input: { hint: "<text>" },
78
+ recordInput: false,
79
+ handler: (invocation) => executeFeedbackCommand(invocation, ctx)
80
+ });
81
+ }
82
+ //#endregion
83
+ export { apply, inject, name, recordFeedback };
@@ -0,0 +1,23 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@stackstackstack/dsh-command-feedback`.
4
+ * @module @stackstackstack/dsh-command-feedback/invariant
5
+ */
6
+ const PACKAGE_NAME = "@stackstackstack/dsh-command-feedback";
7
+ /** Cordis companion plugin name. */
8
+ const name = "command-feedback-invariant";
9
+ /** Service required before the companion can reserve package ownership. */
10
+ const inject = ["invariants"];
11
+ /**
12
+ * No runtime invariant: each `feedback/record` is an independent append-only
13
+ * fact with no cross-event or mutable-data relationship.
14
+ */
15
+ const install = () => {};
16
+ /**
17
+ * Register this package's invariant companion.
18
+ * @param ctx - Cordis context carrying the invariant service.
19
+ * @returns the installed registration's disposer after setup succeeds.
20
+ */
21
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
22
+ //#endregion
23
+ export { apply, inject, name };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Session feedback event plus the human-facing `/feedback` producer. Recording
3
+ * appends one authoritative log-only event and does not start model work. The
4
+ * append is eager but unflushed, so acknowledgement reports that the entry is
5
+ * logged, not that it reached disk.
6
+ * @module @stackstackstack/dsh-command-feedback
7
+ */
8
+ import type { Context } from '@deepseek-ai/cordis';
9
+ import type { Session } from '@stackstackstack/dsh-session';
10
+ export declare const name = "command-feedback";
11
+ export declare const inject: string[];
12
+ declare module '@stackstackstack/dsh-session/types' {
13
+ interface SessionEventMap {
14
+ /**
15
+ * One recorded human remark about this session. Log-only and independent
16
+ * of its trigger; it never enters model context or derived history.
17
+ */
18
+ 'feedback/record': {
19
+ text: string;
20
+ };
21
+ }
22
+ }
23
+ /**
24
+ * Record feedback independently of any UI trigger.
25
+ * @param session - session the feedback describes.
26
+ * @param text - human-authored feedback; surrounding whitespace is discarded.
27
+ * @throws {TypeError} when the normalized text is empty.
28
+ */
29
+ export declare function recordFeedback(session: Session, text: string): void;
30
+ /** Register the global `/feedback` command for every composed command adapter. */
31
+ export declare function apply(ctx: Context): void;
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@stackstackstack/dsh-command-feedback`.
3
+ * @module @stackstackstack/dsh-command-feedback/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "command-feedback-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,54 @@
1
+ {
2
+ "name": "@stackstackstack/dsh-command-feedback",
3
+ "description": "Log-only session feedback producer and human-facing slash command",
4
+ "version": "0.1.5",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
11
+ "directory": "packages/feedback/command-feedback"
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
+ "@stackstackstack/dsh-invariants": "^0.1.5",
36
+ "@stackstackstack/dsh-commands": "^0.1.5",
37
+ "@stackstackstack/dsh-session-telemetry": "^0.1.5",
38
+ "@stackstackstack/dsh-session": "^0.1.5",
39
+ "@stackstackstack/dsh-anonymous-user-id": "^0.1.5",
40
+ "@deepseek-ai/cordis": "^4.0.1"
41
+ },
42
+ "devDependencies": {
43
+ "@deepseek-ai/cordis-plugin-include": "^1.0.6",
44
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.2",
45
+ "@stackstackstack/dsh-agent": "^0.1.5",
46
+ "@stackstackstack/dsh-commands": "^0.1.5",
47
+ "@stackstackstack/dsh-invariants": "^0.1.5",
48
+ "@stackstackstack/dsh-llm": "^0.1.5",
49
+ "@stackstackstack/dsh-session": "^0.1.5",
50
+ "@stackstackstack/dsh-session-telemetry": "^0.1.5",
51
+ "@stackstackstack/dsh-anonymous-user-id": "^0.1.5",
52
+ "@deepseek-ai/cordis": "^4.0.1"
53
+ }
54
+ }