@thincoder/core 0.10.7 → 0.10.8

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 (125) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/advisor/compaction.mjs +1 -1
  3. package/advisor/run.mjs +1 -1
  4. package/agent/chat-call.mjs +40 -27
  5. package/agent/child-marks.mjs +1 -1
  6. package/agent/dispatch-gates.mjs +7 -4
  7. package/agent/dispatch-run.mjs +1 -0
  8. package/agent/family-tools.mjs +11 -6
  9. package/agent/helpers.mjs +6 -4
  10. package/agent/image-heal.mjs +65 -0
  11. package/agent/light-round.mjs +4 -4
  12. package/agent/live-beat.mjs +4 -4
  13. package/agent/record-results.mjs +9 -1
  14. package/agent/run-stages.mjs +2 -1
  15. package/agent/setup-reminders.mjs +14 -13
  16. package/agent/setup.mjs +62 -46
  17. package/agent/spawn-child.mjs +1 -1
  18. package/agent/subagent-event.mjs +1 -1
  19. package/agent/suspension.mjs +2 -1
  20. package/agent/timers.mjs +8 -8
  21. package/agent/turn-loop.mjs +1 -1
  22. package/agent-tools/advisor.mjs +1 -1
  23. package/agent-tools/async-discard.mjs +40 -5
  24. package/agent-tools/async-settle.mjs +3 -1
  25. package/agent-tools/audit-block.mjs +1 -1
  26. package/agent-tools/batch-paths.mjs +20 -20
  27. package/agent-tools/checkpoint.mjs +1 -1
  28. package/agent-tools/design-slots.mjs +44 -5
  29. package/agent-tools/doc-check.mjs +37 -0
  30. package/agent-tools/eng.mjs +5 -3
  31. package/agent-tools/manifest.mjs +18 -18
  32. package/agent-tools/parent-channel.mjs +3 -3
  33. package/agent-tools/review-facts.mjs +2 -2
  34. package/agent-tools/settings.mjs +1 -1
  35. package/agent-tools/spawn-gates.mjs +8 -6
  36. package/agent-tools/ssh-session.mjs +439 -0
  37. package/agent-tools/ssh-transport.mjs +311 -0
  38. package/agent-tools/subagent-scheduler.mjs +6 -5
  39. package/agent-tools/subagent.mjs +7 -5
  40. package/agent-tools/task.mjs +1 -1
  41. package/agent-tools/timer.mjs +6 -0
  42. package/agent-tools/zero-write-watch.mjs +2 -2
  43. package/agent-tools.mjs +3 -2
  44. package/attachments.mjs +4 -4
  45. package/browser/cdp.mjs +2 -2
  46. package/browser/launch.mjs +50 -4
  47. package/browser/snapshot.mjs +1 -1
  48. package/config-io.mjs +7 -2
  49. package/config-watch.mjs +2 -2
  50. package/config.mjs +7 -0
  51. package/declaration.mjs +5 -1
  52. package/doc-check/anchors.mjs +100 -0
  53. package/doc-check/index.mjs +61 -0
  54. package/doc-check/width.mjs +131 -0
  55. package/file-refs.mjs +6 -6
  56. package/generate-title.mjs +1 -1
  57. package/hooks.mjs +1 -1
  58. package/i18n.mjs +11 -1
  59. package/ledger-cmd.mjs +4 -5
  60. package/ledger-db.mjs +100 -21
  61. package/ledger-migrate.mjs +3 -3
  62. package/ledger-read.mjs +6 -7
  63. package/ledger-tools.mjs +24 -9
  64. package/ledger.mjs +23 -54
  65. package/log.mjs +17 -3
  66. package/manifest-discovery.mjs +21 -18
  67. package/manifest-schema.mjs +2 -13
  68. package/manifest.mjs +37 -22
  69. package/mcp/transport-stdio.mjs +1 -1
  70. package/mcp.mjs +2 -2
  71. package/memory/core.mjs +1 -1
  72. package/memory/scan.mjs +1 -1
  73. package/memory/sweep.mjs +1 -1
  74. package/model-specs.mjs +7 -7
  75. package/notify-policy.mjs +6 -6
  76. package/package.json +2 -1
  77. package/permission.mjs +14 -0
  78. package/prompts/advisor-design.md +43 -13
  79. package/prompts/advisor-round1.md +25 -5
  80. package/prompts/advisor-round2.md +17 -4
  81. package/prompts/advisor-round3.md +17 -4
  82. package/prompts/common.md +60 -6
  83. package/prompts/consult-base.md +8 -2
  84. package/prompts/discipline-engineering.md +11 -10
  85. package/prompts/discipline-normal.md +22 -14
  86. package/prompts/persona-coder.md +1 -1
  87. package/prompts/persona-eng-designer.md +8 -3
  88. package/prompts/persona-engineering.md +21 -5
  89. package/prompts/persona-normal.md +4 -1
  90. package/provider/errors.mjs +8 -0
  91. package/provider/google.mjs +3 -0
  92. package/provider/normalize.mjs +42 -12
  93. package/provider/responses-request.mjs +1 -1
  94. package/provider/responses.mjs +2 -2
  95. package/provider/wait-status.mjs +1 -1
  96. package/provider-flows.mjs +1 -1
  97. package/queued.mjs +2 -2
  98. package/rules.mjs +4 -4
  99. package/session-gc.mjs +1 -1
  100. package/session-lifecycle.mjs +1 -1
  101. package/session-slot-write.mjs +2 -2
  102. package/session-slots-manifest.mjs +1 -1
  103. package/session.mjs +1 -1
  104. package/shell-candidates.mjs +2 -2
  105. package/shell-identity.mjs +1 -1
  106. package/team.mjs +61 -4
  107. package/think-off.mjs +3 -3
  108. package/token-ttl.mjs +1 -1
  109. package/tool-docs/bash.md +1 -1
  110. package/tool-docs/browser.md +1 -1
  111. package/tool-docs/doc_check.md +31 -0
  112. package/tool-docs/manifest.md +14 -2
  113. package/tool-docs/ssh.md +34 -0
  114. package/tool-docs/subagent.md +2 -0
  115. package/tool-docs/timer.md +2 -1
  116. package/tools/browser.mjs +1 -1
  117. package/tools/execute.mjs +1 -1
  118. package/tools/git-run.mjs +2 -2
  119. package/tools/git.mjs +8 -8
  120. package/tools/index.mjs +3 -0
  121. package/tools/ops.mjs +1 -1
  122. package/tools/process-tree.mjs +2 -2
  123. package/tools/ssh-askpass.mjs +35 -0
  124. package/tools/ssh.mjs +92 -0
  125. package/vision-reader.mjs +4 -4
