@x-otto/cli 0.0.1-alpha.49 → 0.0.1-alpha.50

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.
Files changed (119) hide show
  1. package/dist/{auth-command-D1T16ed-.js → auth-command-BYaFM76w.js} +2 -2
  2. package/dist/{auth-command-D1T16ed-.js.map → auth-command-BYaFM76w.js.map} +1 -1
  3. package/dist/backend-handler-DUafuNWw.js +3 -0
  4. package/dist/backend-handler-DUafuNWw.js.map +1 -0
  5. package/dist/build-id-DjE6eVpQ.js +3 -0
  6. package/dist/build-id-DjE6eVpQ.js.map +1 -0
  7. package/dist/bundled-extensions/plugin-feedback/otto-plugin.json +24 -0
  8. package/dist/bundled-extensions/plugin-feedback/panels/feedback.tsx +348 -0
  9. package/dist/bundled-extensions/plugin-feedback/panels/panel-host-globals.d.ts +67 -0
  10. package/dist/bundled-extensions/plugin-feedback/panels-dist/feedback.mjs +257 -0
  11. package/dist/bundled-extensions/plugin-feedback/plugin-dist/meta.json +1 -0
  12. package/dist/bundled-extensions/plugin-feedback/plugin-dist/plugin.cjs +11304 -0
  13. package/dist/bundled-extensions/plugin-feedback/plugin.ts +198 -0
  14. package/dist/bundled-extensions/plugin-feedback/src/coding-adapter.ts +183 -0
  15. package/dist/bundled-extensions/plugin-feedback/src/coding-lister.ts +26 -0
  16. package/dist/bundled-extensions/plugin-feedback/src/github-lister.ts +230 -0
  17. package/dist/bundled-extensions/plugin-feedback/src/issue-aggregator.ts +109 -0
  18. package/dist/bundled-extensions/plugin-feedback/src/issue-submitter.ts +241 -0
  19. package/dist/bundled-extensions/plugin-feedback/src/platform-resolver.ts +76 -0
  20. package/dist/bundled-extensions/plugin-feedback/src/pulse-survey-sink.ts +114 -0
  21. package/dist/bundled-extensions/plugin-feedback/src/resolved-sink.ts +163 -0
  22. package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/meta.json +1 -1
  23. package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/plugin.cjs +605 -725
  24. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/anthropic-messages.ts +4 -22
  25. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-completions.ts +5 -5
  26. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-responses.ts +3 -15
  27. package/dist/command-dispatcher-BLT8IO4K.js +18 -0
  28. package/dist/command-dispatcher-BLT8IO4K.js.map +1 -0
  29. package/dist/create-host-app-CbJ8ptv-.js +3 -0
  30. package/dist/{create-host-app-BXQ8bU-B.js.map → create-host-app-CbJ8ptv-.js.map} +1 -1
  31. package/dist/{daemon-base-Y1XI61JY.js → daemon-base-D015ew5y.js} +1 -1
  32. package/dist/{daemon-base-Y1XI61JY.js.map → daemon-base-D015ew5y.js.map} +1 -1
  33. package/dist/{doctor-DXBLkbkP.js → doctor-EndB-ycb.js} +3 -3
  34. package/dist/{doctor-DXBLkbkP.js.map → doctor-EndB-ycb.js.map} +1 -1
  35. package/dist/{doctor-attach-DEMuyBOk.js → doctor-attach-DEoE7eFx.js} +2 -2
  36. package/dist/{doctor-attach-DEMuyBOk.js.map → doctor-attach-DEoE7eFx.js.map} +1 -1
  37. package/dist/{doctor-cdp-CnJUVNOB.js → doctor-cdp-Cj9IFpEP.js} +1 -1
  38. package/dist/{doctor-cdp-CnJUVNOB.js.map → doctor-cdp-Cj9IFpEP.js.map} +1 -1
  39. package/dist/{doctor-heap-Eu3LZj-F.js → doctor-heap-SIxiRvL8.js} +2 -2
  40. package/dist/{doctor-heap-Eu3LZj-F.js.map → doctor-heap-SIxiRvL8.js.map} +1 -1
  41. package/dist/{doctor-ps-JBgCH77n.js → doctor-ps-DNVOF6yY.js} +2 -2
  42. package/dist/{doctor-ps-JBgCH77n.js.map → doctor-ps-DNVOF6yY.js.map} +1 -1
  43. package/dist/extension-CoJqqktf.js +2 -0
  44. package/dist/extension-Dpn8gltG.js +179 -0
  45. package/dist/extension-Dpn8gltG.js.map +1 -0
  46. package/dist/feedback-QcONRnO3.js +30 -0
  47. package/dist/feedback-QcONRnO3.js.map +1 -0
  48. package/dist/feedback-backend-methods-BNm38ddr.js +3 -0
  49. package/dist/feedback-backend-methods-BNm38ddr.js.map +1 -0
  50. package/dist/{feishu-setup-5ZoxtH0J.js → feishu-setup-DbAq_BRH.js} +1 -1
  51. package/dist/feishu-setup-DbAq_BRH.js.map +1 -0
  52. package/dist/{ftue-doctor-recovery-8FeDBFOc.js → ftue-doctor-recovery-CKTMnxM8.js} +1 -1
  53. package/dist/{ftue-doctor-recovery-8FeDBFOc.js.map → ftue-doctor-recovery-CKTMnxM8.js.map} +1 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +11 -11
  56. package/dist/index.js.map +1 -1
  57. package/dist/install-CEPczuet.js +11 -0
  58. package/dist/install-CEPczuet.js.map +1 -0
  59. package/dist/install-CG6b6fox.js +2 -0
  60. package/dist/interactive-schedule-Bv__2Kwc.js +3 -0
  61. package/dist/interactive-schedule-Bv__2Kwc.js.map +1 -0
  62. package/dist/{mcp-Cm4-OhXI.js → mcp-DjReRjuu.js} +1 -1
  63. package/dist/{mcp-Cm4-OhXI.js.map → mcp-DjReRjuu.js.map} +1 -1
  64. package/dist/{mcp-server-Dpza3yn2.js → mcp-server-Rr__aWO7.js} +3 -3
  65. package/dist/mcp-server-Rr__aWO7.js.map +1 -0
  66. package/dist/{migrate-RlBJqJnB.js → migrate-BBi3Txu2.js} +1 -1
  67. package/dist/{migrate-RlBJqJnB.js.map → migrate-BBi3Txu2.js.map} +1 -1
  68. package/dist/{observe-Dxfud-t7.js → observe-BqLCpmFD.js} +2 -2
  69. package/dist/{observe-Dxfud-t7.js.map → observe-BqLCpmFD.js.map} +1 -1
  70. package/dist/parse-cli-Db8pF_Ya.js +3 -0
  71. package/dist/parse-cli-Db8pF_Ya.js.map +1 -0
  72. package/dist/{persistence-CRFhOYx6.js → persistence-BvLRnpfi.js} +2 -2
  73. package/dist/{persistence-CRFhOYx6.js.map → persistence-BvLRnpfi.js.map} +1 -1
  74. package/dist/{plugin-assembly-check-DEozmcJ7.js → plugin-assembly-check-BntT5W6H.js} +1 -1
  75. package/dist/{plugin-assembly-check-DEozmcJ7.js.map → plugin-assembly-check-BntT5W6H.js.map} +1 -1
  76. package/dist/{proxy-evg7ZvoD.js → proxy-CFZDVIwI.js} +1 -1
  77. package/dist/proxy-CFZDVIwI.js.map +1 -0
  78. package/dist/proxy-CkSf8ziQ.js +2 -0
  79. package/dist/{ps-DiKCLKbs.js → ps-BVKv6rAo.js} +1 -1
  80. package/dist/{ps-DiKCLKbs.js.map → ps-BVKv6rAo.js.map} +1 -1
  81. package/dist/{registry-BdCcwyGy.js → registry-BUvu-es1.js} +4 -4
  82. package/dist/registry-BUvu-es1.js.map +1 -0
  83. package/dist/registry-DYHR-ONu.js +2 -0
  84. package/dist/{run-attach-DDpMk2_N.js → run-attach-X35puJ_n.js} +2 -2
  85. package/dist/{run-attach-DDpMk2_N.js.map → run-attach-X35puJ_n.js.map} +1 -1
  86. package/dist/schedule-Ke0jwatM.js +5 -0
  87. package/dist/schedule-Ke0jwatM.js.map +1 -0
  88. package/dist/serve-K6BOT5K_.js +21 -0
  89. package/dist/serve-K6BOT5K_.js.map +1 -0
  90. package/dist/{service-client-Cr4sxDVM.js → service-client-cfUUP4EE.js} +1 -1
  91. package/dist/{service-client-Cr4sxDVM.js.map → service-client-cfUUP4EE.js.map} +1 -1
  92. package/dist/{version-BrSIyY6s.js → version-DrCy32wR.js} +2 -2
  93. package/dist/{version-BrSIyY6s.js.map → version-DrCy32wR.js.map} +1 -1
  94. package/package.json +16 -13
  95. package/dist/build-id-DxfuzdUE.js +0 -3
  96. package/dist/build-id-DxfuzdUE.js.map +0 -1
  97. package/dist/command-dispatcher-DTOPjtZP.js +0 -21
  98. package/dist/command-dispatcher-DTOPjtZP.js.map +0 -1
  99. package/dist/create-host-app-BXQ8bU-B.js +0 -3
  100. package/dist/create-host-app-DG58-vRA.js +0 -2
  101. package/dist/extension-CTyrcdT1.js +0 -2
  102. package/dist/extension-DVEml5IN.js +0 -179
  103. package/dist/extension-DVEml5IN.js.map +0 -1
  104. package/dist/feedback-DvWUvSc4.js +0 -21
  105. package/dist/feedback-DvWUvSc4.js.map +0 -1
  106. package/dist/feedback-DzPLfcfN.js +0 -2
  107. package/dist/feishu-setup-5ZoxtH0J.js.map +0 -1
  108. package/dist/install-DlVJRHRT.js +0 -11
  109. package/dist/install-DlVJRHRT.js.map +0 -1
  110. package/dist/install-WCcQ9k9M.js +0 -2
  111. package/dist/mcp-server-Dpza3yn2.js.map +0 -1
  112. package/dist/parse-cli-BvcxTK88.js +0 -3
  113. package/dist/parse-cli-BvcxTK88.js.map +0 -1
  114. package/dist/proxy-BvdBsB1O.js +0 -2
  115. package/dist/proxy-evg7ZvoD.js.map +0 -1
  116. package/dist/registry-BOX7DaxS.js +0 -2
  117. package/dist/registry-BdCcwyGy.js.map +0 -1
  118. package/dist/serve-Ke0nwN9Y.js +0 -21
  119. package/dist/serve-Ke0nwN9Y.js.map +0 -1
