deskbuddy 0.2.0-beta.13 → 0.2.0-beta.14

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 (46) hide show
  1. package/dist/cli.js +2241 -359
  2. package/dist/gate.cjs +21 -13
  3. package/dist/hook.cjs +287 -9
  4. package/dist/ocTranslate.mjs +106 -0
  5. package/dist/opencode.mjs +100 -69
  6. package/hook/gate.cjs +21 -13
  7. package/hook/hook-debug.log +5 -0
  8. package/hook/hook.cjs +287 -9
  9. package/hook/ocTranslate.d.mts +7 -0
  10. package/hook/ocTranslate.mjs +106 -0
  11. package/hook/opencode.d.mts +4 -1
  12. package/hook/opencode.mjs +100 -69
  13. package/package.json +3 -2
  14. package/vendor/node-pty/LICENSE +69 -0
  15. package/vendor/node-pty/lib/conpty_console_list_agent.js +16 -0
  16. package/vendor/node-pty/lib/eventEmitter2.js +47 -0
  17. package/vendor/node-pty/lib/index.js +52 -0
  18. package/vendor/node-pty/lib/interfaces.js +7 -0
  19. package/vendor/node-pty/lib/shared/conout.js +11 -0
  20. package/vendor/node-pty/lib/terminal.js +190 -0
  21. package/vendor/node-pty/lib/types.js +7 -0
  22. package/vendor/node-pty/lib/unixTerminal.js +346 -0
  23. package/vendor/node-pty/lib/utils.js +39 -0
  24. package/vendor/node-pty/lib/windowsConoutConnection.js +125 -0
  25. package/vendor/node-pty/lib/windowsPtyAgent.js +320 -0
  26. package/vendor/node-pty/lib/windowsTerminal.js +199 -0
  27. package/vendor/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  28. package/vendor/node-pty/package.json +7 -0
  29. package/vendor/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  30. package/vendor/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  31. package/vendor/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  32. package/vendor/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  33. package/vendor/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  34. package/vendor/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  35. package/vendor/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  36. package/vendor/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  37. package/vendor/node-pty/prebuilds/win32-arm64/pty.node +0 -0
  38. package/vendor/node-pty/prebuilds/win32-arm64/winpty-agent.exe +0 -0
  39. package/vendor/node-pty/prebuilds/win32-arm64/winpty.dll +0 -0
  40. package/vendor/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  41. package/vendor/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  42. package/vendor/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  43. package/vendor/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  44. package/vendor/node-pty/prebuilds/win32-x64/pty.node +0 -0
  45. package/vendor/node-pty/prebuilds/win32-x64/winpty-agent.exe +0 -0
  46. package/vendor/node-pty/prebuilds/win32-x64/winpty.dll +0 -0
