railwise-ai 1.2.32 → 1.2.34

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 (173) hide show
  1. package/agent-pack/README.md +16 -0
  2. package/agent-pack/assets/agent/chief_manager.md +69 -0
  3. package/agent-pack/assets/agent/commercial_specialist.md +47 -0
  4. package/agent-pack/assets/agent/data_analyst.md +54 -0
  5. package/agent-pack/assets/agent/docs.md +38 -0
  6. package/agent-pack/assets/agent/duplicate-pr.md +25 -0
  7. package/agent-pack/assets/agent/qa_inspector.md +58 -0
  8. package/agent-pack/assets/agent/qa_reviewer.md +57 -0
  9. package/agent-pack/assets/agent/solution_architect.md +53 -0
  10. package/agent-pack/assets/agent/technical_writer.md +61 -0
  11. package/agent-pack/assets/agent/translator.md +34 -0
  12. package/agent-pack/assets/agent/triage.md +139 -0
  13. package/agent-pack/assets/command/ai-deps.md +24 -0
  14. package/agent-pack/assets/command/bid-intel.md +29 -0
  15. package/agent-pack/assets/command/bid-prepare.md +24 -0
  16. package/agent-pack/assets/command/commit.md +37 -0
  17. package/agent-pack/assets/command/daily-report.md +26 -0
  18. package/agent-pack/assets/command/data-check.md +22 -0
  19. package/agent-pack/assets/command/emergency-response.md +66 -0
  20. package/agent-pack/assets/command/issues.md +23 -0
  21. package/agent-pack/assets/command/learn.md +42 -0
  22. package/agent-pack/assets/command/monthly-report.md +35 -0
  23. package/agent-pack/assets/command/payment-reminder.md +27 -0
  24. package/agent-pack/assets/command/plan-draft.md +28 -0
  25. package/agent-pack/assets/command/review-response.md +23 -0
  26. package/agent-pack/assets/command/rmslop.md +15 -0
  27. package/agent-pack/assets/command/safety-check.md +20 -0
  28. package/agent-pack/assets/command/spellcheck.md +5 -0
  29. package/agent-pack/assets/command/trend-analysis.md +38 -0
  30. package/agent-pack/assets/command/weekly-report.md +28 -0
  31. package/agent-pack/assets/lib/os_api.ts +100 -0
  32. package/agent-pack/assets/skill/adjustment-report/SKILL.md +88 -0
  33. package/agent-pack/assets/skill/approval-flow-intelligence/SKILL.md +123 -0
  34. package/agent-pack/assets/skill/bidding-knowledge/SKILL.md +98 -0
  35. package/agent-pack/assets/skill/bun-file-io/SKILL.md +42 -0
  36. package/agent-pack/assets/skill/business-finance/SKILL.md +91 -0
  37. package/agent-pack/assets/skill/business-operations-analytics/SKILL.md +120 -0
  38. package/agent-pack/assets/skill/cad-bim-review/SKILL.md +84 -0
  39. package/agent-pack/assets/skill/canvas-design/SKILL.md +141 -0
  40. package/agent-pack/assets/skill/construction-monitoring/SKILL.md +89 -0
  41. package/agent-pack/assets/skill/customer-portal-brief/SKILL.md +121 -0
  42. package/agent-pack/assets/skill/data-analysis/SKILL.md +79 -0
  43. package/agent-pack/assets/skill/di-bao-monitoring/SKILL.md +680 -0
  44. package/agent-pack/assets/skill/di-bao-monitoring/agents/openai.yaml +4 -0
  45. package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-static-level-input-template.csv +2 -0
  46. package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-total-station-input-template.csv +2 -0
  47. package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-total-station-report-template.md +59 -0
  48. package/agent-pack/assets/skill/di-bao-monitoring/assets/daily-report-template.md +90 -0
  49. package/agent-pack/assets/skill/di-bao-monitoring/assets/data-input-template.csv +2 -0
  50. package/agent-pack/assets/skill/di-bao-monitoring/assets/initial-value-report-template.md +92 -0
  51. package/agent-pack/assets/skill/di-bao-monitoring/assets/monthly-report-template.md +103 -0
  52. package/agent-pack/assets/skill/di-bao-monitoring/assets/plan-template.md +673 -0
  53. package/agent-pack/assets/skill/di-bao-monitoring/assets/point-alias-map-template.json +25 -0
  54. package/agent-pack/assets/skill/di-bao-monitoring/assets/project-brief-template.md +59 -0
  55. package/agent-pack/assets/skill/di-bao-monitoring/assets/project-summary-template.md +154 -0
  56. package/agent-pack/assets/skill/di-bao-monitoring/assets/warning-notice-template.md +58 -0
  57. package/agent-pack/assets/skill/di-bao-monitoring/assets/weekly-report-template.md +49 -0
  58. package/agent-pack/assets/skill/di-bao-monitoring/assets//345/256/214/346/225/264/346/212/245/350/241/250/346/250/241/346/235/277.xlsx +0 -0
  59. package/agent-pack/assets/skill/di-bao-monitoring/assets//345/277/253/346/212/245/346/250/241/346/235/277.xlsx +0 -0
  60. package/agent-pack/assets/skill/di-bao-monitoring/references/crossing-static-level-report.md +115 -0
  61. package/agent-pack/assets/skill/di-bao-monitoring/references/crossing-total-station-report.md +206 -0
  62. package/agent-pack/assets/skill/di-bao-monitoring/references/data-processing.md +170 -0
  63. package/agent-pack/assets/skill/di-bao-monitoring/references/elevated-line.md +319 -0
  64. package/agent-pack/assets/skill/di-bao-monitoring/references/initial-and-summary-workflow.md +222 -0
  65. package/agent-pack/assets/skill/di-bao-monitoring/references/key-difficulties.md +216 -0
  66. package/agent-pack/assets/skill/di-bao-monitoring/references/monitoring-catalog.md +80 -0
  67. package/agent-pack/assets/skill/di-bao-monitoring/references/phase0-intake.md +169 -0
  68. package/agent-pack/assets/skill/di-bao-monitoring/references/phase1-drafting.md +185 -0
  69. package/agent-pack/assets/skill/di-bao-monitoring/references/phase2-internal-review.md +166 -0
  70. package/agent-pack/assets/skill/di-bao-monitoring/references/report-workflow.md +181 -0
  71. package/agent-pack/assets/skill/di-bao-monitoring/references/review-checklist.md +140 -0
  72. package/agent-pack/assets/skill/di-bao-monitoring/references/review-response-template.md +87 -0
  73. package/agent-pack/assets/skill/di-bao-monitoring/references/scoping-and-pricing.md +214 -0
  74. package/agent-pack/assets/skill/di-bao-monitoring/references/source-analysis.md +137 -0
  75. package/agent-pack/assets/skill/di-bao-monitoring/references/technical-standards.md +188 -0
  76. package/agent-pack/assets/skill/di-bao-monitoring/references/toc-template-A.md +142 -0
  77. package/agent-pack/assets/skill/di-bao-monitoring/references/toc-template-B.md +100 -0
  78. package/agent-pack/assets/skill/di-bao-monitoring/references/warning-workflow.md +63 -0
  79. package/agent-pack/assets/skill/di-bao-monitoring/scripts/build_crossing_total_station_xlsx.py +2438 -0
  80. package/agent-pack/assets/skill/di-bao-monitoring/scripts/evaluate_alarms.py +215 -0
  81. package/agent-pack/assets/skill/di-bao-monitoring/scripts/fetch_adjusted_total_station.py +946 -0
  82. package/agent-pack/assets/skill/di-bao-monitoring/scripts/fetch_shhh_static_level.py +556 -0
  83. package/agent-pack/assets/skill/di-bao-monitoring/scripts/run_crossing_4h_report.sh +141 -0
  84. package/agent-pack/assets/skill/di-bao-monitoring/scripts/summarize_crossing_total_station.py +303 -0
  85. package/agent-pack/assets/skill/docx-generation/SKILL.md +141 -0
  86. package/agent-pack/assets/skill/excel-operations/SKILL.md +121 -0
  87. package/agent-pack/assets/skill/frontend-design/SKILL.md +151 -0
  88. package/agent-pack/assets/skill/humanizer/SKILL.md +90 -0
  89. package/agent-pack/assets/skill/monitoring-design/SKILL.md +100 -0
  90. package/agent-pack/assets/skill/operational-monitoring/SKILL.md +135 -0
  91. package/agent-pack/assets/skill/operational-monitoring/assets/checklists/archive-self-check.md +54 -0
  92. package/agent-pack/assets/skill/operational-monitoring/assets/schemas/convergence-result-table.csv +5 -0
  93. package/agent-pack/assets/skill/operational-monitoring/assets/schemas/horizontal-result-table.csv +3 -0
  94. package/agent-pack/assets/skill/operational-monitoring/assets/schemas/settlement-result-table.csv +7 -0
  95. package/agent-pack/assets/skill/operational-monitoring/assets/scripts/init-archive-tree.sh +65 -0
  96. package/agent-pack/assets/skill/operational-monitoring/assets/templates/control-network-report.md +102 -0
  97. package/agent-pack/assets/skill/operational-monitoring/assets/templates/daily-log.md +47 -0
  98. package/agent-pack/assets/skill/operational-monitoring/assets/templates/i-angle-check.md +38 -0
  99. package/agent-pack/assets/skill/operational-monitoring/assets/templates/monitoring-scheme.md +234 -0
  100. package/agent-pack/assets/skill/operational-monitoring/assets/templates/period-report.md +95 -0
  101. package/agent-pack/assets/skill/operational-monitoring/assets/templates/point-acceptance-record.md +51 -0
  102. package/agent-pack/assets/skill/operational-monitoring/assets/templates/point-installation-record.md +38 -0
  103. package/agent-pack/assets/skill/operational-monitoring/assets/templates/summary-report.md +89 -0
  104. package/agent-pack/assets/skill/operational-monitoring/assets/templates/warning-bulletin.md +61 -0
  105. package/agent-pack/assets/skill/operational-monitoring/assets/templates/weekly-monthly-report.md +46 -0
  106. package/agent-pack/assets/skill/operational-monitoring/references/archive-and-delivery.md +146 -0
  107. package/agent-pack/assets/skill/operational-monitoring/references/baseline-network.md +131 -0
  108. package/agent-pack/assets/skill/operational-monitoring/references/convergence-monitoring.md +134 -0
  109. package/agent-pack/assets/skill/operational-monitoring/references/data-processing.md +178 -0
  110. package/agent-pack/assets/skill/operational-monitoring/references/horizontal-displacement.md +128 -0
  111. package/agent-pack/assets/skill/operational-monitoring/references/monitoring-points.md +132 -0
  112. package/agent-pack/assets/skill/operational-monitoring/references/monitoring-scheme.md +178 -0
  113. package/agent-pack/assets/skill/operational-monitoring/references/period-report.md +108 -0
  114. package/agent-pack/assets/skill/operational-monitoring/references/regulations-and-frequency.md +127 -0
  115. package/agent-pack/assets/skill/operational-monitoring/references/settlement-monitoring.md +116 -0
  116. package/agent-pack/assets/skill/operational-monitoring/references/summary-report.md +128 -0
  117. package/agent-pack/assets/skill/operational-monitoring/references/warning-and-disposal.md +118 -0
  118. package/agent-pack/assets/skill/ops-monitoring/SKILL.md +93 -0
  119. package/agent-pack/assets/skill/railwise-knowledge-curation/SKILL.md +92 -0
  120. package/agent-pack/assets/skill/report-dibao/SKILL.md +60 -0
  121. package/agent-pack/assets/skill/report-writing/SKILL.md +103 -0
  122. package/agent-pack/assets/skill/resource-dispatch-intelligence/SKILL.md +125 -0
  123. package/agent-pack/assets/skill/standard-reference/SKILL.md +101 -0
  124. package/agent-pack/assets/skill/weekly-work-intelligence/SKILL.md +123 -0
  125. package/agent-pack/assets/template/adjustment-trend.json +53 -0
  126. package/agent-pack/assets/template/bid-technical-proposal.json +42 -0
  127. package/agent-pack/assets/template/compliance-review.json +35 -0
  128. package/agent-pack/assets/template/daily-monitor-report.json +34 -0
  129. package/agent-pack/assets/template/field-data-qa.json +47 -0
  130. package/agent-pack/assets/template/monitoring-plan.json +28 -0
  131. package/agent-pack/assets/template/monthly-monitor-report.json +47 -0
  132. package/agent-pack/assets/template/project-ppt.json +47 -0
  133. package/agent-pack/assets/template/review-response.json +28 -0
  134. package/agent-pack/assets/template/schema.json +72 -0
  135. package/agent-pack/assets/template/weekly-monitor-report.json +33 -0
  136. package/agent-pack/assets/theme/mytheme.json +223 -0
  137. package/agent-pack/assets/tool/angle_convert.ts +151 -0
  138. package/agent-pack/assets/tool/axial_force.ts +186 -0
  139. package/agent-pack/assets/tool/chart_generator.ts +185 -0
  140. package/agent-pack/assets/tool/control_network.ts +413 -0
  141. package/agent-pack/assets/tool/coord_transform.ts +333 -0
  142. package/agent-pack/assets/tool/cpiii_adjustment.ts +446 -0
  143. package/agent-pack/assets/tool/cross_section.ts +356 -0
  144. package/agent-pack/assets/tool/deformation_rate.ts +234 -0
  145. package/agent-pack/assets/tool/distance_calculator.ts +239 -0
  146. package/agent-pack/assets/tool/excel_export.ts +494 -0
  147. package/agent-pack/assets/tool/format_parser.ts +181 -0
  148. package/agent-pack/assets/tool/github-pr-search.ts +57 -0
  149. package/agent-pack/assets/tool/github-pr-search.txt +10 -0
  150. package/agent-pack/assets/tool/github-triage.ts +113 -0
  151. package/agent-pack/assets/tool/github-triage.txt +6 -0
  152. package/agent-pack/assets/tool/inclinometer.ts +248 -0
  153. package/agent-pack/assets/tool/monitoring_csv.ts +120 -0
  154. package/agent-pack/assets/tool/os_contract_query.ts +63 -0
  155. package/agent-pack/assets/tool/os_dibao_project_files.ts +75 -0
  156. package/agent-pack/assets/tool/os_file_download_ref.ts +48 -0
  157. package/agent-pack/assets/tool/os_file_preview.ts +46 -0
  158. package/agent-pack/assets/tool/os_gbrain_think.ts +31 -0
  159. package/agent-pack/assets/tool/os_ppt_generate.ts +37 -0
  160. package/agent-pack/assets/tool/os_project_context.ts +24 -0
  161. package/agent-pack/assets/tool/os_report_publish.ts +28 -0
  162. package/agent-pack/assets/tool/os_wiki_ingest.ts +38 -0
  163. package/agent-pack/assets/tool/os_wiki_query.ts +26 -0
  164. package/agent-pack/assets/tool/pile_stakeout.ts +299 -0
  165. package/agent-pack/assets/tool/report_export.ts +279 -0
  166. package/agent-pack/assets/tool/shield_guidance.ts +311 -0
  167. package/agent-pack/assets/tool/standard_query.ts +391 -0
  168. package/agent-pack/assets/tool/survey_calculator.ts +415 -0
  169. package/agent-pack/assets/tool/water_level.ts +209 -0
  170. package/agent-pack/bin/install.js +183 -0
  171. package/agent-pack/package.json +695 -0
  172. package/package.json +14 -8
  173. package/postinstall.mjs +53 -22