package/tools/ssh.mjs ADDED
@@ -0,0 +1,92 @@
1
+ /**
2
+ * tools/ssh.mjs — SSH 会话工具面(薄接线):schema ∥ 参数校验 ∥ `isReadonlyAction` ∥ 回执/错误形
3
+ * (设计 = `docs/core/design/TOOLS.md` §6.22 —— D-TO17/D-TO18 · 台账 #1436;机制单点 =
4
+ * `agent-tools/ssh-session.mjs`;描述档 = `tool-docs/ssh.md`)。
5
+ *
6
+ * 分类钩子(KD-2 ∥ KD-11 同式——动作级,工具级只读位恒 false):免审 = `list` ∥ `read`
7
+ * (只读豁免,NS3 判据);过门 = `connect` ∥ `send` ∥ `secret_input` ∥ `close`——**携密动作仍属
8
+ * 写动作**,门不放松;携密径审批文案 = 掩码占位(`permission.mjs`,值不回显 ⇒ 不入上下文 / 审批记录)。
9
+ *
10
+ * 失败回执**返回**(不 throw)——首行 `Error: …` = 模型面失败形(`bash` / `browser` 既例);
11
+ * 无 UI 考(缺 `ctx.onSecretInput` 回调)⇒ 机制档抛可读错(`question.mjs` 无 UI 抛例同旨)。
12
+ * 会话跨调用存活于池(非本档持有);depth>0 排除(`agent/helpers.mjs` `SUBAGENT_TOOL_EXCLUSIONS`)。
13
+ * 动态 import(W8 契约②:agent-tools 静态链达 node:sqlite——端壳静态闭包须保持零命中)。
14
+ */
15
+ import { DESC } from "./shared.mjs"
16
+
17
+ export const SSH_ACTIONS = ["connect", "send", "read", "secret_input", "close", "list"]
18
+
19
+ /** 参数校验(缺必填 / 形错 ⇒ `Error: …`——不执行;§6.22 动作表逐动作必填面)。 */
20
+ export function validateArgs(args) {
21
+ const action = args?.action
22
+ if (!SSH_ACTIONS.includes(action)) {
23
+ return `Error: unknown ssh action "${action ?? ""}" — actions: ${SSH_ACTIONS.join(", ")}`
24
+ }
25
+ if (action === "connect") {
26
+ if (typeof args.host !== "string" || args.host.trim() === "") return "Error: connect requires host"
27
+ if (args.port !== undefined && args.port !== null && args.port !== "" && !Number.isFinite(Number(args.port))) {
28
+ return "Error: connect port must be a number"
29
+ }
30
+ return null
31
+ }
32
+ if (action === "list") return null
33
+ if (typeof args.id !== "string" || args.id.trim() === "") {
34
+ return `Error: ${action} requires id (the session id from connect, form "ssh#N")`
35
+ }
36
+ if (action === "send" && typeof args.data !== "string") return "Error: send requires data"
37
+ return null
38
+ }
39
+
40
+ export const sshTool = {
41
+ name: "ssh",
42
+ description: DESC("ssh"),
43
+ parameters: {
44
+ type: "object",
45
+ properties: {
46
+ action: { type: "string", enum: SSH_ACTIONS, description: "Action to run (one per call): connect | send | read | secret_input | close | list." },
47
+ host: { type: "string", description: "connect: target host (IP or name)." },
48
+ user: { type: "string", description: "connect: login user (optional: your local ssh config decides, else the user recorded for this host locally)." },
49
+ port: { type: "number", description: "connect: TCP port (optional, default 22)." },
50
+ label: { type: "string", description: "connect: short human label for this session (optional); secret_input: label for the value being sent." },
51
+ promptPattern: { type: "string", description: "connect: regex that marks the shell prompt as ready (optional): send/read then settle the moment the prompt appears instead of waiting out the silence window." },
52
+ id: { type: "string", description: "send / read / secret_input / close: session id from connect (`ssh#N`)." },
53
+ data: { type: "string", description: "send: text to type into the session (a trailing newline is passed as-is; otherwise Enter is sent as `\\r`)." },
54
+ settle: { type: "boolean", description: "send: wait for the ready verdict before returning (default true); false returns right after the bytes are written." },
55
+ timeoutMs: { type: "number", description: "send / read: wait budget override (default 10000) — on expiry the call returns partial output with a readable line." },
56
+ maxChars: { type: "number", description: "read: return cap override (default 8000; the full output stays in the session log)." },
57
+ },
58
+ required: ["action"],
59
+ },
60
+ // 非工具级只读:动作级分类钩子接管(§6.22 NS3——`list` / `read` 免审);也因此不进只读角色的子代工具表。
61
+ readonly: false,
62
+ isReadonlyAction(args) {
63
+ return args?.action === "list" || args?.action === "read"
64
+ },
65
+ async execute(args, ctx) {
66
+ const invalid = validateArgs(args)
67
+ if (invalid) return invalid
68
+ // 动态 import(W8 契约②——与 bash / browser 异步面同式)。
69
+ const mod = await import("../agent-tools/ssh-session.mjs")
70
+ const parent = ctx?.agent ?? null
71
+ const action = args.action
72
+ let res
73
+ if (action === "connect") {
74
+ res = await mod.connectSsh(parent, ctx, {
75
+ host: args.host, user: args.user ?? null, port: args.port ?? null,
76
+ label: args.label ?? null, promptPattern: args.promptPattern ?? null,
77
+ })
78
+ } else if (action === "send") {
79
+ res = await mod.sendSsh(parent, ctx, { id: args.id, data: args.data, settle: args.settle !== false, timeoutMs: args.timeoutMs })
80
+ } else if (action === "read") {
81
+ res = await mod.readSsh(parent, ctx, { id: args.id, timeoutMs: args.timeoutMs, maxChars: args.maxChars })
82
+ } else if (action === "secret_input") {
83
+ res = await mod.secretInputSsh(parent, ctx, { id: args.id, label: args.label ?? null })
84
+ } else if (action === "close") {
85
+ res = await mod.closeSsh(parent, ctx, { id: args.id })
86
+ } else {
87
+ res = mod.listSsh(parent)
88
+ }
89
+ if (res?.error) return res.error.startsWith("Error:") ? res.error : `Error: ${res.error}`
90
+ return res?.text ?? "(no output)"
91
+ },
92
+ }
package/vision-reader.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * vision-reader.mjs — 非多模态降级读图跑者(上提核件 —— parity-b4 W0 · 2026-09-29)。
3
3
  *