@@ -0,0 +1,106 @@
1
+ // opencode 系事件 → cc-hook 同构输入的翻译(spec 2026-10-03 §3.2「共用翻译」)。
2
+ // opencode 插件(opencode.mjs,跑在 opencode 自带的 bun 里)与 daemon 的 DumateWatch(百度搭子 = 改名的 opencode)共用这一份:
3
+ // 插件 import 同目录的本文件(随 hook.cjs 一起同步到 ~/.deskbuddy/),daemon 经 src/core/ocTranslate.ts 打包进去。
4
+ // 🔴 零依赖纯函数:不能 import 任何东西(插件那边同目录只有我们自己的文件)
5
+
6
+ /** opencode 工具 → cc-hook 同构的 tool_name / tool_input(daemon 的 classify 按 Claude Code 的工具名判断) */
7
+ export function toCcTool(tool, args) {
8
+ const a = args && typeof args === 'object' ? args : {}
9
+ const s = (v) => (typeof v === 'string' ? v : '')
10
+ switch (tool) {
11
+ case 'bash':
12
+ return { tool_name: 'Bash', tool_input: { command: s(a.command) } }
13
+ case 'read':
14
+ return { tool_name: 'Read', tool_input: { file_path: s(a.filePath) } }
15
+ case 'edit':
16
+ return { tool_name: 'Edit', tool_input: { file_path: s(a.filePath) } }
17
+ case 'write':
18
+ return { tool_name: 'Write', tool_input: { file_path: s(a.filePath) } }
19
+ case 'glob':
20
+ return { tool_name: 'Glob', tool_input: { pattern: s(a.pattern), path: s(a.path) } }
21
+ case 'grep':
22
+ return { tool_name: 'Grep', tool_input: { pattern: s(a.pattern), path: s(a.path) } }
23
+ case 'list':
24
+ return { tool_name: 'LS', tool_input: { path: s(a.path) } }
25
+ case 'webfetch':
26
+ return { tool_name: 'WebFetch', tool_input: { url: s(a.url) } }
27
+ case 'task':
28
+ return { tool_name: 'Task', tool_input: {} }
29
+ case 'todowrite':
30
+ case 'todoread':
31
+ return { tool_name: 'TodoWrite', tool_input: {} }
32
+ case 'patch':
33
+ case 'apply_patch':
34
+ return { tool_name: 'apply_patch', tool_input: { patch: s(a.patchText) || s(a.patch) || s(a.input) } }
35
+ default:
36
+ // 不认识的工具(MCP 等)原名原参数交出去:classify 对不认识的一律推设备
37
+ return { tool_name: String(tool || ''), tool_input: a }
38
+ }
39
+ }
40
+
41
+ /** permission.asked → PermissionRequest 的 tool_name / tool_input,给设备卡片生成摘要 */
42
+ export function askToCc(props) {
43
+ const md = (props && props.metadata) || {}
44
+ if (typeof md.command === 'string' && md.command) return { tool_name: 'Bash', tool_input: { command: md.command } }
45
+ const file = md.filepath || md.filePath
46
+ if (typeof file === 'string' && file) return { tool_name: 'Edit', tool_input: { file_path: file } }
47
+ const patterns = Array.isArray(props && props.patterns) ? props.patterns.join(' ') : ''
48
+ return { tool_name: String((props && props.permission) || 'permission'), tool_input: { path: patterns } }
49
+ }
50
+
51
+ /**
52
+ * 授权请求里 opencode 自己给的「以后都允许」模式(permission.asked 的 always,如 bash 的 `npm *`、edit 的 `*`)
53
+ * → 一条 session 级 addRules 建议(与 Claude Code 的 permission_suggestions 同形),daemon 据此在设备上给「允许并记住」。
54
+ * 设备选了记住,gate 输出带 updatedPermissions,插件回 always(opencode 在本次运行期间记住这些模式)。没有 always 返回 undefined
55
+ */
56
+ export function alwaysSuggestions(props) {
57
+ const perm = String((props && props.permission) || '').trim()
58
+ const always = props && Array.isArray(props.always) ? props.always.filter((x) => typeof x === 'string' && x.trim() !== '') : []
59
+ if (!perm || always.length === 0) return undefined
60
+ return [{ type: 'addRules', rules: always.map((x) => ({ toolName: perm, ruleContent: `${perm} ${x.trim()}` })), behavior: 'allow', destination: 'session' }]
61
+ }
62
+
63
+ /**
64
+ * 这次提问来自哪个工具:question.asked 只带 tool.callID,工具名要从 tool.execute.before 记下的调用里查。
65
+ * 🔴 只推 question 工具本身的提问:plan_exit 也走 question.asked(「计划完成,是否切到 build」Yes/No),
66
+ * 推到设备 = 盲批计划,违背 ExitPlanMode 不推的原则(设备答选择题 spec §3.7)。认不出来源的一律不推
67
+ */
68
+ export function isPlainQuestion(props, callTool) {
69
+ if (callTool !== 'question') return false
70
+ const qs = props && Array.isArray(props.questions) ? props.questions : []
71
+ // 兜底:plan_exit 的固定题面 / header
72
+ return !qs.some((q) => q && (q.header === 'Build Agent' || (typeof q.question === 'string' && /^Plan at .* is complete\./.test(q.question))))
73
+ }
74
+
75
+ /**
76
+ * question.asked(opencode 的 question 工具 / plan_exit 等向用户提问)→ AskUserQuestion 形状的 tool_input,
77
+ * 统一走 daemon 的选择题链路(设备答选择题 spec §3.4)。`multiple` → multiSelect;`custom:false` 原样带上(不许自己填)
78
+ */
79
+ export function questionToCc(props) {
80
+ const qs = props && Array.isArray(props.questions) ? props.questions : null
81
+ if (!qs || qs.length === 0) return null
82
+ return {
83
+ tool_name: 'AskUserQuestion',
84
+ tool_input: {
85
+ questions: qs.map((q) => ({
86
+ question: q && q.question,
87
+ header: (q && q.header) || '',
88
+ multiSelect: !!(q && q.multiple),
89
+ options: q && Array.isArray(q.options) ? q.options.map((o) => ({ label: o && o.label, description: (o && o.description) || '' })) : [],
90
+ ...(q && q.custom === false ? { custom: false } : {}),
91
+ })),
92
+ },
93
+ }
94
+ }
95
+
96
+ /** opencode 起标题前的占位名(1.18.32 isDefaultTitle:`New session - ` / `Child session - ` + ISO 时间),不当标题 */
97
+ const OC_DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/
98
+
99
+ /** session.updated 的 info → 记下自动标题。子会话(subagent,带 parentID)、占位名不记 */
100
+ export function rememberTitle(titles, info) {
101
+ if (!info || typeof info.id !== 'string' || !info.id || info.parentID) return
102
+ const t = typeof info.title === 'string' ? info.title.trim() : ''
103
+ if (!t || OC_DEFAULT_TITLE_RE.test(t)) return
104
+ titles.set(info.id, t.slice(0, 100))
105
+ }
106
+
@@ -6,6 +6,9 @@ export function openPermissions(cfg: unknown): void
6
6
  export const OC_GATED_KEYS: string[]