@@ -0,0 +1,279 @@
1
+ /// <reference path="../env.d.ts" />
2
+ import { tool } from "nb-railwise/tool"
3
+ import { deflateRawSync } from "node:zlib"
4
+ import path from "path"
5
+
6
+ // ============================================================
7
+ // Minimal ZIP builder (DOCX = ZIP of XML files)
8
+ // ============================================================
9
+
10
+ function crc32(buf: Uint8Array) {
11
+ let c = 0xffffffff
12
+ for (let i = 0; i < buf.length; i++) {
13
+ c ^= buf[i]!
14
+ for (let j = 0; j < 8; j++) c = (c >>> 1) ^ (c & 1 ? 0xedb88320 : 0)
15
+ }
16
+ return (c ^ 0xffffffff) >>> 0
17
+ }
18
+
19
+ function zip(files: Array<{ name: string; data: Uint8Array }>) {
20
+ const entries: Array<{
21
+ name: Uint8Array
22
+ compressed: Uint8Array
23
+ crc: number
24
+ size: number
25
+ csize: number
26
+ offset: number
27
+ }> = []
28
+ const parts: Uint8Array[] = []
29
+ let offset = 0
30
+
31
+ for (const f of files) {
32
+ const nameBytes = new TextEncoder().encode(f.name)
33
+ const crc = crc32(f.data)
34
+ const compressed = new Uint8Array(deflateRawSync(f.data))
35
+ const header = new Uint8Array(30 + nameBytes.length)
36
+ const v = new DataView(header.buffer)
37
+ v.setUint32(0, 0x04034b50, true)
38
+ v.setUint16(4, 20, true)
39
+ v.setUint16(8, 8, true)
40
+ v.setUint32(14, crc, true)
41
+ v.setUint32(18, compressed.length, true)
42
+ v.setUint32(22, f.data.length, true)
43
+ v.setUint16(26, nameBytes.length, true)
44
+ header.set(nameBytes, 30)
45
+
46
+ entries.push({ name: nameBytes, compressed, crc, size: f.data.length, csize: compressed.length, offset })
47
+ parts.push(header, compressed)
48
+ offset += header.length + compressed.length
49
+ }
50
+
51
+ const cdStart = offset
52
+ for (const e of entries) {
53
+ const cd = new Uint8Array(46 + e.name.length)
54
+ const v = new DataView(cd.buffer)
55
+ v.setUint32(0, 0x02014b50, true)
56
+ v.setUint16(4, 20, true)
57
+ v.setUint16(6, 20, true)
58
+ v.setUint16(10, 8, true)
59
+ v.setUint32(16, e.crc, true)
60
+ v.setUint32(20, e.csize, true)
61
+ v.setUint32(24, e.size, true)
62
+ v.setUint16(28, e.name.length, true)
63
+ v.setUint32(42, e.offset, true)
64
+ cd.set(e.name, 46)
65
+ parts.push(cd)
66
+ offset += cd.length
67
+ }
68
+
69
+ const eocd = new Uint8Array(22)
70
+ const ev = new DataView(eocd.buffer)
71
+ ev.setUint32(0, 0x06054b50, true)
72
+ ev.setUint16(8, entries.length, true)
73
+ ev.setUint16(10, entries.length, true)
74
+ ev.setUint32(12, offset - cdStart, true)
75
+ ev.setUint32(16, cdStart, true)
76
+ parts.push(eocd)
77
+
78
+ let total = 0
79
+ for (const p of parts) total += p.length
80
+ const result = new Uint8Array(total)
81
+ let pos = 0
82
+ for (const p of parts) {
83
+ result.set(p, pos)
84
+ pos += p.length
85
+ }
86
+ return result
87
+ }
88
+
89
+ // ============================================================
90
+ // Markdown → DOCX XML conversion
91
+ // ============================================================
92
+
93
+ function esc(s: string) {
94
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;")
95
+ }
96
+
97
+ function md2paragraphs(markdown: string) {
98
+ const lines = markdown.split("\n")
99
+ const paragraphs: string[] = []
100
+
101
+ for (const line of lines) {
102
+ const trimmed = line.trimEnd()
103
+
104
+ if (/^#{1,6}\s/.test(trimmed)) {
105
+ const level = trimmed.match(/^(#{1,6})/)?.[1]?.length ?? 1
106
+ const text = trimmed.replace(/^#{1,6}\s+/, "")
107
+ paragraphs.push(
108
+ `<w:p><w:pPr><w:pStyle w:val="Heading${level}"/></w:pPr><w:r><w:rPr><w:b/></w:rPr><w:t xml:space="preserve">${esc(text)}</w:t></w:r></w:p>`,
109
+ )
110
+ continue
111
+ }
112
+
113
+ if (/^[-*]\s/.test(trimmed)) {
114
+ const text = trimmed.replace(/^[-*]\s+/, "")
115
+ paragraphs.push(
116
+ `<w:p><w:pPr><w:pStyle w:val="ListParagraph"/><w:numPr><w:ilvl w:val="0"/><w:numId w:val="1"/></w:numPr></w:pPr><w:r><w:t xml:space="preserve">${esc(text)}</w:t></w:r></w:p>`,
117
+ )
118
+ continue
119
+ }
120
+
121
+ if (/^\d+\.\s/.test(trimmed)) {
122
+ const text = trimmed.replace(/^\d+\.\s+/, "")
123
+ paragraphs.push(
124
+ `<w:p><w:pPr><w:pStyle w:val="ListParagraph"/><w:numPr><w:ilvl w:val="0"/><w:numId w:val="2"/></w:numPr></w:pPr><w:r><w:t xml:space="preserve">${esc(text)}</w:t></w:r></w:p>`,
125
+ )
126
+ continue
127
+ }
128
+
129
+ if (/^>\s/.test(trimmed)) {
130
+ const text = trimmed.replace(/^>\s*/, "")
131
+ paragraphs.push(
132
+ `<w:p><w:pPr><w:ind w:left="720"/></w:pPr><w:r><w:rPr><w:i/></w:rPr><w:t xml:space="preserve">${esc(text)}</w:t></w:r></w:p>`,
133
+ )
134
+ continue
135
+ }
136
+
137
+ if (/^---$/.test(trimmed) || /^\*\*\*$/.test(trimmed)) {
138
+ paragraphs.push(
139
+ `<w:p><w:pPr><w:pBdr><w:bottom w:val="single" w:sz="6" w:space="1" w:color="auto"/></w:pBdr></w:pPr></w:p>`,
140
+ )
141
+ continue
142
+ }
143
+
144
+ if (trimmed === "") {
145
+ paragraphs.push(`<w:p/>`)
146
+ continue
147
+ }
148
+
149
+ let runs = ""
150
+ const parts = trimmed.split(/(\*\*[^*]+\*\*)/g)
151
+ for (const part of parts) {
152
+ if (part.startsWith("**") && part.endsWith("**")) {
153
+ const inner = part.slice(2, -2)
154
+ runs += `<w:r><w:rPr><w:b/></w:rPr><w:t xml:space="preserve">${esc(inner)}</w:t></w:r>`
155
+ } else if (part.length > 0) {
156
+ runs += `<w:r><w:t xml:space="preserve">${esc(part)}</w:t></w:r>`
157
+ }
158
+ }
159
+ paragraphs.push(`<w:p>${runs}</w:p>`)
160
+ }
161
+
162
+ return paragraphs.join("\n")
163
+ }
164
+
165
+ function buildDocx(markdown: string, title: string) {
166
+ const body = md2paragraphs(markdown)
167
+
168
+ const contentTypes = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
169
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
170
+ <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
171
+ <Default Extension="xml" ContentType="application/xml"/>
172
+ <Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
173
+ <Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>
174
+ <Override PartName="/word/numbering.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"/>
175
+ </Types>`
176
+
177
+ const rels = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
178
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
179
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
180
+ </Relationships>`
181
+
182
+ const wordRels = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
183
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
184
+ <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
185
+ <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml"/>
186
+ </Relationships>`
187
+
188
+ const document = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
189
+ <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
190
+ <w:body>
191
+ ${body}
192
+ <w:sectPr>
193
+ <w:pgSz w:w="11906" w:h="16838"/>
194
+ <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708"/>
195
+ </w:sectPr>
196
+ </w:body>
197
+ </w:document>`
198
+
199
+ const styles = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
200
+ <w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
201
+ <w:style w:type="paragraph" w:default="1" w:styleId="Normal">
202
+ <w:name w:val="Normal"/>
203
+ <w:rPr><w:rFonts w:ascii="SimSun" w:hAnsi="SimSun" w:eastAsia="SimSun"/><w:sz w:val="21"/></w:rPr>
204
+ </w:style>
205
+ <w:style w:type="paragraph" w:styleId="Heading1">
206
+ <w:name w:val="heading 1"/>
207
+ <w:pPr><w:spacing w:before="240" w:after="120"/></w:pPr>
208
+ <w:rPr><w:rFonts w:ascii="SimHei" w:hAnsi="SimHei" w:eastAsia="SimHei"/><w:b/><w:sz w:val="32"/></w:rPr>
209
+ </w:style>
210
+ <w:style w:type="paragraph" w:styleId="Heading2">
211
+ <w:name w:val="heading 2"/>
212
+ <w:pPr><w:spacing w:before="200" w:after="100"/></w:pPr>
213
+ <w:rPr><w:rFonts w:ascii="SimHei" w:hAnsi="SimHei" w:eastAsia="SimHei"/><w:b/><w:sz w:val="28"/></w:rPr>
214
+ </w:style>
215
+ <w:style w:type="paragraph" w:styleId="Heading3">
216
+ <w:name w:val="heading 3"/>
217
+ <w:pPr><w:spacing w:before="160" w:after="80"/></w:pPr>
218
+ <w:rPr><w:rFonts w:ascii="SimHei" w:hAnsi="SimHei" w:eastAsia="SimHei"/><w:b/><w:sz w:val="24"/></w:rPr>
219
+ </w:style>
220
+ <w:style w:type="paragraph" w:styleId="ListParagraph">
221
+ <w:name w:val="List Paragraph"/>
222
+ <w:pPr><w:ind w:left="720"/></w:pPr>
223
+ </w:style>
224
+ </w:styles>`
225
+
226
+ const numbering = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
227
+ <w:numbering xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
228
+ <w:abstractNum w:abstractNumId="0">
229
+ <w:lvl w:ilvl="0"><w:numFmt w:val="bullet"/><w:lvlText w:val="•"/><w:pPr><w:ind w:left="720" w:hanging="360"/></w:pPr></w:lvl>
230
+ </w:abstractNum>
231
+ <w:abstractNum w:abstractNumId="1">
232
+ <w:lvl w:ilvl="0"><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/><w:pPr><w:ind w:left="720" w:hanging="360"/></w:pPr></w:lvl>
233
+ </w:abstractNum>
234
+ <w:num w:numId="1"><w:abstractNumId w:val="0"/></w:num>
235
+ <w:num w:numId="2"><w:abstractNumId w:val="1"/></w:num>
236
+ </w:numbering>`
237
+
238
+ const enc = (s: string) => new TextEncoder().encode(s)
239
+
240
+ return zip([
241
+ { name: "[Content_Types].xml", data: enc(contentTypes) },
242
+ { name: "_rels/.rels", data: enc(rels) },
243
+ { name: "word/_rels/document.xml.rels", data: enc(wordRels) },
244
+ { name: "word/document.xml", data: enc(document) },
245
+ { name: "word/styles.xml", data: enc(styles) },
246
+ { name: "word/numbering.xml", data: enc(numbering) },
247
+ ])
248
+ }
249
+
250
+ export default tool({
251
+ description:
252
+ "将 Markdown 格式的监测报告转换为 .docx(Word)文件。technical_writer 完成报告编制后,调用此工具导出正式 Word 文件,可直接提交给业主或监理。支持标题层级、加粗、列表、引用块。",
253
+ args: {
254
+ markdown: tool.schema.string().describe("Markdown 格式的报告正文"),
255
+ title: tool.schema.string().default("监测报告").describe("文档标题(用于文件名)"),
256
+ outputPath: tool.schema.string().optional().describe("输出 .docx 文件路径,默认为 ./[title].docx"),
257
+ },
258
+ async execute(args) {
259
+ const docxBytes = buildDocx(args.markdown, args.title)
260
+ const dest = args.outputPath ?? `./${args.title.replace(/[/\\:*?"<>|]/g, "_")}.docx`
261
+
262
+ await Bun.write(dest, docxBytes)
263
+
264
+ const stats = {
265
+ paragraphs: (args.markdown.match(/\n/g)?.length ?? 0) + 1,
266
+ chars: args.markdown.length,
267
+ headings: (args.markdown.match(/^#{1,6}\s/gm) ?? []).length,
268
+ lists: (args.markdown.match(/^(?:[-*]\s|\d+\.\s)/gm) ?? []).length,
269
+ }
270
+
271
+ return JSON.stringify({
272
+ output_path: dest,
273
+ file_size_kb: Number((docxBytes.length / 1024).toFixed(1)),
274
+ format: "docx (Office Open XML)",
275
+ content_stats: stats,
276
+ message: `✅ 报告已导出为 Word 文件:${dest}(${(docxBytes.length / 1024).toFixed(1)} KB),包含 ${stats.headings} 个标题、${stats.paragraphs} 个段落。`,
277
+ })
278
+ },
279
+ })
@@ -0,0 +1,311 @@
1
+ /// <reference path="../env.d.ts" />
2
+ import { tool } from "nb-railwise/tool"
3
+
4
+ const deg2rad = (d: number) => (d * Math.PI) / 180
5
+ const rad2deg = (r: number) => (r * 180) / Math.PI
6
+
7
+ export const shield_position = tool({
8
+ description:
9
+ "盾构机姿态计算。根据盾构机头部和尾部的实测坐标,计算盾构机当前中心坐标、方位角、俯仰角、滚转角,与设计轴线对比计算偏差。盾构导向测量的核心计算工具。data_analyst 处理盾构导向数据时必须调用此工具。",
10
+ args: {
11
+ ringNumber: tool.schema.number().int().positive().describe("当前环号"),
12
+ chainage: tool.schema.string().optional().describe("当前里程,如 K5+123.456"),
13
+ headPosition: tool.schema
14
+ .object({
15
+ x: tool.schema.number().describe("盾头中心X坐标(m)"),
16
+ y: tool.schema.number().describe("盾头中心Y坐标(m)"),
17
+ z: tool.schema.number().describe("盾头中心高程(m)"),
18
+ })
19
+ .describe("盾构机头部测量坐标"),
20
+ tailPosition: tool.schema
21
+ .object({
22
+ x: tool.schema.number().describe("盾尾中心X坐标(m)"),
23
+ y: tool.schema.number().describe("盾尾中心Y坐标(m)"),
24
+ z: tool.schema.number().describe("盾尾中心高程(m)"),
25
+ })
26
+ .describe("盾构机尾部测量坐标"),
27
+ designAxis: tool.schema
28
+ .object({
29
+ x: tool.schema.number().describe("设计轴线该里程处X坐标(m)"),
30
+ y: tool.schema.number().describe("设计轴线该里程处Y坐标(m)"),
31
+ z: tool.schema.number().describe("设计轴线该里程处高程(m)"),
32
+ azimuth: tool.schema.number().describe("设计方位角(度)"),
33
+ grade: tool.schema.number().describe("设计纵坡(‰)"),
34
+ })
35
+ .describe("设计轴线参数"),
36
+ shieldLength: tool.schema.number().positive().default(8.7).describe("盾构机总长(m),默认8.7m"),
37
+ horizontalLimit: tool.schema.number().positive().default(50).describe("水平偏差报警值(mm)"),
38
+ verticalLimit: tool.schema.number().positive().default(50).describe("垂直偏差报警值(mm)"),
39
+ },
40
+ async execute(args) {
41
+ const head = args.headPosition
42
+ const tail = args.tailPosition
43
+
44
+ // Shield center = midpoint of head and tail
45
+ const center = {
46
+ x: (head.x + tail.x) / 2,
47
+ y: (head.y + tail.y) / 2,
48
+ z: (head.z + tail.z) / 2,
49
+ }
50
+
51
+ // Shield azimuth (horizontal plane)
52
+ const dx = head.x - tail.x
53
+ const dy = head.y - tail.y
54
+ const dz = head.z - tail.z
55
+ const horizontalDist = Math.sqrt(dx * dx + dy * dy)
56
+ const shieldAzimuth = ((Math.atan2(dx, dy) * 180) / Math.PI + 360) % 360
57
+
58
+ // Pitch angle (vertical plane, positive = upward)
59
+ const pitchAngle = (Math.atan2(dz, horizontalDist) * 180) / Math.PI
60
+
61
+ // Shield grade in ‰
62
+ const shieldGrade = horizontalDist > 0 ? (dz / horizontalDist) * 1000 : 0
63
+
64
+ // Deviations from design axis
65
+ const da = args.designAxis
66
+ const designAzRad = deg2rad(da.azimuth)
67
+
68
+ // Horizontal deviation: perpendicular distance from center to design line
69
+ const relX = center.x - da.x
70
+ const relY = center.y - da.y
71
+ const horizontalDev = (relX * Math.cos(designAzRad) - relY * Math.sin(designAzRad)) * 1000
72
+
73
+ // Vertical deviation
74
+ const verticalDev = (center.z - da.z) * 1000
75
+
76
+ // Azimuth deviation
77
+ let azimuthDev = shieldAzimuth - da.azimuth
78
+ if (azimuthDev > 180) azimuthDev -= 360
79
+ if (azimuthDev < -180) azimuthDev += 360
80
+
81
+ // Grade deviation
82
+ const gradeDev = shieldGrade - da.grade
83
+
84
+ // Head deviations (for trend analysis)
85
+ const headRelX = head.x - da.x
86
+ const headRelY = head.y - da.y
87
+ const headHDev = (headRelX * Math.cos(designAzRad) - headRelY * Math.sin(designAzRad)) * 1000
88
+ const headVDev = (head.z - da.z) * 1000
89
+
90
+ // Tail deviations
91
+ const tailRelX = tail.x - da.x
92
+ const tailRelY = tail.y - da.y
93
+ const tailHDev = (tailRelX * Math.cos(designAzRad) - tailRelY * Math.sin(designAzRad)) * 1000
94
+ const tailVDev = (tail.z - da.z) * 1000
95
+
96
+ // Trend: if head deviates more than tail, shield is moving away from axis
97
+ const hTrend = Math.abs(headHDev) > Math.abs(tailHDev) ? "偏离" : "回归"
98
+ const vTrend = Math.abs(headVDev) > Math.abs(tailVDev) ? "偏离" : "回归"
99
+
100
+ let hStatus = "🟢 正常"
101
+ if (Math.abs(horizontalDev) >= args.horizontalLimit) hStatus = "🔴 超限"
102
+ else if (Math.abs(horizontalDev) >= args.horizontalLimit * 0.7) hStatus = "🟡 关注"
103
+
104
+ let vStatus = "🟢 正常"
105
+ if (Math.abs(verticalDev) >= args.verticalLimit) vStatus = "🔴 超限"
106
+ else if (Math.abs(verticalDev) >= args.verticalLimit * 0.7) vStatus = "🟡 关注"
107
+
108
+ const hDirection = horizontalDev > 0 ? "偏右" : horizontalDev < 0 ? "偏左" : "居中"
109
+ const vDirection = verticalDev > 0 ? "偏高" : verticalDev < 0 ? "偏低" : "居中"
110
+
111
+ return JSON.stringify({
112
+ ring_number: args.ringNumber,
113
+ chainage: args.chainage ?? "未指定",
114
+ shield_center: {
115
+ x: Number(center.x.toFixed(4)),
116
+ y: Number(center.y.toFixed(4)),
117
+ z: Number(center.z.toFixed(4)),
118
+ },
119
+ shield_attitude: {
120
+ azimuth_deg: Number(shieldAzimuth.toFixed(6)),
121
+ pitch_deg: Number(pitchAngle.toFixed(4)),
122
+ grade_permille: Number(shieldGrade.toFixed(2)),
123
+ },
124
+ deviation: {
125
+ horizontal_mm: Number(horizontalDev.toFixed(1)),
126
+ horizontal_direction: hDirection,
127
+ horizontal_status: hStatus,
128
+ vertical_mm: Number(verticalDev.toFixed(1)),
129
+ vertical_direction: vDirection,
130
+ vertical_status: vStatus,
131
+ azimuth_deviation_deg: Number(azimuthDev.toFixed(4)),
132
+ grade_deviation_permille: Number(gradeDev.toFixed(2)),
133
+ },
134
+ head_deviation: {
135
+ horizontal_mm: Number(headHDev.toFixed(1)),
136
+ vertical_mm: Number(headVDev.toFixed(1)),
137
+ },
138
+ tail_deviation: {
139
+ horizontal_mm: Number(tailHDev.toFixed(1)),
140
+ vertical_mm: Number(tailVDev.toFixed(1)),
141
+ },
142
+ trend: {
143
+ horizontal: hTrend,
144
+ vertical: vTrend,
145
+ },
146
+ message: `✅ 第${args.ringNumber}环姿态:水平${hDirection} ${Math.abs(horizontalDev).toFixed(1)}mm(${hStatus}),垂直${vDirection} ${Math.abs(verticalDev).toFixed(1)}mm(${vStatus}),趋势:水平${hTrend}、垂直${vTrend}`,
147
+ })
148
+ },
149
+ })
150
+
151
+ export const shield_trend = tool({
152
+ description: "盾构掘进偏差趋势分析。输入多环的偏差数据,分析偏差发展趋势,预测未来偏差,为纠偏决策提供依据。",
153
+ args: {
154
+ records: tool.schema
155
+ .array(
156
+ tool.schema.object({
157
+ ring: tool.schema.number().int().positive().describe("环号"),
158
+ horizontalDev: tool.schema.number().describe("水平偏差(mm),正=偏右"),
159
+ verticalDev: tool.schema.number().describe("垂直偏差(mm),正=偏高"),
160
+ }),
161
+ )
162
+ .min(3)
163
+ .describe("多环偏差数据,按环号排列"),
164
+ horizontalLimit: tool.schema.number().positive().default(50).describe("水平限值(mm)"),
165
+ verticalLimit: tool.schema.number().positive().default(50).describe("垂直限值(mm)"),
166
+ predictionRings: tool.schema.number().int().positive().default(10).describe("预测环数"),
167
+ },
168
+ async execute(args) {
169
+ const n = args.records.length
170
+ const rings = args.records.map((r) => r.ring)
171
+ const hDevs = args.records.map((r) => r.horizontalDev)
172
+ const vDevs = args.records.map((r) => r.verticalDev)
173
+
174
+ function linReg(x: number[], y: number[]) {
175
+ const mx = x.reduce((s, v) => s + v, 0) / n
176
+ const my = y.reduce((s, v) => s + v, 0) / n
177
+ const sxy = x.reduce((s, v, i) => s + (v - mx) * (y[i]! - my), 0)
178
+ const sxx = x.reduce((s, v) => s + (v - mx) * (v - mx), 0)
179
+ const b = sxx > 0 ? sxy / sxx : 0
180
+ const a = my - b * mx
181
+ return { a, b }
182
+ }
183
+
184
+ const hReg = linReg(rings, hDevs)
185
+ const vReg = linReg(rings, vDevs)
186
+
187
+ const lastRing = rings[n - 1]!
188
+ const hPredictions = Array.from({ length: args.predictionRings }, (_, i) => {
189
+ const r = lastRing + i + 1
190
+ return { ring: r, predicted_mm: Number((hReg.a + hReg.b * r).toFixed(1)) }
191
+ })
192
+ const vPredictions = Array.from({ length: args.predictionRings }, (_, i) => {
193
+ const r = lastRing + i + 1
194
+ return { ring: r, predicted_mm: Number((vReg.a + vReg.b * r).toFixed(1)) }
195
+ })
196
+
197
+ // Rings until exceeding limit
198
+ const hRingsToLimit =
199
+ hReg.b !== 0 ? Math.ceil((args.horizontalLimit * Math.sign(hReg.b) - hReg.a) / hReg.b) - lastRing : Infinity
200
+ const vRingsToLimit =
201
+ vReg.b !== 0 ? Math.ceil((args.verticalLimit * Math.sign(vReg.b) - vReg.a) / vReg.b) - lastRing : Infinity
202
+
203
+ const latestH = hDevs[n - 1]!
204
+ const latestV = vDevs[n - 1]!
205
+
206
+ // Rate per ring (last 5)
207
+ const recent = Math.min(5, n - 1)
208
+ const hRate = (hDevs[n - 1]! - hDevs[n - 1 - recent]!) / recent
209
+ const vRate = (vDevs[n - 1]! - vDevs[n - 1 - recent]!) / recent
210
+
211
+ let recommendation = ""
212
+ if (Math.abs(latestH) > args.horizontalLimit * 0.7 && Math.abs(hRate) > 1) {
213
+ recommendation += `水平方向需向${latestH > 0 ? "左" : "右"}纠偏;`
214
+ }
215
+ if (Math.abs(latestV) > args.verticalLimit * 0.7 && Math.abs(vRate) > 1) {
216
+ recommendation += `垂直方向需向${latestV > 0 ? "下" : "上"}纠偏;`
217
+ }
218
+ if (!recommendation) recommendation = "当前偏差可控,保持掘进"
219
+
220
+ return JSON.stringify({
221
+ analysis_range: `第${rings[0]}环 ~ 第${lastRing}环`,
222
+ latest: {
223
+ ring: lastRing,
224
+ horizontal_mm: latestH,
225
+ vertical_mm: latestV,
226
+ },
227
+ rate_per_ring: {
228
+ horizontal_mm: Number(hRate.toFixed(2)),
229
+ vertical_mm: Number(vRate.toFixed(2)),
230
+ },
231
+ trend: {
232
+ horizontal_slope: Number(hReg.b.toFixed(4)),
233
+ vertical_slope: Number(vReg.b.toFixed(4)),
234
+ },
235
+ horizontal_predictions: hPredictions,
236
+ vertical_predictions: vPredictions,
237
+ rings_to_horizontal_limit: hRingsToLimit > 0 && isFinite(hRingsToLimit) ? hRingsToLimit : "不会超限",
238
+ rings_to_vertical_limit: vRingsToLimit > 0 && isFinite(vRingsToLimit) ? vRingsToLimit : "不会超限",
239
+ recommendation,
240
+ message: `✅ 盾构偏差趋势(${rings[0]}~${lastRing}环):水平 ${latestH}mm(速率${hRate.toFixed(2)}mm/环),垂直 ${latestV}mm(速率${vRate.toFixed(2)}mm/环)。${recommendation}`,
241
+ })
242
+ },
243
+ })
244
+
245
+ export const shield_ring_build = tool({
246
+ description:
247
+ "管片选型与拼装角度计算。根据盾构机当前姿态偏差和设计线路曲率,推算下一环管片的旋转角(楔形量方向),辅助管片选型决策。",
248
+ args: {
249
+ ringNumber: tool.schema.number().int().positive().describe("待拼装环号"),
250
+ horizontalDev: tool.schema.number().describe("当前水平偏差(mm),正=偏右"),
251
+ verticalDev: tool.schema.number().describe("当前垂直偏差(mm),正=偏高"),
252
+ horizontalRate: tool.schema.number().describe("水平偏差速率(mm/环)"),
253
+ verticalRate: tool.schema.number().describe("垂直偏差速率(mm/环)"),
254
+ designCurveRadius: tool.schema.number().optional().describe("设计曲线半径(m),直线段不传"),
255
+ curveDirection: tool.schema.enum(["left", "right"]).optional().describe("曲线方向:left=左转, right=右转"),
256
+ wedgeAmount: tool.schema.number().positive().default(38).describe("楔形管片最大楔形量(mm),默认38mm"),
257
+ segmentTypes: tool.schema.array(tool.schema.string()).default(["A", "B", "C"]).describe("可选管片类型"),
258
+ },
259
+ async execute(args) {
260
+ // Target correction direction
261
+ const targetH = -Math.sign(args.horizontalDev + args.horizontalRate * 3)
262
+ const targetV = -Math.sign(args.verticalDev + args.verticalRate * 3)
263
+
264
+ // Rotation angle of wedge ring (0°=top, clockwise)
265
+ // Map (targetH, targetV) to angle: right correction = 90°, down = 180°, left = 270°, up = 0°
266
+ let rotationAngle = (Math.atan2(targetH, -targetV) * 180) / Math.PI
267
+ rotationAngle = ((rotationAngle % 360) + 360) % 360
268
+
269
+ // Curve compensation
270
+ let curveNote = ""
271
+ if (args.designCurveRadius && args.curveDirection) {
272
+ const curveCorrection = args.curveDirection === "left" ? 270 : 90
273
+ const blendFactor = 0.3
274
+ rotationAngle = rotationAngle * (1 - blendFactor) + curveCorrection * blendFactor
275
+ rotationAngle = ((rotationAngle % 360) + 360) % 360
276
+ curveNote = `曲线段(R=${args.designCurveRadius}m ${args.curveDirection === "left" ? "左转" : "右转"}),已叠加曲线补偿`
277
+ }
278
+
279
+ // Determine segment type
280
+ const deviationMag = Math.sqrt(args.horizontalDev ** 2 + args.verticalDev ** 2)
281
+ const rateMag = Math.sqrt(args.horizontalRate ** 2 + args.verticalRate ** 2)
282
+
283
+ let recommendedType: string
284
+ let useWedge: boolean
285
+ if (deviationMag < 20 && rateMag < 2) {
286
+ recommendedType = "标准环"
287
+ useWedge = false
288
+ } else {
289
+ recommendedType = "楔形环(纠偏)"
290
+ useWedge = true
291
+ }
292
+
293
+ return JSON.stringify({
294
+ ring_number: args.ringNumber,
295
+ current_deviation: {
296
+ horizontal_mm: args.horizontalDev,
297
+ vertical_mm: args.verticalDev,
298
+ magnitude_mm: Number(deviationMag.toFixed(1)),
299
+ },
300
+ recommendation: {
301
+ segment_type: recommendedType,
302
+ use_wedge: useWedge,
303
+ rotation_angle_deg: Number(rotationAngle.toFixed(1)),
304
+ wedge_amount_mm: useWedge ? args.wedgeAmount : 0,
305
+ correction_direction: `水平${targetH > 0 ? "向右" : "向左"}、垂直${targetV > 0 ? "向上" : "向下"}`,
306
+ },
307
+ curve_note: curveNote || undefined,
308
+ message: `✅ 第${args.ringNumber}环建议:${recommendedType},楔形量方向 ${rotationAngle.toFixed(1)}°${curveNote ? `(${curveNote})` : ""}`,
309
+ })
310
+ },
311
+ })