dsh-working-activity 0.3.3 → 0.4.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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/activity/working-activity/README.md
5
- README.md: bf0787caac11a292882ba1a35963878e373e7db8
6
- README.zh.md: de09a7945dbe42c85d359fd256cdac0264d4b6cd
5
+ README.md: 5ec920a3514e566f80d36b7952c1f9b6f9a06a5a
6
+ README.zh.md: 71f191268687d26345371877e54571950f17367b
package/README.md CHANGED
@@ -38,6 +38,10 @@ inserting a second same-id row:
38
38
  publishIntervalMs: 500
39
39
  ```
40
40
 
41
+ Host and TUI integration supports the DSH `0.1.0-rc.6` and `0.1.1-rc` lines,
42
+ plus `0.1.2-alpha.2`. The optional Web client still uses the rc client-runtime
43
+ contract and is not covered by alpha.2 compatibility.
44
+
41
45
  ## TUI usage
42
46
 
43
47
  Install the plugin into a profile that composes the official `dsh-tui`, then
package/README.zh.md CHANGED
@@ -27,6 +27,10 @@ plugins:
27
27
  name: '@deepseek-ai/dsh-working-activity'
28
28
  ```
29
29
 
30
+ Host 与 TUI 集成支持 DSH `0.1.0-rc.6`、`0.1.1-rc` 版本线和
31
+ `0.1.2-alpha.2`。可选 Web 客户端仍使用 rc 版 client-runtime 契约,不在
32
+ alpha.2 兼容范围内。
33
+
30
34
  ## TUI 用法
31
35
 
32
36
  与 `dsh-tui` 一起启用插件,并把槽位加进左侧 prompt 模板:
package/lib/client.js CHANGED
@@ -18,9 +18,9 @@ window.__ModuleLoader__.load({
18
18
  var WorkingLine_module_css_default = {
19
19
  "tools": "TG_uoa_tools",
20
20
  "line": "TG_uoa_line",
21
- "working-pulse": "TG_uoa_working-pulse",
21
+ "text": "TG_uoa_text",
22
22
  "marker": "TG_uoa_marker",
23
- "text": "TG_uoa_text"
23
+ "working-pulse": "TG_uoa_working-pulse"
24
24
  };
25
25
  //#endregion
26
26
  //#region src/client/WorkingLine.tsx
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/status.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAQ5D,4CAA4C;AAC5C,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;AAE7E,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,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,0CAA0C;IAC1C,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,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,8CAA8C;IAC9C,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAChC;AAED,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;IACnC,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1C,qEAAqE;IACrE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAA;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAoCD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA+BtH;AAED;;;;;GAKG;AACH,qBAAa,eAAe;IAmDxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IApDjC,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,iBAAiB,CAAQ;IACjC,yEAAyE;IACzE,OAAO,CAAC,YAAY,CAAsB;IAC1C,6EAA6E;IAC7E,OAAO,CAAC,WAAW,CAAI;IACvB,0EAA0E;IAC1E,OAAO,CAAC,YAAY,CAAK;IACzB,kEAAkE;IAClE,OAAO,CAAC,UAAU,CAAI;IACtB,8EAA8E;IAC9E,OAAO,CAAC,UAAU,CAAmB;IACrC,kEAAkE;IAClE,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,YAAY,CAAQ;IAC5B;+DAC2D;IAC3D,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,YAAY,CAAI;IACxB,oEAAoE;IACpE,OAAO,CAAC,SAAS,CAAoB;IACrC,4CAA4C;IAC5C,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,SAAS,CAAI;IACrB,uDAAuD;IACvD,OAAO,CAAC,aAAa,CAAI;IACzB,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAQ;IACxB,mDAAmD;IACnD,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,cAAc,CAAI;IAE1B;;;;OAIG;gBAEgB,MAAM,EAAE,aAAa,EACrB,GAAG,GAAE,MAAM,MAAiB,EAC5B,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,YAAA;IAG9E,0CAA0C;IAC1C,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAc/C,wEAAwE;IACxE,aAAa,IAAI,IAAI;IAMrB,yDAAyD;IACzD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IASpC,oEAAoE;IACpE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAM1C,sEAAsE;IACtE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI7C,iEAAiE;IACjE,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAgJzC,kEAAkE;IAClE,MAAM,CAAC,KAAK,GAAE,MAAmB,GAAG,aAAa;IA0DjD,2DAA2D;IAC3D,KAAK,IAAI,SAAS;IAQlB,OAAO,CAAC,cAAc;IA8DtB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IA0BpB;oEACgE;IAChE,OAAO,CAAC,eAAe;IAgBvB,yEAAyE;IACzE,OAAO,CAAC,YAAY;IAIpB,wEAAwE;IACxE,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,WAAW;IAsBnB,6EAA6E;IAC7E,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,QAAQ;CAIjB;AAqED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB9D"}
@@ -572,15 +572,57 @@ const DONE_FRAGMENT_MS = 3000;
572
572
  const STREAM_BUFFER_CHARS = 300;
573
573
  /** A narration stays visible this long after the stream went quiet. */
574
574
  const NARRATE_GRACE_MS = 5000;
575
+ /** Narration budget in display columns: 40 CJK chars ≈ 12 English words. */
576
+ const NARRATION_MAX_COLUMNS = 80;
577
+ /** A CJK/full-width code point renders 2 terminal columns; the rest render 1. */
578
+ function isWide(cp) {
579
+ return ((cp >= 0x1100 && cp <= 0x115f) || // Hangul Jamo
580
+ (cp >= 0x2e80 && cp <= 0xa4cf) || // CJK radicals, kana, Yi
581
+ (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul syllables
582
+ (cp >= 0xf900 && cp <= 0xfaff) || // CJK compatibility ideographs
583
+ (cp >= 0xfe30 && cp <= 0xfe4f) || // CJK compatibility forms
584
+ (cp >= 0xff00 && cp <= 0xff60) || // full-width forms
585
+ (cp >= 0xffe0 && cp <= 0xffe6) || // full-width signs
586
+ (cp >= 0x20000 && cp <= 0x3fffd) // CJK extensions
587
+ );
588
+ }
589
+ /** Cut before `max` columns, backing off to the last word or clause boundary. */
590
+ function cutToWidth(text, max) {
591
+ let width = 0;
592
+ let cut = text.length;
593
+ const chars = [...text];
594
+ for (let i = 0; i < chars.length; i++) {
595
+ const w = isWide(chars[i].codePointAt(0)) ? 2 : 1;
596
+ if (width + w > max) {
597
+ cut = chars.slice(0, i).join('').length;
598
+ break;
599
+ }
600
+ width += w;
601
+ }
602
+ if (cut === text.length)
603
+ return text;
604
+ // Back off to a soft boundary so English words survive intact; dense CJK has
605
+ // none and hard-cuts at the budget like the original fixed 40-char capture.
606
+ const head = text.slice(0, cut);
607
+ const soft = Math.max(head.lastIndexOf(' '), head.lastIndexOf('\t'), head.lastIndexOf(','), head.lastIndexOf('、'), head.lastIndexOf(';'), head.lastIndexOf(';'), head.lastIndexOf(','));
608
+ return soft > 0 ? head.slice(0, soft) : head;
609
+ }
575
610
  /** Extract the latest `⏵` self-narration line from a stream buffer. */
576
611
  export function extractNarration(buffer) {
577
- const matches = [...buffer.matchAll(/⏵\s*([^\n⏵]{1,40})/g)];
578
- if (matches.length === 0)
579
- return null;
580
- const latest = matches[matches.length - 1]?.[1];
581
- if (latest === undefined)
612
+ const matches = [...buffer.matchAll(/⏵[ \t]*([^\n⏵]*)/g)];
613
+ const latest = matches[matches.length - 1]?.[1]?.trim();
614
+ if (!latest)
582
615
  return null;
583
- const text = latest.replace(/[。..!!,,、;;]+$/, '').trim();
616
+ // A missing newline must not turn the rest of the response into status text.
617
+ // Stop at sentence ends and clause delimiters, while leaving dotted
618
+ // identifiers such as `ink.tsx`, `agent.ctx` and `README.MD` intact. A dot
619
+ // ends a sentence only before whitespace, the end, or a Title-case word
620
+ // (`safely.The`); dot-uppercase-uppercase stays an extension (`.MD`).
621
+ const boundary = latest.search(/[。.!?!?;;]|\.(?=\s|$|[A-Z][a-z])/);
622
+ const sentence = boundary < 0 ? latest : latest.slice(0, boundary + 1);
623
+ // The budget is display width, so English and Chinese render equally long:
624
+ // 40 CJK characters and ~12 English words share the same line budget.
625
+ const text = cutToWidth(sentence, NARRATION_MAX_COLUMNS).replace(/[。..!!,,、;;]+$/, '').trim();
584
626
  return text.length === 0 ? null : text;
585
627
  }
586
628
  /** Format a token count compactly (`12.3k`, `1.2M`). */
package/package.json CHANGED
@@ -1,127 +1,128 @@
1
- {
2
- "name": "dsh-working-activity",
3
- "description": "Live model working-status line: playful copy, running tool, turn elapsed — for TUI prompt and Web UI",
4
- "version": "0.3.3",
5
- "type": "module",
6
- "main": "lib/types/index.js",
7
- "types": "lib/types/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./lib/types/index.d.ts",
11
- "default": "./lib/types/index.js"
12
- },
13
- "./client": {
14
- "types": "./lib/types/client/index.d.ts",
15
- "default": "./lib/client.js"
16
- },
17
- "./config": {
18
- "types": "./lib/types/config.d.ts",
19
- "default": "./lib/types/config.js"
20
- },
21
- "./events": {
22
- "types": "./lib/types/events.d.ts",
23
- "default": "./lib/types/events.js"
24
- },
25
- "./frames": {
26
- "types": "./lib/types/frames.d.ts",
27
- "default": "./lib/types/frames.js"
28
- },
29
- "./invariant": {
30
- "types": "./lib/types/invariant.d.ts",
31
- "default": "./lib/types/invariant.js"
32
- },
33
- "./status": {
34
- "types": "./lib/types/status.d.ts",
35
- "default": "./lib/types/status.js"
36
- },
37
- "./cordis.patch.yml": "./cordis.patch.yml",
38
- "./src/*": "./src/*",
39
- "./package.json": "./package.json"
40
- },
41
- "files": [
42
- "lib",
43
- "src",
44
- "cordis.patch.yml"
45
- ],
46
- "engines": {
47
- "node": "^22.19 || >=24"
48
- },
49
- "scripts": {
50
- "build": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
51
- "build:client": "tsdown -c tsdown.config.ts",
52
- "test": "vitest run",
53
- "verify:deps": "node scripts/verify-manifest-deps.mjs",
54
- "verify:lockfiles": "node scripts/verify-lockfiles.mjs",
55
- "prepublishOnly": "npm run verify:deps && npm run verify:lockfiles && npm run build && npm run build:client"
56
- },
57
- "license": "BSD-3-Clause",
58
- "repository": {
59
- "type": "git",
60
- "url": "git+https://github.com/ccch1mneyyy/working-activity.git"
61
- },
62
- "bugs": {
63
- "url": "https://github.com/ccch1mneyyy/working-activity/issues"
64
- },
65
- "homepage": "https://github.com/ccch1mneyyy/working-activity#readme",
66
- "dsh": {
67
- "bundle": {
68
- "patch": "./cordis.patch.yml"
69
- },
70
- "client": {
71
- "platform": "web",
72
- "inject": [
73
- "@deepseek-ai/dsh-client-runtime",
74
- "@deepseek-ai/dsh-client-ui-conversation",
75
- "@deepseek-ai/dsh-client-ui-slots"
76
- ]
77
- }
78
- },
79
- "peerDependencies": {
80
- "@deepseek-ai/cordis": "^4.0.1",
81
- "@deepseek-ai/dsh-agent": "^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",
85
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
86
- "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
87
- "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
88
- "@deepseek-ai/schemastery": "^3.18.1",
89
- "react": "^18.2.0"
90
- },
91
- "devDependencies": {
92
- "@deepseek-ai/cordis": "^4.0.1",
93
- "@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
94
- "@deepseek-ai/dsh-agent-loop": "^0.1.0-rc.6",
95
- "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.0-rc.6",
96
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
97
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
98
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
99
- "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
100
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
101
- "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
102
- "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
103
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
104
- "@deepseek-ai/schemastery": "^3.18.1",
105
- "@types/node": "^22.0.0",
106
- "@types/react": "~18.3.1",
107
- "lightningcss": "^1.32.0",
108
- "react": "^18.2.0",
109
- "tsdown": "^0.22.2",
110
- "typescript": "^6.0.3",
111
- "vitest": "^3.2.4"
112
- },
113
- "peerDependenciesMeta": {
114
- "@deepseek-ai/dsh-client-runtime": {
115
- "optional": true
116
- },
117
- "@deepseek-ai/dsh-client-ui-conversation": {
118
- "optional": true
119
- },
120
- "@deepseek-ai/dsh-client-ui-slots": {
121
- "optional": true
122
- },
123
- "react": {
124
- "optional": true
125
- }
126
- }
127
- }
1
+ {
2
+ "name": "dsh-working-activity",
3
+ "description": "Live model working-status line: playful copy, running tool, turn elapsed — for TUI prompt and Web UI",
4
+ "version": "0.4.0",
5
+ "type": "module",
6
+ "main": "lib/types/index.js",
7
+ "types": "lib/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/types/index.d.ts",
11
+ "default": "./lib/types/index.js"
12
+ },
13
+ "./client": {
14
+ "types": "./lib/types/client/index.d.ts",
15
+ "default": "./lib/client.js"
16
+ },
17
+ "./config": {
18
+ "types": "./lib/types/config.d.ts",
19
+ "default": "./lib/types/config.js"
20
+ },
21
+ "./events": {
22
+ "types": "./lib/types/events.d.ts",
23
+ "default": "./lib/types/events.js"
24
+ },
25
+ "./frames": {
26
+ "types": "./lib/types/frames.d.ts",
27
+ "default": "./lib/types/frames.js"
28
+ },
29
+ "./invariant": {
30
+ "types": "./lib/types/invariant.d.ts",
31
+ "default": "./lib/types/invariant.js"
32
+ },
33
+ "./status": {
34
+ "types": "./lib/types/status.d.ts",
35
+ "default": "./lib/types/status.js"
36
+ },
37
+ "./cordis.patch.yml": "./cordis.patch.yml",
38
+ "./src/*": "./src/*",
39
+ "./package.json": "./package.json"
40
+ },
41
+ "files": [
42
+ "lib",
43
+ "src",
44
+ "cordis.patch.yml"
45
+ ],
46
+ "engines": {
47
+ "node": "^22.19 || >=24"
48
+ },
49
+ "scripts": {
50
+ "build": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
51
+ "build:client": "tsdown -c tsdown.config.ts",
52
+ "test": "vitest run",
53
+ "test:alpha2": "pnpm run build && pnpm --dir ../working-activity-alpha2-compat install --frozen-lockfile --strict-peer-dependencies && pnpm --dir ../working-activity-alpha2-compat test",
54
+ "verify:deps": "node scripts/verify-manifest-deps.mjs",
55
+ "verify:lockfiles": "node scripts/verify-lockfiles.mjs",
56
+ "prepublishOnly": "npm run verify:deps && npm run verify:lockfiles && npm run build && npm run build:client"
57
+ },
58
+ "license": "BSD-3-Clause",
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/ccch1mneyyy/working-activity.git"
62
+ },
63
+ "bugs": {
64
+ "url": "https://github.com/ccch1mneyyy/working-activity/issues"
65
+ },
66
+ "homepage": "https://github.com/ccch1mneyyy/working-activity#readme",
67
+ "dsh": {
68
+ "bundle": {
69
+ "patch": "./cordis.patch.yml"
70
+ },
71
+ "client": {
72
+ "platform": "web",
73
+ "inject": [
74
+ "@deepseek-ai/dsh-client-runtime",
75
+ "@deepseek-ai/dsh-client-ui-conversation",
76
+ "@deepseek-ai/dsh-client-ui-slots"
77
+ ]
78
+ }
79
+ },
80
+ "peerDependencies": {
81
+ "@deepseek-ai/cordis": "^4.0.1",
82
+ "@deepseek-ai/dsh-agent": "^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-alpha.2",
83
+ "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
84
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
85
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
86
+ "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-alpha.2",
87
+ "@deepseek-ai/dsh-session": "^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-alpha.2",
88
+ "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6 || ^0.1.1-rc.1 || ^0.1.2-alpha.2",
89
+ "@deepseek-ai/schemastery": "^3.18.1",
90
+ "react": "^18.2.0"
91
+ },
92
+ "devDependencies": {
93
+ "@deepseek-ai/cordis": "^4.0.1",
94
+ "@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
95
+ "@deepseek-ai/dsh-agent-loop": "^0.1.0-rc.6",
96
+ "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.0-rc.6",
97
+ "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
98
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
99
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
100
+ "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
101
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
102
+ "@deepseek-ai/dsh-session": "^0.1.0-rc.6",
103
+ "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
104
+ "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
105
+ "@deepseek-ai/schemastery": "^3.18.1",
106
+ "@types/node": "^22.0.0",
107
+ "@types/react": "~18.3.1",
108
+ "lightningcss": "^1.32.0",
109
+ "react": "^18.2.0",
110
+ "tsdown": "^0.22.2",
111
+ "typescript": "^6.0.3",
112
+ "vitest": "^3.2.4"
113
+ },
114
+ "peerDependenciesMeta": {
115
+ "@deepseek-ai/dsh-client-runtime": {
116
+ "optional": true
117
+ },
118
+ "@deepseek-ai/dsh-client-ui-conversation": {
119
+ "optional": true
120
+ },
121
+ "@deepseek-ai/dsh-client-ui-slots": {
122
+ "optional": true
123
+ },
124
+ "react": {
125
+ "optional": true
126
+ }
127
+ }
128
+ }
package/src/status.ts CHANGED
@@ -662,13 +662,69 @@ const STREAM_BUFFER_CHARS = 300
662
662
  /** A narration stays visible this long after the stream went quiet. */