7
7
  export function userText(output: unknown): string
8
8
  export function rememberTitle(titles: Map<string, string>, info: unknown): void
9
- export function make(opts?: { node?: string }): (ctx: unknown) => Promise<Record<string, unknown>>
9
+ export function make(opts?: { node?: string; env?: Record<string, string | undefined>; execPath?: string }): (ctx: unknown) => Promise<Record<string, unknown>>
10
+ export function isDumateHost(env?: Record<string, string | undefined>, execPath?: string): boolean
10
11
  export function injectAppended(output: unknown, raw: string): string
11
12
  export function alwaysSuggestions(props: unknown): Array<Record<string, unknown>> | undefined
13
+ export function questionToCc(props: unknown): { tool_name: string; tool_input: { questions: Array<Record<string, unknown>> } } | null
14
+ export function isPlainQuestion(props: unknown, callTool: unknown): boolean
package/hook/opencode.mjs CHANGED
@@ -21,8 +21,13 @@
21
21
  // 🔴 窗口模式反过来:任何失败都不表态,授权框照常由人处理。
22
22
 
23
23
  import { spawn } from 'node:child_process'
24
+ import { appendFileSync } from 'node:fs'
24
25
  import { dirname, join } from 'node:path'
25
26
  import { fileURLToPath } from 'node:url'
27
+ import { alwaysSuggestions, askToCc, isPlainQuestion, questionToCc, rememberTitle, toCcTool } from './ocTranslate.mjs'
28
+
29
+ // 翻译函数搬到了 ocTranslate.mjs(与 DumateWatch 共用),这里转出去保持原来的导出
30
+ export { alwaysSuggestions, askToCc, isPlainQuestion, questionToCc, rememberTitle, toCcTool }
26
31
 
27
32
  const HERE = dirname(fileURLToPath(import.meta.url))