4
- * 上提源 = VSC `thincoder-vscode/src/extension/vision-channel.mjs:14`(`findVisionChannel` 逐字)
5
- * + `image-handler.mjs:70-95`(`runVisionReader` 逐字);VSC 自持跑者 ∕ 渠道副本已随迁移轮(parity-b4)删。
4
+ * 上提源 = VSC `thincoder-vscode/src/extension/vision-channel.mjs`(#1127 已删档;`findVisionChannel` 逐字)
5
+ * + `image-handler.mjs`(`runVisionReader` 逐字);VSC 自持跑者 ∕ 渠道副本已随迁移轮(parity-b4)删。
6
6
  * 消费面 = VSC `image-handler.mjs`(已改指本档)· 桌面 `src/main/attachments.mjs`
7
7
  * (降级适配器缺省 = 本档 —— `visionReader` 缝的核默认实现)。
8
8
  *
@@ -19,13 +19,13 @@
19
19
  *
20
20
  * W8 契约②(2026-09-29 断链):`agent.mjs` ∕ `agent-tools/subagent-async.mjs` 静态链达 `node:sqlite`
21
21
  * (`agent.mjs` → `agent/setup.mjs` → `memory.mjs` → `memory/schema.mjs`)⇒ 两端一律**函数体内动态 import**
22
- * (约定源 = `ledger.mjs:16`;实例 = `tools/index.mjs:63`);本档静态边只留闭包净件(`config-io.mjs` ∕
22
+ * (约定源 = `ledger.mjs`;实例 = `tools/index.mjs` 的 `assembleBuiltinTools`);本档静态边只留闭包净件(`config-io.mjs` ∕
23
23
  * `tools/index.mjs`)。
24
24
  */
25
25
  import { resolveProviders } from "./config-io.mjs"
26
26
  import { assembleBuiltinTools } from "./tools/index.mjs"
27
27
 
28
- /** 读图墙钟上限(VSC `image-handler.mjs:70` 同值——一次性子代理的成功径上限)。 */
28
+ /** 读图墙钟上限(VSC `image-handler.mjs` 的 `runVisionReader` 同值——一次性子代理的成功径上限)。 */
29
29
  export const VISION_READ_TIMEOUT_MS = 60_000
30
30
 
31
31
  /** 找可跑视觉读图的渠道:`{ provider, model }` ∥ `null`。