dsh-working-activity 0.1.0 → 0.2.0
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 +28 -0
- package/README.md +25 -14
- package/cordis.patch.yml +19 -0
- package/lib/client.js +80 -0
- package/lib/client.js.map +1 -0
- package/lib/types/client/WorkingLine.d.ts +9 -0
- package/lib/types/client/WorkingLine.d.ts.map +1 -0
- package/lib/types/client/WorkingLine.js +14 -0
- package/lib/types/client/activity.d.ts +48 -0
- package/lib/types/client/activity.d.ts.map +1 -0
- package/lib/types/client/activity.js +18 -0
- package/lib/types/client/index.d.ts +25 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/index.js +19 -0
- package/package.json +35 -4
- package/src/client/WorkingLine.module.css +74 -0
- package/src/client/WorkingLine.tsx +37 -0
- package/src/client/activity.ts +50 -0
- package/src/client/css-modules.d.ts +6 -0
- package/src/client/index.ts +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, chimney (ccch1mneyyy)
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -18,26 +18,37 @@ Two optional sinks, both off by default only when their seam is absent:
|
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
|
+
The package is a self-mounting bundle: it declares `dsh.bundle.patch`
|
|
22
|
+
(`cordis.patch.yml`), so the official CLI both installs it and appends it to
|
|
23
|
+
the profile's bundle layer stack:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
dsh plugin --profile <profile> add dsh-working-activity
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
At boot, app-boot applies the bundle's patch list over the profile root and
|
|
30
|
+
the package inserts its own `working-activity` row — no manual configuration
|
|
31
|
+
required. To tune a value, override the row's config by id in the profile's
|
|
32
|
+
user layer (`$DSH_HOME/profiles/<profile>/cordis.patch.yml`) instead of
|
|
33
|
+
inserting a second same-id row:
|
|
34
|
+
|
|
21
35
|
```yaml
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
name: 'dsh-working-activity'
|
|
36
|
+
- id: working-activity
|
|
37
|
+
config:
|
|
38
|
+
publishIntervalMs: 500
|
|
26
39
|
```
|
|
27
40
|
|
|
28
41
|
## TUI usage
|
|
29
42
|
|
|
30
|
-
|
|
43
|
+
Install the plugin into a profile that composes the official `dsh-tui`, then
|
|
44
|
+
add the `${activity}` slot to the left prompt template in the profile's user
|
|
45
|
+
layer (`$DSH_HOME/profiles/<profile>/cordis.patch.yml`):
|
|
31
46
|
|
|
32
47
|
```yaml
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
theme:
|
|
38
|
-
leftPrompt: '${cwd}${git/worktree}${activity}${model}${token_meter/cache_hit_rate}${context}'
|
|
39
|
-
- id: working-activity
|
|
40
|
-
name: 'dsh-working-activity'
|
|
48
|
+
- id: tui
|
|
49
|
+
config:
|
|
50
|
+
theme:
|
|
51
|
+
leftPrompt: '${cwd}${git/worktree}${activity}${model}${token_meter/cache_hit_rate}${context}'
|
|
41
52
|
```
|
|
42
53
|
|
|
43
54
|
While a turn runs, the prompt line shows e.g. `dsh main 跑个命令 npm test · 12s deepseek-chat …`; while thinking, `嗯…让我捋捋 · 总1m23s`; after the turn, `搞定 ✓ · 4 工具 · 想12s 干11s` briefly. Without `${activity}` in the template, the plugin is inert in the TUI (the slot is unregistered values are omitted by the template renderer).
|
|
@@ -57,7 +68,7 @@ Both fall back to the previous static label while the plugin is absent, so the W
|
|
|
57
68
|
|---|---|---|---|
|
|
58
69
|
| `phrases` | `boolean` | `true` | Playful copy pool; `false` renders plain functional labels |
|
|
59
70
|
| `publish` | `boolean` | `true` | Append `activity/status` session events for UI consumers |
|
|
60
|
-
| `tickMs` | `number` | `500` | Status render tick interval (
|
|
71
|
+
| `tickMs` | `number` | `500` | Status render tick interval (100–5000) |
|
|
61
72
|
| `publishIntervalMs` | `number` | `2000` | Minimum interval between published events while the line is stable (500–30000) |
|
|
62
73
|
| `detailLimit` | `number` | `40` | Max displayed detail length (paths/commands/patterns), 8–120 |
|
|
63
74
|
| `customActions` | `object` | `{}` | Exact tool-name → action-copy pools, e.g. `{"my_deploy": ["部署一下", "上线中"]}` |
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# dsh-working-activity bundle patch: mount the plugin itself into the
|
|
2
|
+
# profile composition tree.
|
|
3
|
+
#
|
|
4
|
+
# `dsh plugin --profile <name> add dsh-working-activity` auto-initializes the
|
|
5
|
+
# profile (first layer @deepseek-ai/dsh-base), pnpm-installs this package into
|
|
6
|
+
# the profile, and the CLI's reconcile step appends it to the profile's
|
|
7
|
+
# dsh.profile.bundles because this package.json declares `dsh.bundle.patch`.
|
|
8
|
+
# At boot, app-boot applies every bundle's patch list in bundle order over the
|
|
9
|
+
# empty root; this insert list is what actually mounts the working-activity
|
|
10
|
+
# row — no manual configuration is needed.
|
|
11
|
+
#
|
|
12
|
+
# All row config stays at schema defaults (phrases/publish/tickMs/
|
|
13
|
+
# publishIntervalMs/detailLimit/customActions/narrate). To tune a value (for
|
|
14
|
+
# dsh-cc, set publishIntervalMs to 500), override this row's config by id in
|
|
15
|
+
# the profile's own cordis.patch.yml user layer — do NOT insert a second
|
|
16
|
+
# same-id row.
|
|
17
|
+
- insert:
|
|
18
|
+
- id: working-activity
|
|
19
|
+
name: 'dsh-working-activity'
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "dsh-working-activity",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
//#region \0dsh-css:C:\Users\17481\AppData\Local\Temp\dshwa-scan\packages\activity\working-activity\src\client\WorkingLine.module.css.mjs
|
|
9
|
+
const css = ".GDqYEG_line{box-sizing:border-box;width:100%;max-width:var(--dsh-composer-card-max-width);font-family:var(--dsw-font-family);color:var(--dsw-alias-label-secondary);align-items:center;gap:8px;margin:0 auto;padding:4px 16px 0;font-size:13px;line-height:18px;display:flex}.GDqYEG_marker{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:7px;height:7px;animation:1.6s ease-in-out infinite GDqYEG_working-pulse}.GDqYEG_line[data-activity-phase=done] .GDqYEG_marker{background:var(--dsw-alias-state-business-primary);animation:none}.GDqYEG_line[data-activity-phase=tool] .GDqYEG_marker{background:var(--dsw-alias-state-business-primary)}.GDqYEG_line[data-activity-phase=waiting] .GDqYEG_marker{background:var(--dsw-alias-label-tertiary);opacity:.6}.GDqYEG_text{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.GDqYEG_tools{background:var(--dsw-alias-surface-tertiary);min-width:18px;color:var(--dsw-alias-label-secondary);text-align:center;border-radius:9px;flex:none;padding:0 5px;font-size:11px;line-height:18px}@keyframes GDqYEG_working-pulse{0%,to{opacity:1}50%{opacity:.35}}";
|
|
10
|
+
const tagId = "dsh-working-activity/WorkingLine.module.css";
|
|
11
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
12
|
+
const tag = document.createElement("style");
|
|
13
|
+
tag.dataset.plugin = "dsh-working-activity";
|
|
14
|
+
tag.dataset.pluginCss = tagId;
|
|
15
|
+
tag.textContent = css;
|
|
16
|
+
document.head.appendChild(tag);
|
|
17
|
+
}
|
|
18
|
+
var WorkingLine_module_css_default = {
|
|
19
|
+
"line": "GDqYEG_line",
|
|
20
|
+
"working-pulse": "GDqYEG_working-pulse",
|
|
21
|
+
"tools": "GDqYEG_tools",
|
|
22
|
+
"text": "GDqYEG_text",
|
|
23
|
+
"marker": "GDqYEG_marker"
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/client/WorkingLine.tsx
|
|
27
|
+
/** Tool-count badge copy (no locale seat: the line text itself is host-composed). */
|
|
28
|
+
const TOOLS_LABEL = "tools this turn";
|
|
29
|
+
/**
|
|
30
|
+
* Working-line dock entry: reads the latest activity snapshot off the
|
|
31
|
+
* conversation snapshot and renders the row, or nothing when idle/absent.
|
|
32
|
+
*/
|
|
33
|
+
function WorkingLine({ useSession }) {
|
|
34
|
+
const activity = useSession((s) => s.activity);
|
|
35
|
+
if (activity === null || activity.phase === "idle" || activity.line === "") return null;
|
|
36
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
37
|
+
className: WorkingLine_module_css_default.line,
|
|
38
|
+
"data-activity-phase": activity.phase,
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
41
|
+
className: WorkingLine_module_css_default.marker,
|
|
42
|
+
"aria-hidden": "true"
|
|
43
|
+
}),
|
|
44
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
45
|
+
className: WorkingLine_module_css_default.text,
|
|
46
|
+
children: activity.line
|
|
47
|
+
}),
|
|
48
|
+
activity.toolCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
49
|
+
className: WorkingLine_module_css_default.tools,
|
|
50
|
+
title: `${activity.toolCount} ${TOOLS_LABEL}`,
|
|
51
|
+
children: activity.toolCount
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/client/index.ts
|
|
58
|
+
/** Required services for the dock registration. */
|
|
59
|
+
const inject = ["slots"];
|
|
60
|
+
/**
|
|
61
|
+
* Client plugin body: the working-line dock entry.
|
|
62
|
+
* @param ctx - client root context.
|
|
63
|
+
*/
|
|
64
|
+
function apply(ctx) {
|
|
65
|
+
ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
|
|
66
|
+
name: "conversation.input.dock",
|
|
67
|
+
id: "activity",
|
|
68
|
+
order: 15,
|
|
69
|
+
registrant: "dsh-working-activity"
|
|
70
|
+
}, WorkingLine));
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
exports.WorkingLine = WorkingLine;
|
|
74
|
+
exports.apply = apply;
|
|
75
|
+
exports.inject = inject;
|
|
76
|
+
return module.exports;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","names":["css"],"sources":["../src/client/WorkingLine.tsx","../src/client/index.ts"],"sourcesContent":["// Working-line dock entry: one dim full-width row above the composer card\n// showing the live working-activity snapshot — phase-colored breathing\n// marker, the host-composed status line, and the turn's tool count badge.\n// Renders for every live phase (waiting/thinking/tool) and the done summary;\n// hides while idle or before the first publish.\n//\n// The 'conversation.input.dock' SlotMap declaration lives in\n// @deepseek-ai/dsh-client-ui-conversation/client (contract/slots.ts); this\n// entry contributes into it without owning it.\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport css from './WorkingLine.module.css'\n\n/** Full props of the dock entry: the input-zone runtime share (session standard kit). */\nexport type WorkingLineProps = PropsRuntime<'conversation.input.dock'>\n\n/** Tool-count badge copy (no locale seat: the line text itself is host-composed). */\nconst TOOLS_LABEL = 'tools this turn'\n\n/**\n * Working-line dock entry: reads the latest activity snapshot off the\n * conversation snapshot and renders the row, or nothing when idle/absent.\n */\nexport function WorkingLine({ useSession }: WorkingLineProps) {\n const activity = useSession(s => s.activity)\n if (activity === null || activity.phase === 'idle' || activity.line === '') return null\n return (\n <div className={css.line} data-activity-phase={activity.phase}>\n <span className={css.marker} aria-hidden=\"true\" />\n <span className={css.text}>{activity.line}</span>\n {activity.toolCount > 0 && (\n <span className={css.tools} title={`${activity.toolCount} ${TOOLS_LABEL}`}>\n {activity.toolCount}\n </span>\n )}\n </div>\n )\n}\n","/**\n * Working-activity surface plugin, browser half: the working-line entry in\n * the conversation.input.dock strip. This package's node half emits\n * `activity/status` session events; the web runtime patch narrows them into\n * the conversation snapshot's `activity` member, so this dock entry reads\n * the live frame through the standard session kit and owns no store, no\n * refresh chain, and no event listener.\n *\n * Mount contract (see the root README's \"Web UI 集成\" section): the web\n * client's client-modules host scans loader entries for `dsh.client`\n * declarations and serves this package's `./client` bundle at\n * /plugins/dsh-working-activity/client.js. The entry contributes into the\n * input dock — no official-source patch is involved.\n */\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: pulls the ui-conversation SlotMap merge (the input.dock entry)\n// through the Client assembly boundary.\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { WorkingLine } from './WorkingLine.tsx'\nimport type { ActivityPhase, ActivitySnapshot } from './activity.ts'\n\nexport { WorkingLine, type WorkingLineProps } from './WorkingLine.tsx'\nexport type { ActivityPhase, ActivitySnapshot } from './activity.ts'\n\n/** Required services for the dock registration. */\nexport const inject = ['slots']\n\n/**\n * Client plugin body: the working-line dock entry.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({\n name: 'conversation.input.dock',\n // The pre-slots patch used the same id in ui-conversation; entries with\n // equal order render in registration order, and goal (10) / queue (20)\n // keep their seats — this row sits between them.\n id: 'activity',\n order: 15,\n registrant: 'dsh-working-activity',\n }, WorkingLine))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBA,MAAM,cAAc;;;;;EAMpB,SAAgB,YAAY,EAAE,cAAgC;GAC5D,MAAM,WAAW,YAAW,MAAK,EAAE,QAAQ;GAC3C,IAAI,aAAa,QAAQ,SAAS,UAAU,UAAU,SAAS,SAAS,IAAI,OAAO;GACnF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,+BAAI;IAAM,uBAAqB,SAAS;IAAxD,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,+BAAI;MAAQ,eAAY;KAAQ,CAAA;KACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,+BAAI;MAAO,UAAA,SAAS;KAAW,CAAA;KAC/C,SAAS,YAAY,KACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,+BAAI;MAAO,OAAO,GAAG,SAAS,UAAU,GAAG;MACzD,UAAA,SAAS;KACN,CAAA;IAEL;;EAET;;;;ECXA,MAAa,SAAS,CAAC,OAAO;;;;;EAM9B,SAAgB,MAAM,KAA0B;GAC9C,IAAI,MAAM,OAAO,iCAAiC,IAAI,MAAM,SAAS;IACnE,MAAM;IAIN,IAAI;IACJ,OAAO;IACP,YAAY;GACd,GAAG,WAAW,CAAC;EACjB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
/** Full props of the dock entry: the input-zone runtime share (session standard kit). */
|
|
3
|
+
export type WorkingLineProps = PropsRuntime<'conversation.input.dock'>;
|
|
4
|
+
/**
|
|
5
|
+
* Working-line dock entry: reads the latest activity snapshot off the
|
|
6
|
+
* conversation snapshot and renders the row, or nothing when idle/absent.
|
|
7
|
+
*/
|
|
8
|
+
export declare function WorkingLine({ useSession }: WorkingLineProps): import("react").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=WorkingLine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkingLine.d.ts","sourceRoot":"","sources":["../../../src/client/WorkingLine.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAGpE,yFAAyF;AACzF,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAA;AAKtE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,gBAAgB,sCAc3D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import css from './WorkingLine.module.css';
|
|
3
|
+
/** Tool-count badge copy (no locale seat: the line text itself is host-composed). */
|
|
4
|
+
const TOOLS_LABEL = 'tools this turn';
|
|
5
|
+
/**
|
|
6
|
+
* Working-line dock entry: reads the latest activity snapshot off the
|
|
7
|
+
* conversation snapshot and renders the row, or nothing when idle/absent.
|
|
8
|
+
*/
|
|
9
|
+
export function WorkingLine({ useSession }) {
|
|
10
|
+
const activity = useSession(s => s.activity);
|
|
11
|
+
if (activity === null || activity.phase === 'idle' || activity.line === '')
|
|
12
|
+
return null;
|
|
13
|
+
return (_jsxs("div", { className: css.line, "data-activity-phase": activity.phase, children: [_jsx("span", { className: css.marker, "aria-hidden": "true" }), _jsx("span", { className: css.text, children: activity.line }), activity.toolCount > 0 && (_jsx("span", { className: css.tools, title: `${activity.toolCount} ${TOOLS_LABEL}`, children: activity.toolCount }))] }));
|
|
14
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side activity snapshot type + the ConversationSnapshot merge that
|
|
3
|
+
* carries it.
|
|
4
|
+
*
|
|
5
|
+
* The host half (@deepseek-ai/dsh-working-activity's node side) publishes
|
|
6
|
+
* `activity/status` session events; the web runtime patch (dsh-client-runtime
|
|
7
|
+
* activity field, shipping separately) narrows those frames into the
|
|
8
|
+
* conversation snapshot's `activity` member. Until that runtime release lands
|
|
9
|
+
* on npm, this module re-declares the field via declaration merging so the
|
|
10
|
+
* dock component type-checks against the published rc.6 types.
|
|
11
|
+
*
|
|
12
|
+
* REMOVE the `declare module` block below once
|
|
13
|
+
* `@deepseek-ai/dsh-client-runtime/client` ships `ConversationSnapshot.activity`
|
|
14
|
+
* natively (the runtime's own `ActivityStatusView` is structurally identical
|
|
15
|
+
* to {@link ActivitySnapshot}; the two then agree by construction).
|
|
16
|
+
* @module @deepseek-ai/dsh-working-activity/client/activity
|
|
17
|
+
*/
|
|
18
|
+
/** The `activity/status` phase vocabulary, mirroring the host's ActivityPhase. */
|
|
19
|
+
export type ActivityPhase = 'idle' | 'waiting' | 'thinking' | 'tool' | 'done';
|
|
20
|
+
/** One `activity/status` snapshot as rendered by the dock line. */
|
|
21
|
+
export interface ActivitySnapshot {
|
|
22
|
+
/** Which activity phase the model is in right now. */
|
|
23
|
+
readonly phase: ActivityPhase;
|
|
24
|
+
/** Full human-readable status line (plain text, no ANSI). */
|
|
25
|
+
readonly line: string;
|
|
26
|
+
/** Short label of the current work (tool action or stage), when any. */
|
|
27
|
+
readonly label?: string;
|
|
28
|
+
/** Detail fragment (path / command / search pattern), when any. */
|
|
29
|
+
readonly detail?: string;
|
|
30
|
+
/** The playful phrase currently shown, when any. */
|
|
31
|
+
readonly phrase?: string;
|
|
32
|
+
/** Tools completed in the current turn. */
|
|
33
|
+
readonly toolCount: number;
|
|
34
|
+
/** Wall-clock milliseconds since the current turn started (0 when idle). */
|
|
35
|
+
readonly turnElapsedMs: number;
|
|
36
|
+
/** Wall-clock time the current phase started, for animations. */
|
|
37
|
+
readonly phaseStartedAt: number;
|
|
38
|
+
}
|
|
39
|
+
declare module '@deepseek-ai/dsh-client-runtime/client' {
|
|
40
|
+
interface ConversationSnapshot {
|
|
41
|
+
/**
|
|
42
|
+
* Latest validated `activity/status` snapshot (the working-activity
|
|
43
|
+
* plugin's live working line), or null before the first publish.
|
|
44
|
+
*/
|
|
45
|
+
activity: ActivitySnapshot | null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/client/activity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,kFAAkF;AAClF,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;AAE7E,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AAED,OAAO,QAAQ,wCAAwC,CAAC;IACtD,UAAU,oBAAoB;QAC5B;;;WAGG;QACH,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAA;KAClC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side activity snapshot type + the ConversationSnapshot merge that
|
|
3
|
+
* carries it.
|
|
4
|
+
*
|
|
5
|
+
* The host half (@deepseek-ai/dsh-working-activity's node side) publishes
|
|
6
|
+
* `activity/status` session events; the web runtime patch (dsh-client-runtime
|
|
7
|
+
* activity field, shipping separately) narrows those frames into the
|
|
8
|
+
* conversation snapshot's `activity` member. Until that runtime release lands
|
|
9
|
+
* on npm, this module re-declares the field via declaration merging so the
|
|
10
|
+
* dock component type-checks against the published rc.6 types.
|
|
11
|
+
*
|
|
12
|
+
* REMOVE the `declare module` block below once
|
|
13
|
+
* `@deepseek-ai/dsh-client-runtime/client` ships `ConversationSnapshot.activity`
|
|
14
|
+
* natively (the runtime's own `ActivityStatusView` is structurally identical
|
|
15
|
+
* to {@link ActivitySnapshot}; the two then agree by construction).
|
|
16
|
+
* @module @deepseek-ai/dsh-working-activity/client/activity
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working-activity surface plugin, browser half: the working-line entry in
|
|
3
|
+
* the conversation.input.dock strip. This package's node half emits
|
|
4
|
+
* `activity/status` session events; the web runtime patch narrows them into
|
|
5
|
+
* the conversation snapshot's `activity` member, so this dock entry reads
|
|
6
|
+
* the live frame through the standard session kit and owns no store, no
|
|
7
|
+
* refresh chain, and no event listener.
|
|
8
|
+
*
|
|
9
|
+
* Mount contract (see the root README's "Web UI 集成" section): the web
|
|
10
|
+
* client's client-modules host scans loader entries for `dsh.client`
|
|
11
|
+
* declarations and serves this package's `./client` bundle at
|
|
12
|
+
* /plugins/dsh-working-activity/client.js. The entry contributes into the
|
|
13
|
+
* input dock — no official-source patch is involved.
|
|
14
|
+
*/
|
|
15
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
16
|
+
export { WorkingLine, type WorkingLineProps } from './WorkingLine.tsx';
|
|
17
|
+
export type { ActivityPhase, ActivitySnapshot } from './activity.ts';
|
|
18
|
+
/** Required services for the dock registration. */
|
|
19
|
+
export declare const inject: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Client plugin body: the working-line dock entry.
|
|
22
|
+
* @param ctx - client root context.
|
|
23
|
+
*/
|
|
24
|
+
export declare function apply(ctx: ClientContext): void;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAO3E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACtE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAEpE,mDAAmD;AACnD,eAAO,MAAM,MAAM,UAAY,CAAA;AAE/B;;;GAGG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAU9C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { WorkingLine } from "./WorkingLine.js";
|
|
2
|
+
export { WorkingLine } from "./WorkingLine.js";
|
|
3
|
+
/** Required services for the dock registration. */
|
|
4
|
+
export const inject = ['slots'];
|
|
5
|
+
/**
|
|
6
|
+
* Client plugin body: the working-line dock entry.
|
|
7
|
+
* @param ctx - client root context.
|
|
8
|
+
*/
|
|
9
|
+
export function apply(ctx) {
|
|
10
|
+
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
|
11
|
+
name: 'conversation.input.dock',
|
|
12
|
+
// The pre-slots patch used the same id in ui-conversation; entries with
|
|
13
|
+
// equal order render in registration order, and goal (10) / queue (20)
|
|
14
|
+
// keep their seats — this row sits between them.
|
|
15
|
+
id: 'activity',
|
|
16
|
+
order: 15,
|
|
17
|
+
registrant: 'dsh-working-activity',
|
|
18
|
+
}, WorkingLine));
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-working-activity",
|
|
3
3
|
"description": "Live model working-status line: playful copy, running tool, turn elapsed — for TUI prompt and Web UI",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/types/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
"types": "./lib/types/index.d.ts",
|
|
11
11
|
"default": "./lib/types/index.js"
|
|
12
12
|
},
|
|
13
|
+
"./client": {
|
|
14
|
+
"types": "./lib/types/client/index.d.ts",
|
|
15
|
+
"default": "./lib/client.js"
|
|
16
|
+
},
|
|
13
17
|
"./events": {
|
|
14
18
|
"types": "./lib/types/events.d.ts",
|
|
15
19
|
"default": "./lib/types/events.js"
|
|
@@ -22,20 +26,36 @@
|
|
|
22
26
|
"types": "./lib/types/status.d.ts",
|
|
23
27
|
"default": "./lib/types/status.js"
|
|
24
28
|
},
|
|
29
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
25
30
|
"./src/*": "./src/*",
|
|
26
31
|
"./package.json": "./package.json"
|
|
27
32
|
},
|
|
28
33
|
"files": [
|
|
29
34
|
"lib",
|
|
30
|
-
"src"
|
|
35
|
+
"src",
|
|
36
|
+
"cordis.patch.yml"
|
|
31
37
|
],
|
|
32
38
|
"engines": {
|
|
33
39
|
"node": "^22.19 || >=24"
|
|
34
40
|
},
|
|
35
41
|
"scripts": {
|
|
36
|
-
"build": "tsc -p tsconfig.json"
|
|
42
|
+
"build": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
|
|
43
|
+
"build:client": "tsdown -c tsdown.config.ts"
|
|
37
44
|
},
|
|
38
45
|
"license": "BSD-3-Clause",
|
|
46
|
+
"dsh": {
|
|
47
|
+
"bundle": {
|
|
48
|
+
"patch": "./cordis.patch.yml"
|
|
49
|
+
},
|
|
50
|
+
"client": {
|
|
51
|
+
"platform": "web",
|
|
52
|
+
"inject": [
|
|
53
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-slots"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
},
|
|
39
59
|
"dependencies": {
|
|
40
60
|
"@deepseek-ai/schemastery": "^3.18.1"
|
|
41
61
|
},
|
|
@@ -44,7 +64,11 @@
|
|
|
44
64
|
"@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
|
|
45
65
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
46
66
|
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
47
|
-
"@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6"
|
|
67
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
|
|
68
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
71
|
+
"react": "^18.2.0"
|
|
48
72
|
},
|
|
49
73
|
"devDependencies": {
|
|
50
74
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
@@ -55,7 +79,14 @@
|
|
|
55
79
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
|
|
56
80
|
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
57
81
|
"@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
|
|
82
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
|
|
58
85
|
"@types/node": "^22.0.0",
|
|
86
|
+
"@types/react": "~18.3.1",
|
|
87
|
+
"lightningcss": "^1.32.0",
|
|
88
|
+
"react": "^18.2.0",
|
|
89
|
+
"tsdown": "^0.22.2",
|
|
59
90
|
"typescript": "^6.0.3"
|
|
60
91
|
}
|
|
61
92
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* Working line row: one dim line with a phase-colored breathing marker and
|
|
2
|
+
the turn's tool-count badge, sized to the composer dock inset like the
|
|
3
|
+
queue strip. Mirrors the pre-slots patch's WorkingLine visuals, re-targeted
|
|
4
|
+
at the rc.6 design tokens. */
|
|
5
|
+
|
|
6
|
+
.line {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: 8px;
|
|
11
|
+
width: 100%;
|
|
12
|
+
max-width: var(--dsh-composer-card-max-width);
|
|
13
|
+
margin: 0 auto;
|
|
14
|
+
padding: 4px 16px 0;
|
|
15
|
+
font-family: var(--dsw-font-family);
|
|
16
|
+
font-size: 13px;
|
|
17
|
+
line-height: 18px;
|
|
18
|
+
color: var(--dsw-alias-label-secondary);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.marker {
|
|
22
|
+
flex: none;
|
|
23
|
+
width: 7px;
|
|
24
|
+
height: 7px;
|
|
25
|
+
border-radius: 50%;
|
|
26
|
+
background: var(--dsw-alias-label-tertiary);
|
|
27
|
+
animation: working-pulse 1.6s ease-in-out infinite;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* The model's turn is done: steady marker in the brand tone, no pulse. */
|
|
31
|
+
.line[data-activity-phase='done'] .marker {
|
|
32
|
+
background: var(--dsw-alias-state-business-primary);
|
|
33
|
+
animation: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* A tool is actually executing: brand-tone pulse. */
|
|
37
|
+
.line[data-activity-phase='tool'] .marker {
|
|
38
|
+
background: var(--dsw-alias-state-business-primary);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* Waiting for the first token: muted pulse. */
|
|
42
|
+
.line[data-activity-phase='waiting'] .marker {
|
|
43
|
+
background: var(--dsw-alias-label-tertiary);
|
|
44
|
+
opacity: 0.6;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.text {
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
text-overflow: ellipsis;
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.tools {
|
|
54
|
+
flex: none;
|
|
55
|
+
min-width: 18px;
|
|
56
|
+
padding: 0 5px;
|
|
57
|
+
border-radius: 9px;
|
|
58
|
+
background: var(--dsw-alias-surface-tertiary);
|
|
59
|
+
color: var(--dsw-alias-label-secondary);
|
|
60
|
+
font-size: 11px;
|
|
61
|
+
line-height: 18px;
|
|
62
|
+
text-align: center;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@keyframes working-pulse {
|
|
66
|
+
0%,
|
|
67
|
+
100% {
|
|
68
|
+
opacity: 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
50% {
|
|
72
|
+
opacity: 0.35;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Working-line dock entry: one dim full-width row above the composer card
|
|
2
|
+
// showing the live working-activity snapshot — phase-colored breathing
|
|
3
|
+
// marker, the host-composed status line, and the turn's tool count badge.
|
|
4
|
+
// Renders for every live phase (waiting/thinking/tool) and the done summary;
|
|
5
|
+
// hides while idle or before the first publish.
|
|
6
|
+
//
|
|
7
|
+
// The 'conversation.input.dock' SlotMap declaration lives in
|
|
8
|
+
// @deepseek-ai/dsh-client-ui-conversation/client (contract/slots.ts); this
|
|
9
|
+
// entry contributes into it without owning it.
|
|
10
|
+
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
|
|
11
|
+
import css from './WorkingLine.module.css'
|
|
12
|
+
|
|
13
|
+
/** Full props of the dock entry: the input-zone runtime share (session standard kit). */
|
|
14
|
+
export type WorkingLineProps = PropsRuntime<'conversation.input.dock'>
|
|
15
|
+
|
|
16
|
+
/** Tool-count badge copy (no locale seat: the line text itself is host-composed). */
|
|
17
|
+
const TOOLS_LABEL = 'tools this turn'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Working-line dock entry: reads the latest activity snapshot off the
|
|
21
|
+
* conversation snapshot and renders the row, or nothing when idle/absent.
|
|
22
|
+
*/
|
|
23
|
+
export function WorkingLine({ useSession }: WorkingLineProps) {
|
|
24
|
+
const activity = useSession(s => s.activity)
|
|
25
|
+
if (activity === null || activity.phase === 'idle' || activity.line === '') return null
|
|
26
|
+
return (
|
|
27
|
+
<div className={css.line} data-activity-phase={activity.phase}>
|
|
28
|
+
<span className={css.marker} aria-hidden="true" />
|
|
29
|
+
<span className={css.text}>{activity.line}</span>
|
|
30
|
+
{activity.toolCount > 0 && (
|
|
31
|
+
<span className={css.tools} title={`${activity.toolCount} ${TOOLS_LABEL}`}>
|
|
32
|
+
{activity.toolCount}
|
|
33
|
+
</span>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side activity snapshot type + the ConversationSnapshot merge that
|
|
3
|
+
* carries it.
|
|
4
|
+
*
|
|
5
|
+
* The host half (@deepseek-ai/dsh-working-activity's node side) publishes
|
|
6
|
+
* `activity/status` session events; the web runtime patch (dsh-client-runtime
|
|
7
|
+
* activity field, shipping separately) narrows those frames into the
|
|
8
|
+
* conversation snapshot's `activity` member. Until that runtime release lands
|
|
9
|
+
* on npm, this module re-declares the field via declaration merging so the
|
|
10
|
+
* dock component type-checks against the published rc.6 types.
|
|
11
|
+
*
|
|
12
|
+
* REMOVE the `declare module` block below once
|
|
13
|
+
* `@deepseek-ai/dsh-client-runtime/client` ships `ConversationSnapshot.activity`
|
|
14
|
+
* natively (the runtime's own `ActivityStatusView` is structurally identical
|
|
15
|
+
* to {@link ActivitySnapshot}; the two then agree by construction).
|
|
16
|
+
* @module @deepseek-ai/dsh-working-activity/client/activity
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** The `activity/status` phase vocabulary, mirroring the host's ActivityPhase. */
|
|
20
|
+
export type ActivityPhase = 'idle' | 'waiting' | 'thinking' | 'tool' | 'done'
|
|
21
|
+
|
|
22
|
+
/** One `activity/status` snapshot as rendered by the dock line. */
|
|
23
|
+
export interface ActivitySnapshot {
|
|
24
|
+
/** Which activity phase the model is in right now. */
|
|
25
|
+
readonly phase: ActivityPhase
|
|
26
|
+
/** Full human-readable status line (plain text, no ANSI). */
|
|
27
|
+
readonly line: string
|
|
28
|
+
/** Short label of the current work (tool action or stage), when any. */
|
|
29
|
+
readonly label?: string
|
|
30
|
+
/** Detail fragment (path / command / search pattern), when any. */
|
|
31
|
+
readonly detail?: string
|
|
32
|
+
/** The playful phrase currently shown, when any. */
|
|
33
|
+
readonly phrase?: string
|
|
34
|
+
/** Tools completed in the current turn. */
|
|
35
|
+
readonly toolCount: number
|
|
36
|
+
/** Wall-clock milliseconds since the current turn started (0 when idle). */
|
|
37
|
+
readonly turnElapsedMs: number
|
|
38
|
+
/** Wall-clock time the current phase started, for animations. */
|
|
39
|
+
readonly phaseStartedAt: number
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
declare module '@deepseek-ai/dsh-client-runtime/client' {
|
|
43
|
+
interface ConversationSnapshot {
|
|
44
|
+
/**
|
|
45
|
+
* Latest validated `activity/status` snapshot (the working-activity
|
|
46
|
+
* plugin's live working line), or null before the first publish.
|
|
47
|
+
*/
|
|
48
|
+
activity: ActivitySnapshot | null
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Working-activity surface plugin, browser half: the working-line entry in
|
|
3
|
+
* the conversation.input.dock strip. This package's node half emits
|
|
4
|
+
* `activity/status` session events; the web runtime patch narrows them into
|
|
5
|
+
* the conversation snapshot's `activity` member, so this dock entry reads
|
|
6
|
+
* the live frame through the standard session kit and owns no store, no
|
|
7
|
+
* refresh chain, and no event listener.
|
|
8
|
+
*
|
|
9
|
+
* Mount contract (see the root README's "Web UI 集成" section): the web
|
|
10
|
+
* client's client-modules host scans loader entries for `dsh.client`
|
|
11
|
+
* declarations and serves this package's `./client` bundle at
|
|
12
|
+
* /plugins/dsh-working-activity/client.js. The entry contributes into the
|
|
13
|
+
* input dock — no official-source patch is involved.
|
|
14
|
+
*/
|
|
15
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
|
|
16
|
+
// Type-only: pulls the ui-conversation SlotMap merge (the input.dock entry)
|
|
17
|
+
// through the Client assembly boundary.
|
|
18
|
+
import type {} from '@deepseek-ai/dsh-client-ui-conversation/client'
|
|
19
|
+
import { WorkingLine } from './WorkingLine.tsx'
|
|
20
|
+
import type { ActivityPhase, ActivitySnapshot } from './activity.ts'
|
|
21
|
+
|
|
22
|
+
export { WorkingLine, type WorkingLineProps } from './WorkingLine.tsx'
|
|
23
|
+
export type { ActivityPhase, ActivitySnapshot } from './activity.ts'
|
|
24
|
+
|
|
25
|
+
/** Required services for the dock registration. */
|
|
26
|
+
export const inject = ['slots']
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Client plugin body: the working-line dock entry.
|
|
30
|
+
* @param ctx - client root context.
|
|
31
|
+
*/
|
|
32
|
+
export function apply(ctx: ClientContext): void {
|
|
33
|
+
ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({
|
|
34
|
+
name: 'conversation.input.dock',
|
|
35
|
+
// The pre-slots patch used the same id in ui-conversation; entries with
|
|
36
|
+
// equal order render in registration order, and goal (10) / queue (20)
|
|
37
|
+
// keep their seats — this row sits between them.
|
|
38
|
+
id: 'activity',
|
|
39
|
+
order: 15,
|
|
40
|
+
registrant: 'dsh-working-activity',
|
|
41
|
+
}, WorkingLine))
|
|
42
|
+
}
|