663
663
  const NARRATE_GRACE_MS = 5000
664
664
 
665
+ /** Narration budget in display columns: 40 CJK chars ≈ 12 English words. */
666
+ const NARRATION_MAX_COLUMNS = 80
667
+
668
+ /** A CJK/full-width code point renders 2 terminal columns; the rest render 1. */
669
+ function isWide(cp: number): boolean {
670
+ return (
671
+ (cp >= 0x1100 && cp <= 0x115f) || // Hangul Jamo
672
+ (cp >= 0x2e80 && cp <= 0xa4cf) || // CJK radicals, kana, Yi
673
+ (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul syllables
674
+ (cp >= 0xf900 && cp <= 0xfaff) || // CJK compatibility ideographs
675
+ (cp >= 0xfe30 && cp <= 0xfe4f) || // CJK compatibility forms
676
+ (cp >= 0xff00 && cp <= 0xff60) || // full-width forms
677
+ (cp >= 0xffe0 && cp <= 0xffe6) || // full-width signs
678
+ (cp >= 0x20000 && cp <= 0x3fffd) // CJK extensions
679
+ )
680
+ }
681
+
682
+ /** Cut before `max` columns, backing off to the last word or clause boundary. */
683
+ function cutToWidth(text: string, max: number): string {
684
+ let width = 0
685
+ let cut = text.length
686
+ const chars = [...text]
687
+ for (let i = 0; i < chars.length; i++) {
688
+ const w = isWide(chars[i]!.codePointAt(0)!) ? 2 : 1
689
+ if (width + w > max) {
690
+ cut = chars.slice(0, i).join('').length
691
+ break
692
+ }
693
+ width += w
694
+ }
695
+ if (cut === text.length) return text
696
+ // Back off to a soft boundary so English words survive intact; dense CJK has
697
+ // none and hard-cuts at the budget like the original fixed 40-char capture.
698
+ const head = text.slice(0, cut)
699
+ const soft = Math.max(
700
+ head.lastIndexOf(' '),
701
+ head.lastIndexOf('\t'),
702
+ head.lastIndexOf(','),
703
+ head.lastIndexOf('、'),
704
+ head.lastIndexOf(';'),
705
+ head.lastIndexOf(';'),
706
+ head.lastIndexOf(','),
707
+ )
708
+ return soft > 0 ? head.slice(0, soft) : head
709
+ }
710
+
665
711
  /** Extract the latest `⏵` self-narration line from a stream buffer. */
666
712
  export function extractNarration(buffer: string): string | null {
667
- const matches = [...buffer.matchAll(/⏵\s*([^\n⏵]{1,40})/g)]
668
- if (matches.length === 0) return null
669
- const latest = matches[matches.length - 1]?.[1]
670
- if (latest === undefined) return null
671
- const text = latest.replace(/[。..!!,,、;;]+$/, '').trim()
713
+ const matches = [...buffer.matchAll(/⏵[ \t]*([^\n⏵]*)/g)]
714
+ const latest = matches[matches.length - 1]?.[1]?.trim()
715
+ if (!latest) return null
716
+
717
+ // A missing newline must not turn the rest of the response into status text.
718
+ // Stop at sentence ends and clause delimiters, while leaving dotted
719
+ // identifiers such as `ink.tsx`, `agent.ctx` and `README.MD` intact. A dot
720
+ // ends a sentence only before whitespace, the end, or a Title-case word
721
+ // (`safely.The`); dot-uppercase-uppercase stays an extension (`.MD`).
722
+ const boundary = latest.search(/[。.!?!?;;]|\.(?=\s|$|[A-Z][a-z])/)
723
+ const sentence = boundary < 0 ? latest : latest.slice(0, boundary + 1)
724
+
725
+ // The budget is display width, so English and Chinese render equally long:
726
+ // 40 CJK characters and ~12 English words share the same line budget.
727
+ const text = cutToWidth(sentence, NARRATION_MAX_COLUMNS).replace(/[。..!!,,、;;]+$/, '').trim()
672
728
  return text.length === 0 ? null : text
673
729
  }
674
730