devez-vibe 1.5.20 → 1.5.22

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 CHANGED
@@ -1,33 +1,33 @@
1
- DevezCode source code license
2
-
3
- The MIT License below applies only to the DevezCode source code and to files
4
- that are not listed in the exception below.
5
-
6
- Exceptions:
7
-
8
- * `Resources/Images/FileTypes/` and `Resources/Licenses/` are Microsoft Visual
9
- Studio Image Library materials, subject to the included Microsoft terms.
10
- * `Resources/Images/ShellPresets/` contains third-party brand assets, subject
11
- to their respective owners' terms.
12
-
13
- MIT License
14
-
15
- Copyright (c) 2026 DevezCode contributors
16
-
17
- Permission is hereby granted, free of charge, to any person obtaining a copy
18
- of this software and associated documentation files (the "Software"), to deal
19
- in the Software without restriction, including without limitation the rights
20
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
- copies of the Software, and to permit persons to whom the Software is
22
- furnished to do so, subject to the following conditions:
23
-
24
- The above copyright notice and this permission notice shall be included in all
25
- copies or substantial portions of the Software.
26
-
27
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
- SOFTWARE.
1
+ DevezCode source code license
2
+
3
+ The MIT License below applies only to the DevezCode source code and to files
4
+ that are not listed in the exception below.
5
+
6
+ Exceptions:
7
+
8
+ * `Resources/Images/FileTypes/` and `Resources/Licenses/` are Microsoft Visual
9
+ Studio Image Library materials, subject to the included Microsoft terms.
10
+ * `Resources/Images/ShellPresets/` contains third-party brand assets, subject
11
+ to their respective owners' terms.
12
+
13
+ MIT License
14
+
15
+ Copyright (c) 2026 DevezCode contributors
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy
18
+ of this software and associated documentation files (the "Software"), to deal
19
+ in the Software without restriction, including without limitation the rights
20
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+ copies of the Software, and to permit persons to whom the Software is
22
+ furnished to do so, subject to the following conditions:
23
+
24
+ The above copyright notice and this permission notice shall be included in all
25
+ copies or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+ SOFTWARE.
package/bin/dvz.exe CHANGED
Binary file
@@ -1683,34 +1683,62 @@ function notificationTag(body, name) {
1683
1683
  return match?.[1]?.trim() || "";
1684
1684
  }
1685
1685
 