@@ -0,0 +1,163 @@
1
+ /**
2
+ * resolved-sink.ts — RFC-430 §2.4:「本地标记已解决」JSONL 落地层。
3
+ *
4
+ * 复刻 pulse-survey-sink.ts 的既有纪律(appendFileSync + 5MB 截断保留最后 50% +
5
+ * fail-soft 全局吞错 + RFC-345 shadow 模式零写盘)——两处独立各自实现一份而非
6
+ * 抽取共享 helper(同 pulse-survey-sink 头注释的既有判断:各自的 fail-soft 边界
7
+ * 不完全相同,重复优于错误的抽象)。
8
+ *
9
+ * 落盘位置:`~/.otto/feedback/resolved.jsonl`(pulse-surveys.jsonl 平级的独立子目录,
10
+ * 为 M2+ 反馈面板其他本地态预留目录位)。
11
+ *
12
+ * **仅本地标记**——真实关闭请在平台侧操作(面板 UI 明示同一文案,RFC-430 §3)。
13
+ */
14
+ import { existsSync, mkdirSync, appendFileSync, statSync, readFileSync, writeFileSync, renameSync } from 'node:fs'
15
+ import { resolve } from 'node:path'
16
+ import { randomUUID } from 'node:crypto'
17
+
18
+ import { OTTO_HOME, isShadowModeEnabled } from '@x-otto/env'
19
+
20
+ import type { FeedbackResolvedMark, FeedbackSource } from '@x-otto/plugin'
21
+ import type { FeedbackLoggerPort } from './pulse-survey-sink'
22
+
23
+ const noopLogger: FeedbackLoggerPort = { warn: () => {} }
24
+
25
+ /** 单文件大小上限(5MB,同 pulse-survey-sink/plugin-log-writer 既有惯例)。 */
26
+ const MAX_LOG_FILE_BYTES = 5 * 1024 * 1024
27
+
28
+ /** 标记文件路径(`resolve` 而非 `join`,对齐 pulse-survey-sink 的既有惯例)。 */
29
+ export function resolvedMarksPath(): string {
30
+ return resolve(OTTO_HOME, 'feedback', 'resolved.jsonl')
31
+ }
32
+
33
+ /** 单文件超限时截断保留最后 50%(有损策略,同 pulse-survey-sink truncateIfOversized)。 */
34
+ function truncateIfOversized(path: string, logger: FeedbackLoggerPort): void {
35
+ let size: number
36
+ try {
37
+ size = statSync(path).size
38
+ } catch {
39
+ return // 文件不存在,无需截断
40
+ }
41
+ if (size <= MAX_LOG_FILE_BYTES) return
42
+
43
+ try {
44
+ const content = readFileSync(path, 'utf8')
45
+ const keepFrom = Math.floor(content.length / 2)
46
+ // 从字符中点找下一个换行符,避免截断到半行 JSON。
47
+ const nl = content.indexOf('\n', keepFrom)
48
+ const truncated = nl >= 0 ? content.slice(nl + 1) : content.slice(keepFrom)
49
+ writeFileSync(path, truncated)
50
+ } catch (error) {
51
+ // fail-soft:截断失败不影响后续写入尝试(append 会继续追加到超限文件,下次再试截断)。
52
+ logger.warn(`resolved marks truncation failed (fail-soft): path=${path} err=${String(error)}`)
53
+ }
54
+ }
55
+
56
+ /**
57
+ * 读全部行(容错:坏行跳过;文件不存在/读取失败 → 空数组)。
58
+ *
59
+ * `_logger` 有意未使用:本函数的三条失败路径(文件不存在/读取失败、单行 JSON 解析
60
+ * 失败、形状不符的脏条目)按设计**全部静默跳过**——读路径的坏数据不该刷屏(写路径才
61
+ * 记 warn,见 appendResolvedMark/truncate)。参数保留是为与同模块写函数签名一致,
62
+ * 且三个调用点已传 `this.logger`,删参会破坏调用方。
63
+ */
64
+ export function readResolvedMarks(_logger: FeedbackLoggerPort = noopLogger): FeedbackResolvedMark[] {
65
+ // RFC-345:影子态零读取语义对齐零写盘——面板在影子态下视为「无本地标记」。
66
+ if (isShadowModeEnabled()) return []
67
+ const path = resolvedMarksPath()
68
+ let content: string
69
+ try {
70
+ content = readFileSync(path, 'utf8')
71
+ } catch {
72
+ return []
73
+ }
74
+ const marks: FeedbackResolvedMark[] = []
75
+ for (const line of content.split('\n')) {
76
+ if (!line.trim()) continue
77
+ try {
78
+ const raw = JSON.parse(line) as Partial<FeedbackResolvedMark>
79
+ if (
80
+ typeof raw.ts === 'number' &&
81
+ (raw.source === 'github' || raw.source === 'coding') &&
82
+ typeof raw.platformIssueId === 'string' &&
83
+ typeof raw.url === 'string' &&
84
+ typeof raw.title === 'string'
85
+ ) {
86
+ marks.push({
87
+ ts: raw.ts,
88
+ source: raw.source,
89
+ platformIssueId: raw.platformIssueId,
90
+ url: raw.url,
91
+ title: raw.title,
92
+ })
93
+ }
94
+ // 形状不符的坏行静默跳过(容错解析,同 github-lister 的脏条目纪律)。
95
+ } catch {
96
+ // 单行 JSON 解析失败静默跳过。
97
+ }
98
+ }
99
+ return marks
100
+ }
101
+
102
+ /**
103
+ * 本地标记 sink(RFC-430 §2.4 数据面)。
104
+ * fail-soft:所有写路径异常内部吞掉仅 warn;影子态 mark/unmark 返回 false 零写盘。
105
+ */
106
+ export class LocalJsonlResolvedMarksSink {
107
+ constructor(private readonly logger: FeedbackLoggerPort = noopLogger) {}
108
+
109
+ /** 追加一条标记;重复标记(同 source+platformIssueId)幂等返回 true(不重写)。 */
110
+ mark(mark: Omit<FeedbackResolvedMark, 'ts'>): boolean {
111
+ if (isShadowModeEnabled()) return false
112
+ try {
113
+ // 幂等去重:面板可能重复触发标记动作。
114
+ const existing = readResolvedMarks(this.logger)
115
+ if (existing.some((m) => m.source === mark.source && m.platformIssueId === mark.platformIssueId)) {
116
+ return true
117
+ }
118
+ const path = resolvedMarksPath()
119
+ const dir = resolve(OTTO_HOME, 'feedback')
120
+ if (!existsSync(dir)) {
121
+ mkdirSync(dir, { recursive: true })
122
+ }
123
+ truncateIfOversized(path, this.logger)
124
+ const entry: FeedbackResolvedMark = { ts: Date.now(), ...mark }
125
+ appendFileSync(path, `${JSON.stringify(entry)}\n`)
126
+ return true
127
+ } catch (error) {
128
+ this.logger.warn(`resolved mark append failed (fail-soft): ${String(error)}`)
129
+ return false
130
+ }
131
+ }
132
+
133
+ /**
134
+ * 剔除匹配行(原子重写:写临时文件 + rename 覆盖,避免半写状态);
135
+ * 无匹配行/影子态/写失败返回 false。
136
+ */
137
+ unmark(source: FeedbackSource, platformIssueId: string): boolean {
138
+ if (isShadowModeEnabled()) return false
139
+ try {
140
+ const path = resolvedMarksPath()
141
+ const existing = readResolvedMarks(this.logger)
142
+ const kept = existing.filter((m) => !(m.source === source && m.platformIssueId === platformIssueId))
143
+ if (kept.length === existing.length) return false // 无匹配行
144
+ const tmpPath = `${path}.${randomUUID()}.tmp`
145
+ writeFileSync(tmpPath, kept.map((m) => `${JSON.stringify(m)}\n`).join(''))
146
+ renameSync(tmpPath, path) // POSIX rename 原子替换
147
+ return true
148
+ } catch (error) {
149
+ this.logger.warn(`resolved mark unmark failed (fail-soft): ${String(error)}`)
150
+ return false
151
+ }
152
+ }
153
+
154
+ /** 读取全部标记(fail-soft:任何失败返回空数组)。 */
155
+ list(): FeedbackResolvedMark[] {
156
+ try {
157
+ return readResolvedMarks(this.logger)
158
+ } catch (error) {
159
+ this.logger.warn(`resolved marks list failed (fail-soft): ${String(error)}`)
160
+ return []
161
+ }
162
+ }
163
+ }
@@ -1 +1 @@
1
- {"apiVersion":1,"compilerVersion":"0.1.0-alpha.6","sourceHash":"28b4f7c10707642654e4b86f54be95e11a6544869c1be666c36bf9beb7b40133"}
1
+ {"apiVersion":1,"compilerVersion":"0.1.0-alpha.6","sourceHash":"ac6abc4d8fbfb920396f454bdbca52424de691d8787743bf4ef84c3c4fac0cfc"}