28
33
  const HOOK = join(HERE, 'hook.cjs')
@@ -62,63 +67,6 @@ export function isHeadless(argv = process.argv) {
62
67
  return (end >= 0 ? args.slice(0, end) : args).includes('run')
63
68
  }
64
69
 
65
- /** opencode 工具 → cc-hook 同构的 tool_name / tool_input(daemon 的 classify 按 Claude Code 的工具名判断) */
66
- export function toCcTool(tool, args) {
67
- const a = args && typeof args === 'object' ? args : {}
68
- const s = (v) => (typeof v === 'string' ? v : '')
69
- switch (tool) {
70
- case 'bash':
71
- return { tool_name: 'Bash', tool_input: { command: s(a.command) } }
72
- case 'read':
73
- return { tool_name: 'Read', tool_input: { file_path: s(a.filePath) } }
74
- case 'edit':
75
- return { tool_name: 'Edit', tool_input: { file_path: s(a.filePath) } }
76
- case 'write':
77
- return { tool_name: 'Write', tool_input: { file_path: s(a.filePath) } }
78
- case 'glob':
79
- return { tool_name: 'Glob', tool_input: { pattern: s(a.pattern), path: s(a.path) } }
80
- case 'grep':
81
- return { tool_name: 'Grep', tool_input: { pattern: s(a.pattern), path: s(a.path) } }
82
- case 'list':
83
- return { tool_name: 'LS', tool_input: { path: s(a.path) } }
84
- case 'webfetch':
85
- return { tool_name: 'WebFetch', tool_input: { url: s(a.url) } }
86
- case 'task':
87
- return { tool_name: 'Task', tool_input: {} }
88
- case 'todowrite':
89
- case 'todoread':
90
- return { tool_name: 'TodoWrite', tool_input: {} }
91
- case 'patch':
92
- case 'apply_patch':
93
- return { tool_name: 'apply_patch', tool_input: { patch: s(a.patchText) || s(a.patch) || s(a.input) } }
94
- default:
95
- // 不认识的工具(MCP 等)原名原参数交出去:classify 对不认识的一律推设备
96
- return { tool_name: String(tool || ''), tool_input: a }
97
- }
98
- }
99
-
100
- /** permission.asked → PermissionRequest 的 tool_name / tool_input,给设备卡片生成摘要 */
101
- export function askToCc(props) {
102
- const md = (props && props.metadata) || {}
103
- if (typeof md.command === 'string' && md.command) return { tool_name: 'Bash', tool_input: { command: md.command } }
104
- const file = md.filepath || md.filePath
105
- if (typeof file === 'string' && file) return { tool_name: 'Edit', tool_input: { file_path: file } }
106
- const patterns = Array.isArray(props && props.patterns) ? props.patterns.join(' ') : ''
107
- return { tool_name: String((props && props.permission) || 'permission'), tool_input: { path: patterns } }
108
- }
109
-
110
- /**
111
- * 授权请求里 opencode 自己给的「以后都允许」模式(permission.asked 的 always,如 bash 的 `npm *`、edit 的 `*`)
112
- * → 一条 session 级 addRules 建议(与 Claude Code 的 permission_suggestions 同形),daemon 据此在设备上给「允许并记住」。
113
- * 设备选了记住,gate 输出带 updatedPermissions,插件回 always(opencode 在本次运行期间记住这些模式)。没有 always 返回 undefined
114
- */
115
- export function alwaysSuggestions(props) {
116
- const perm = String((props && props.permission) || '').trim()
117
- const always = props && Array.isArray(props.always) ? props.always.filter((x) => typeof x === 'string' && x.trim() !== '') : []
118
- if (!perm || always.length === 0) return undefined
119
- return [{ type: 'addRules', rules: always.map((x) => ({ toolName: perm, ruleContent: `${perm} ${x.trim()}` })), behavior: 'allow', destination: 'session' }]
120
- }
121
-
122
70
  /**
123
71
  * 远程模式:关卡改由 tool.execute.before 把,放开权限。🔴 必须原地改(整对象替换不生效,O8)。
124
72
  * - OC_GATED_KEYS 是 daemon 压成 deny 的,放成 allow(用户原来在这些键上写的值已被覆盖,找不回来 —— 每一步都要过设备)
@@ -184,17 +132,6 @@ export function injectAppended(output, raw) {
184
132
  return o && typeof o.systemMessage === 'string' ? o.systemMessage : ''
185
133
  }
186
134
 
187
- /** opencode 起标题前的占位名(1.18.32 isDefaultTitle:`New session - ` / `Child session - ` + ISO 时间),不当标题 */
188
- const OC_DEFAULT_TITLE_RE = /^(New session - |Child session - )\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/
189
-
190
- /** session.updated 的 info → 记下自动标题。子会话(subagent,带 parentID)、占位名不记 */
191
- export function rememberTitle(titles, info) {
192
- if (!info || typeof info.id !== 'string' || !info.id || info.parentID) return
193
- const t = typeof info.title === 'string' ? info.title.trim() : ''
194
- if (!t || OC_DEFAULT_TITLE_RE.test(t)) return
195
- titles.set(info.id, t.slice(0, 100))
196
- }
197
-
198
135
  /** 活着的子进程;opencode 退出时一并结束,不留孤儿 gate 挂着设备卡片(评审) */