1686
+ // 완료 통지는 SDK 빌드에 따라 문자열·text 블록·다른 블록 형태로 올 수 있다.
1687
+ // 감지가 본문 구조에 좌우되면 백그라운드 서브에이전트가 영원히 남으므로, 잡을 수
1688
+ // 있는 모든 문자열을 한데 모은다.
1689
+ function messageAllText(message) {
1690
+ const content = message.message?.content;
1691
+ if (typeof content === "string") return content;
1692
+ if (!Array.isArray(content)) return "";
1693
+ const parts = [];
1694
+ for (const block of content) {
1695
+ if (typeof block === "string") parts.push(block);
1696
+ else if (typeof block?.text === "string") parts.push(block.text);
1697
+ else if (typeof block?.content === "string") parts.push(block.content);
1698
+ }
1699
+ return parts.join("\n");
1700
+ }
1701
+
1686
1702
  function taskNotifications(message) {
1687
- if (message.origin?.kind !== "task-notification"
1688
- && !messageTextParts(message).some((text) => text.includes("<task-notification>"))) {
1703
+ const raw = messageAllText(message);
1704
+ if (message.origin?.kind !== "task-notification" && !raw.includes("<task-notification>")) {
1689
1705
  return [];
1690
1706
  }
1691
1707
  const notifications = [];
1692
- for (const text of messageTextParts(message)) {
1693
- for (const match of text.matchAll(/<task-notification>([\s\S]*?)<\/task-notification>/g)) {
1694
- const body = match[1];
1695
- notifications.push({
1696
- taskId: notificationTag(body, "task-id"),
1697
- toolUseId: notificationTag(body, "tool-use-id"),
1698
- status: notificationTag(body, "status"),
1699
- summary: notificationTag(body, "summary"),
1700
- });
1701
- }
1708
+ for (const match of raw.matchAll(/<task-notification>([\s\S]*?)<\/task-notification>/g)) {
1709
+ const body = match[1];
1710
+ notifications.push({
1711
+ taskId: notificationTag(body, "task-id"),
1712
+ toolUseId: notificationTag(body, "tool-use-id"),
1713
+ status: notificationTag(body, "status"),
1714
+ summary: notificationTag(body, "summary"),
1715
+ });
1702
1716
  }
1703
1717
  return notifications;
1704
1718
  }
1705
1719
 
1720
+ // 통지 요약은 보통 `Agent "Explore" finished` 형태로 에이전트 이름을 따옴표로 담는다.
1721
+ function subagentNameFromSummary(summary) {
1722
+ return String(summary || "").match(/"([^"]+)"/)?.[1] || "";
1723
+ }
1724
+
1706
1725
  function finishNotifiedSubagents(session, notifications) {
1707
1726
  for (const notification of notifications) {
1708
1727
  const byToolUse = notification.toolUseId
1709
1728
  ? session.subagents.get(notification.toolUseId)
1710
1729
  : null;
1711
- const running = byToolUse || (notification.taskId
1730
+ let running = byToolUse || (notification.taskId
1712
1731
  ? [...session.subagents.values()].find((agent) => agent.taskId === notification.taskId)
1713
1732
  : null);
1733
+ // 전달 형태에 따라 id가 어긋날 수 있다. 그때는 요약이 지목한 이름의 백그라운드
1734
+ // 에이전트를 지워, 끝난 에이전트가 그래도 행에서 사라지게 한다.
1735
+ if (!running) {
1736
+ const name = subagentNameFromSummary(notification.summary);
1737
+ if (name) {
1738
+ running = [...session.subagents.values()]
1739
+ .find((agent) => agent.background && agent.name === name);
1740
+ }
1741
+ }
1714
1742
  if (!running) continue;
1715
1743
  emitSubagentLine(session, running.id, {
1716
1744
  kind: notification.status === "completed" ? "result" : "error",
@@ -2899,6 +2927,33 @@ async function runSelfTest() {
2899
2927
  || notification[0].summary !== 'Agent "Explore" finished') {
2900
2928
  throw new Error(`Claude task notification self-test failed: ${JSON.stringify(notification)}`);
2901
2929
  }
2930
+ // 통지가 문자열이 아닌 text 블록 배열로 와도 감지해야 한다.
2931
+ const blockNotification = taskNotifications({
2932
+ message: {
2933
+ content: [{
2934
+ type: "text",
2935
+ text: `[SYSTEM NOTIFICATION]\n<task-notification>\n<task-id>agent-9</task-id>\n<tool-use-id>toolu_9</tool-use-id>\n<status>completed</status>\n<summary>Agent "Explore" finished</summary>\n</task-notification>`,
2936
+ }],
2937
+ },
2938
+ });
2939
+ if (blockNotification.length !== 1 || blockNotification[0].taskId !== "agent-9") {
2940
+ throw new Error(`Claude block notification self-test failed: ${JSON.stringify(blockNotification)}`);
2941
+ }
2942
+ // id가 어긋나도 요약의 이름으로 백그라운드 서브에이전트를 정리해야 한다.
2943
+ const nameFallbackSession = {
2944
+ id: "name-fallback-session",
2945
+ turn: { id: "t", sawStreamText: false },
2946
+ subagents: new Map([[
2947
+ "toolu_live",
2948
+ { id: "toolu_live", taskId: "agent-live", background: true, name: "Explore", description: "", tool: "", startedAt: Date.now() },
2949
+ ]]),
2950
+ };
2951
+ finishNotifiedSubagents(nameFallbackSession, [{
2952
+ taskId: "mismatch", toolUseId: "mismatch", status: "completed", summary: 'Agent "Explore" finished',
2953
+ }]);
2954
+ if (nameFallbackSession.subagents.size !== 0) {
2955
+ throw new Error("Claude subagent name fallback self-test failed");
2956
+ }
2902
2957
  const lifecycleSession = {
2903
2958
  id: "self-test-session",
2904
2959
  turn: { id: "parent-turn", sawStreamText: false },
package/package.json CHANGED
@@ -1,41 +1,41 @@
1
- {
2
- "name": "devez-vibe",
3
- "version": "1.5.20",
4
- "description": "Stable terminal UI for Codex and Claude Agent SDK",
5
- "keywords": [
6
- "codex",
7
- "cli",
8
- "tui",
9
- "terminal",
10
- "app-server",
11
- "claude-agent-sdk"
12
- ],
13
- "homepage": "https://github.com/MrHoje/Devez-vibe#readme",
14
- "bugs": "https://github.com/MrHoje/Devez-vibe/issues",
15
- "repository": {
16
- "type": "git",
17
- "url": "git+https://github.com/MrHoje/Devez-vibe.git"
18
- },
19
- "license": "MIT",
20
- "bin": {
21
- "dvz": "bin/dvz.exe"
22
- },
23
- "files": [
24
- "bin/dvz.exe",
25
- "bridge/claude-agent-sdk-bridge.mjs",
26
- "README.md",
27
- "LICENSE"
28
- ],
29
- "os": [
30
- "win32"
31
- ],
32
- "cpu": [
33
- "x64"
34
- ],
35
- "engines": {
36
- "node": ">=18"
37
- },
38
- "dependencies": {
39
- "@anthropic-ai/claude-agent-sdk": "0.3.223"
40
- }
41
- }
1
+ {
2
+ "name": "devez-vibe",
3
+ "version": "1.5.22",
4
+ "description": "Stable terminal UI for Codex and Claude Agent SDK",
5
+ "keywords": [
6
+ "codex",
7
+ "cli",
8
+ "tui",
9
+ "terminal",
10
+ "app-server",
11
+ "claude-agent-sdk"
12
+ ],
13
+ "homepage": "https://github.com/MrHoje/Devez-vibe#readme",
14
+ "bugs": "https://github.com/MrHoje/Devez-vibe/issues",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/MrHoje/Devez-vibe.git"
18
+ },
19
+ "license": "MIT",
20
+ "bin": {
21
+ "dvz": "bin/dvz.exe"
22
+ },
23
+ "files": [
24
+ "bin/dvz.exe",
25
+ "bridge/claude-agent-sdk-bridge.mjs",
26
+ "README.md",
27
+ "LICENSE"
28
+ ],
29
+ "os": [
30
+ "win32"
31
+ ],
32
+ "cpu": [
33
+ "x64"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "dependencies": {
39
+ "@anthropic-ai/claude-agent-sdk": "0.3.231"
40
+ }
41
+ }