iterate-plugin 2.12.2 → 2.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -95,7 +95,8 @@ Besides 13 pure-function tools, it ships a **build-free Web UI layer** (triage p
95
95
 
96
96
  | UI component | Mounted slot | Function |
97
97
  | --- | --- | --- |
98
- | ConvergenceDashboard | `conversation.input.dock` | Live round progress bar, severity stats, dimension badges, trend mini-chart above the input; normal mode also shows fix-count badges |
98
+ | ConvergenceDashboard | `conversation.input.dock` | Live round progress bar, severity stats, dimension badges, trend mini-chart above the input; normal mode also shows fix-count badges; plus a live workflow-phase chip (current phase + running/stopped) |
99
+ | ObservatoryPanel | `conversation.input.dock` | Seven-tab runtime observatory below the input: live activity stream (type filter), review threads (expand/collapse all), convergence trend, finding locations (severity/dimension/search filter), fixes + rollback, checkpoint resume, decision timeline (type/round filter + search); one-click export of all observatory data to JSON (download, copy fallback) |
99
100
  | TriagePanel | `conversation.chat.turnTail` | Per-finding y/n/a triage, filtering, batch (incl. select-all), keyboard shortcuts, localStorage persistence, copy-YAML / apply-instruction |
100
101
  | StatsCard | `conversation.chat.turnTail` | When no findings remain: convergence stats, round history table, trend chart, completion summary |
101
102
  | iterate theme skin | `theme.overrideTokens` | Warm-amber 13-dsw-token override, light/dark modes, togglable in settings |
package/README.zh-CN.md CHANGED
@@ -95,7 +95,8 @@ dsh plugin --profile web add iterate-plugin
95
95
 
96
96
  | UI 组件 | 挂载槽位 | 功能 |
97
97
  |---------|---------|------|
98
- | 收敛看板 `ConvergenceDashboard` | `conversation.input.dock` | 输入框上方实时显示轮次进度条、严重度统计、维度徽章、趋势迷你图,normal 模式另显示修复计数徽章 |
98
+ | 收敛看板 `ConvergenceDashboard` | `conversation.input.dock` | 输入框上方实时显示轮次进度条、严重度统计、维度徽章、趋势迷你图,normal 模式另显示修复计数徽章;并显示运行阶段芯片(当前工作流阶段 + 运行中/已结束) |
99
+ | 运行时观测台 `ObservatoryPanel` | `conversation.input.dock` | 输入框下方七个标签页:实时活动流(支持按活动类型筛选)、审查线程(支持全部展开/全部收起)、收敛趋势、发现定位(支持按严重度/维度/关键词筛选)、修复与回滚、断点恢复、决策时间线(支持按类型/轮次筛选与关键词搜索);支持一键导出全部观测数据为 JSON(优先下载,失败回退复制) |
99
100
  | Findings 分诊面板 `TriagePanel` | `conversation.chat.turnTail` | 逐条 y/n/a 判定,支持筛选、批量(含一键全选所有 findings)、键盘快捷键、localStorage 持久化、复制 YAML/应用指令 |
100
101
  | 收敛统计卡片 `StatsCard` | `conversation.chat.turnTail` | 无 findings 时显示收敛统计、历史轮次表、趋势图、完成摘要 |
101
102
  | iterate 主题皮肤 | `theme.overrideTokens` | 暖琥珀配色的 13 个 dsw token 覆盖,明暗双模式,可在设置页开关 |
package/dist/git-scope.js CHANGED
@@ -29,6 +29,64 @@ import { join } from 'node:path';
29
29
  * NUL is present (callers that did not pass -z) fall back to newline-split
30
30
  * with C-style quote/escape unescaping for core.quotePath output.
31
31
  */
32
+ /**
33
+ * Decode the quoted body of a git core.quotePath output line into the real
34
+ * filename bytes, then interpret them as UTF-8.
35
+ *
36
+ * Single-pass and escape-atomic: each `\` consumes exactly one escape (\" \\
37
+ * \t \n or a 3-digit octal for a raw byte), so a literal `\\303` in a filename
38
+ * (escaped backslash + literal "303") is decoded as the byte `\` followed by
39
+ * ASCII "303" rather than as the single byte 0xC3. Ordinary characters in the
40
+ * quoted body are ASCII (git always octal-escapes non-ASCII bytes), so they map
41
+ * 1:1 to bytes.
42
+ */
43
+ function decodeQuotedPath(content) {
44
+ const bytes = [];
45
+ let i = 0;
46
+ while (i < content.length) {
47
+ const ch = content[i];
48
+ if (ch !== '\\') {
49
+ bytes.push(ch.charCodeAt(0));
50
+ i++;
51
+ continue;
52
+ }
53
+ const next = content[i + 1];
54
+ if (next === '"') {
55
+ bytes.push(0x22);
56
+ i += 2;
57
+ }
58
+ else if (next === '\\') {
59
+ bytes.push(0x5c);
60
+ i += 2;
61
+ }
62
+ else if (next === 't') {
63
+ bytes.push(0x09);
64
+ i += 2;
65
+ }
66
+ else if (next === 'n') {
67
+ bytes.push(0x0a);
68
+ i += 2;
69
+ }
70
+ else if (next !== undefined && next >= '0' && next <= '7') {
71
+ const oct = content.slice(i + 1, i + 4);
72
+ if (oct.length === 3 && /^[0-7]{3}$/.test(oct)) {
73
+ bytes.push(parseInt(oct, 8));
74
+ i += 4;
75
+ }
76
+ else {
77
+ // Malformed octal — keep the backslash literally.
78
+ bytes.push(0x5c);
79
+ i++;
80
+ }
81
+ }
82
+ else {
83
+ // Unknown escape — keep the backslash literally.
84
+ bytes.push(0x5c);
85
+ i++;
86
+ }
87
+ }
88
+ return Buffer.from(bytes).toString('utf-8');
89
+ }
32
90
  export function parseChangedFiles(stdout) {
33
91
  if (stdout.includes('\0')) {
34
92
  return stdout.split('\0').map((s) => s.trim()).filter((s) => s.length > 0);
@@ -38,16 +96,12 @@ export function parseChangedFiles(stdout) {
38
96
  .map((line) => {
39
97
  const trimmed = line.trim();
40
98
  // git core.quotePath wraps paths with special characters in "..."; the
41
- // content uses C-style escapes (\" \\ \t \n and \ooo octal for non-ASCII).
99
+ // content uses C-style escapes (\" \\ \t \n) and \ooo octal escapes for
100
+ // non-ASCII bytes (which are raw UTF-8 BYTES, not Latin-1 code points).
42
101
  const quoted = trimmed.match(/^"(.*)"$/);
43
102
  if (!quoted)
44
103
  return trimmed;
45
- return quoted[1]
46
- .replace(/\\"/g, '"')
47
- .replace(/\\\\/g, '\\')
48
- .replace(/\\t/g, '\t')
49
- .replace(/\\n/g, '\n')
50
- .replace(/\\([0-7]{3})/g, (_m, oct) => String.fromCharCode(parseInt(oct, 8)));
104
+ return decodeQuotedPath(quoted[1]);
51
105
  })
52
106
  .filter((line) => line.length > 0);
53
107
  }