199
136
  const LIVE = new Set()
200
137
  process.on('exit', () => {
@@ -238,7 +175,18 @@ function startChild(node, script, args, input, killMs = 0) {
238
175
 
239
176
  const runChild = (node, script, args, input, killMs) => startChild(node, script, args, input, killMs).done
240
177
 
178
+ /**
179
+ * 跑在百度搭子(DuMate,内核是改名的 opencode:dumate-opencode)里。那边的会话由 daemon 的 DumateWatch 直连 HTTP 上报和推卡,
180
+ * 插件再报一遍就是 tool=opencode 的第二份会话 + 双卡(spec 2026-10-03 §3.2「防双卡」)
181
+ */
182
+ export function isDumateHost(env = process.env, execPath = process.execPath) {
183
+ return !!(env && env.DUMATE_INAPP_KEY) || /dumate-opencode/i.test(String(execPath || ''))
184
+ }
185
+
241
186
  export function make(opts = {}) {
187
+ if (isDumateHost(opts.env, opts.execPath)) return async function DeskBuddyOff() {
188
+ return {}
189
+ }
242
190
  return async function DeskBuddy(ctx) {
243
191
  const node = process.env.DESKBUDDY_NODE || opts.node || 'node'
244
192
  const client = ctx && ctx.client
@@ -325,6 +273,82 @@ export function make(opts = {}) {
325
273
  if (typeof out.systemMessage === 'string' && out.systemMessage) await toast(out.systemMessage)
326
274
  }
327
275
 
276
+ // ---- 选择题(question.asked):推设备作答,答案经 /question/{id}/reply 回填;设备跳过 → reject ----
277
+ const pendingQ = new Map() // requestID → gate 子进程
278
+ const debugLog = (line) => {
279
+ try {
280
+ appendFileSync(join(HERE, 'hook-debug.log'), `${new Date().toISOString()} [opencode] ${line}\n`, 'utf8')
281
+ } catch (_) {
282
+ /* 记不下不影响 */
283
+ }
284
+ }
285
+ /** 返回是否成功(hey-api 客户端不抛错,失败在返回值的 error / response.status 里) */
286
+ const postRaw = async (url, path, body) => {
287
+ // 插件拿到的是 v1 SDK 客户端,没有 question 的方法:用它底下的 HTTP 客户端直接打(路径参数由客户端填)
288
+ const http = client && (client._client || client.client)
289
+ if (!http || typeof http.post !== 'function') {
290
+ debugLog(`回填选择题失败:客户端没有 post(${url})`)
291
+ return false
292
+ }
293
+ try {
294
+ const r = await http.post({ url, path, ...(body ? { body, headers: { 'Content-Type': 'application/json' } } : {}) })
295
+ const status = r && r.response && typeof r.response.status === 'number' ? r.response.status : 0
296
+ if ((r && r.error) || status >= 400) {
297
+ debugLog(`回填选择题失败:${url} status=${status || '?'}`)
298
+ return false
299
+ }
300
+ return true
301
+ } catch (e) {
302
+ debugLog(`回填选择题出错:${url} ${(e && e.message) || e}`)
303
+ return false
304
+ }
305
+ }
306
+ const onQuestion = async (p) => {
307
+ const { id, sessionID } = p || {}
308
+ if (!id || !sessionID || runId || headless || !client) return
309
+ const call = p.tool && p.tool.callID ? calls.get(p.tool.callID) : null
310
+ if (!isPlainQuestion(p, call && call.tool)) return
311
+ const cc = questionToCc(p)
312
+ if (!cc) return
313
+ const input = { hook_event_name: 'PermissionRequest', session_id: sessionID, cwd, ...cc }
314
+ const { child, done } = startChild(node, GATE, ['--window', '--tool', TOOL], input)
315
+ if (child) pendingQ.set(id, child)
316
+ const r = await done
317
+ pendingQ.delete(id)
318
+ if (r.code !== 0 || !r.out) return
319
+ let out
320
+ try {
321
+ out = JSON.parse(r.out)
322
+ } catch (_) {
323
+ return
324
+ }
325
+ const d = out && out.hookSpecificOutput && out.hookSpecificOutput.decision
326
+ if (!d) return
327
+ let ok
328
+ if (d.behavior === 'allow' && Array.isArray(out.deskbuddyAnswers)) {
329
+ ok = await postRaw('/question/{requestID}/reply', { requestID: id }, { answers: out.deskbuddyAnswers })
330
+ } else if (d.behavior === 'deny') {
331
+ ok = await postRaw('/question/{requestID}/reject', { requestID: id })
332
+ } else return
333
+ if (!ok) {
334
+ await toast('设备答案未能回填,请在窗口作答')
335
+ return
336
+ }
337
+ if (typeof out.systemMessage === 'string' && out.systemMessage) await toast(out.systemMessage)
338
+ }
339
+ const onQuestionDone = (p) => {
340
+ // 人先在窗口里答了 / 拒了:结束 gate 子进程,daemon 随之撤掉设备上的卡片
341
+ const child = p && pendingQ.get(p.requestID)
342
+ if (child) {
343
+ pendingQ.delete(p.requestID)
344
+ try {
345
+ child.kill('SIGTERM')
346
+ } catch (_) {
347
+ /* 已经退了 */
348
+ }
349
+ }
350
+ }
351
+
328
352
  const onReplied = (p) => {
329
353
  // 人先在窗口里答了:结束 gate 子进程,daemon 随之撤掉设备上的卡片
330
354
  const child = p && pending.get(p.requestID)
@@ -362,7 +386,7 @@ export function make(opts = {}) {
362
386
 
363
387
  'tool.execute.before': async (input, output) => {
364
388
  const cc = toCcTool(input && input.tool, output && output.args)
365
- if (input && input.callID) calls.set(input.callID, { cc, at: Date.now() })
389
+ if (input && input.callID) calls.set(input.callID, { cc, tool: input && input.tool, at: Date.now() })
366
390
  report('PreToolUse', input && input.sessionID, cc)
367
391
  if (!runId) return
368
392
  // 远程关卡:等设备。任何失败都拒(见顶部)
@@ -398,6 +422,13 @@ export function make(opts = {}) {
398
422
  case 'permission.replied':
399
423
  onReplied(p)
400
424
  break
425
+ case 'question.asked':
426
+ onQuestion(p).catch(() => {})
427
+ break
428
+ case 'question.replied':
429
+ case 'question.rejected':
430
+ onQuestionDone(p)
431
+ break
401
432
  case 'session.idle':
402
433
  report('Stop', p.sessionID)
403
434
  break
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deskbuddy",
3
- "version": "0.2.0-beta.13",
3
+ "version": "0.2.0-beta.14",
4
4
  "description": "把 Claude Code、Codex 等 AI 编码智能体每个会话窗口的状态,实时同步到桌面硬件屏幕",
5
5
  "keywords": [
6
6
  "ai",
@@ -19,11 +19,12 @@
19
19
  "files": [
20
20
  "dist",
21
21
  "hook",
22
+ "vendor",
22
23
  "docs/INSTALL.md",
23
24
  "README.md"
24
25
  ],
25
26
  "scripts": {
26
- "build": "tsup && cp hook/hook.cjs dist/hook.cjs && cp hook/gate.cjs dist/gate.cjs && cp hook/wake.cjs dist/wake.cjs && cp hook/opencode.mjs dist/opencode.mjs && cp hook/launcher.cjs dist/launcher.cjs",
27
+ "build": "tsup && cp hook/hook.cjs dist/hook.cjs && cp hook/gate.cjs dist/gate.cjs && cp hook/wake.cjs dist/wake.cjs && cp hook/opencode.mjs dist/opencode.mjs && cp hook/ocTranslate.mjs dist/ocTranslate.mjs && cp hook/launcher.cjs dist/launcher.cjs",
27
28
  "prepublishOnly": "npm run typecheck && npm test && npm run build",
28
29
  "test": "vitest run",
29
30
  "typecheck": "tsc --noEmit"
@@ -0,0 +1,69 @@
1
+ Copyright (c) 2012-2015, Christopher Jeffrey (https://github.com/chjj/)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
20
+
21
+
22
+
23
+ The MIT License (MIT)
24
+
25
+ Copyright (c) 2016, Daniel Imms (http://www.growingwiththeweb.com)
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining a copy
28
+ of this software and associated documentation files (the "Software"), to deal
29
+ in the Software without restriction, including without limitation the rights
30
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
31
+ copies of the Software, and to permit persons to whom the Software is
32
+ furnished to do so, subject to the following conditions:
33
+
34
+ The above copyright notice and this permission notice shall be included in all
35
+ copies or substantial portions of the Software.
36
+
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43
+ SOFTWARE.
44
+
45
+
46
+
47
+ MIT License
48
+
49
+ Copyright (c) 2018 - present Microsoft Corporation
50
+
51
+ All rights reserved.
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining a copy
54
+ of this software and associated documentation files (the "Software"), to deal
55
+ in the Software without restriction, including without limitation the rights
56
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57
+ copies of the Software, and to permit persons to whom the Software is
58
+ furnished to do so, subject to the following conditions:
59
+
60
+ The above copyright notice and this permission notice shall be included in all
61
+ copies or substantial portions of the Software.
62
+
63
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
68
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
69
+ SOFTWARE.
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2019, Microsoft Corporation (MIT License).
4
+ *
5
+ * This module fetches the console process list for a particular PID. It must be
6
+ * called from a different process (child_process.fork) as there can only be a
7
+ * single console attached to a process.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ var utils_1 = require("./utils");
11
+ var getConsoleProcessList = utils_1.loadNativeModule('conpty_console_list').module.getConsoleProcessList;
12
+ var shellPid = parseInt(process.argv[2], 10);
13
+ var consoleProcessList = getConsoleProcessList(shellPid);
14
+ process.send({ consoleProcessList: consoleProcessList });
15
+ process.exit(0);
16
+ //# sourceMappingURL=conpty_console_list_agent.js.map
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2019, Microsoft Corporation (MIT License).
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EventEmitter2 = void 0;
7
+ var EventEmitter2 = /** @class */ (function () {
8
+ function EventEmitter2() {
9
+ this._listeners = [];
10
+ }
11
+ Object.defineProperty(EventEmitter2.prototype, "event", {
12
+ get: function () {
13
+ var _this = this;
14
+ if (!this._event) {
15
+ this._event = function (listener) {
16
+ _this._listeners.push(listener);
17
+ var disposable = {
18
+ dispose: function () {
19
+ for (var i = 0; i < _this._listeners.length; i++) {
20
+ if (_this._listeners[i] === listener) {
21
+ _this._listeners.splice(i, 1);
22
+ return;
23
+ }
24
+ }
25
+ }
26
+ };
27
+ return disposable;
28
+ };
29
+ }
30
+ return this._event;
31
+ },
32
+ enumerable: false,
33
+ configurable: true
34
+ });
35
+ EventEmitter2.prototype.fire = function (data) {
36
+ var queue = [];
37
+ for (var i = 0; i < this._listeners.length; i++) {
38
+ queue.push(this._listeners[i]);
39
+ }
40
+ for (var i = 0; i < queue.length; i++) {
41
+ queue[i].call(undefined, data);
42
+ }
43
+ };
44
+ return EventEmitter2;
45
+ }());
46
+ exports.EventEmitter2 = EventEmitter2;
47
+ //# sourceMappingURL=eventEmitter2.js.map
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2012-2015, Christopher Jeffrey, Peter Sunde (MIT License)
4
+ * Copyright (c) 2016, Daniel Imms (MIT License).
5
+ * Copyright (c) 2018, Microsoft Corporation (MIT License).
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.native = exports.open = exports.createTerminal = exports.fork = exports.spawn = void 0;
9
+ var utils_1 = require("./utils");
10
+ var terminalCtor;
11
+ if (process.platform === 'win32') {
12
+ terminalCtor = require('./windowsTerminal').WindowsTerminal;
13
+ }
14
+ else {
15
+ terminalCtor = require('./unixTerminal').UnixTerminal;
16
+ }
17
+ /**
18
+ * Forks a process as a pseudoterminal.
19
+ * @param file The file to launch.
20
+ * @param args The file's arguments as argv (string[]) or in a pre-escaped
21
+ * CommandLine format (string). Note that the CommandLine option is only
22
+ * available on Windows and is expected to be escaped properly.
23
+ * @param options The options of the terminal.
24
+ * @throws When the file passed to spawn with does not exists.
25
+ * @see CommandLineToArgvW https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx
26
+ * @see Parsing C++ Comamnd-Line Arguments https://msdn.microsoft.com/en-us/library/17w5ykft.aspx
27
+ * @see GetCommandLine https://msdn.microsoft.com/en-us/library/windows/desktop/ms683156.aspx
28
+ */
29
+ function spawn(file, args, opt) {
30
+ return new terminalCtor(file, args, opt);
31
+ }
32
+ exports.spawn = spawn;
33
+ /** @deprecated */
34
+ function fork(file, args, opt) {
35
+ return new terminalCtor(file, args, opt);
36
+ }
37
+ exports.fork = fork;
38
+ /** @deprecated */
39
+ function createTerminal(file, args, opt) {
40
+ return new terminalCtor(file, args, opt);
41
+ }
42
+ exports.createTerminal = createTerminal;
43
+ function open(options) {
44
+ return terminalCtor.open(options);
45
+ }
46
+ exports.open = open;
47
+ /**
48
+ * Expose the native API when not Windows, note that this is not public API and
49
+ * could be removed at any time.
50
+ */
51
+ exports.native = (process.platform !== 'win32' ? utils_1.loadNativeModule('pty').module : null);
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2016, Daniel Imms (MIT License).
4
+ * Copyright (c) 2018, Microsoft Corporation (MIT License).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2020, Microsoft Corporation (MIT License).
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getWorkerPipeName = void 0;
7
+ function getWorkerPipeName(conoutPipeName) {
8
+ return conoutPipeName + "-worker";
9
+ }
10
+ exports.getWorkerPipeName = getWorkerPipeName;
11
+ //# sourceMappingURL=conout.js.map