@archsight/aios 1.5.0 → 1.5.1

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "archsight-aios",
3
3
  "displayName": "ArchSight AIOS",
4
- "version": "1.5.0",
4
+ "version": "1.5.1",
5
5
  "description": "面向建筑行业知识工作从业者与 AI 研发团队的 Skills、Workflow 与多 Agent 工具包 / Building-industry AI agent skills for BIM, IFC, RAG, GraphRAG, project evidence work, code review, and runtime governance.",
6
6
  "author": {
7
7
  "name": "ArchSightLabs",
package/README.md CHANGED
@@ -1,55 +1,182 @@
1
- # ArchSight AIOS
2
-
3
- ArchSight AIOS 是一套面向建筑行业知识工作从业者与 AI 研发团队的规则、AgentSkill、Workflow 和项目接入工具包。它重点服务 BIM / IFC / Revit / CAD、施工视觉 AI、建筑规范知识库、GraphRAG、智能审图、工程资料证据链和 AI Coding 治理,让 Codex、Claude Code、OpenCode、Antigravity 2.0、WorkBuddy 等 AI Agent 工具在同一个项目或个人 skills 目录里读取同一套规则、项目上下文和验收要求。
4
-
5
- AIOS 不是全行业项目模板集合。它保留通用的 AI 编码规则、Agent 路由、Workflow、项目 `.ai/` 上下文和交付验证能力,但真正的差异化能力集中在建筑行业语义、工程证据链、规范知识工程、Capability 工具证据和可复核的 AI 研发流程。
1
+ # ArchSight AIOS
2
+
3
+ ArchSight AIOS 是面向建筑行业的开源 AI 技能包与工程知识治理工具包。它让 WorkBuddy、Codex、Claude Code、OpenCode、Gemini、Antigravity 等 AI 工具可以使用同一组建筑行业 Skills、Workflows、Templates Runtime 规则。
4
+
5
+ AIOS 不是从研发工具转成业务资料工具,而是在保留建筑 AI / 软件研发治理能力的基础上,扩展到建筑行业知识工作从业者。现在它同时覆盖两套并列能力:
6
+
7
+ - **建筑工程资料与知识工作技能包**:处理工程资料、技术标、合同履约、施工日报、工程会议、变更签证、专项施工方案、规范摘录和知识包治理。
8
+ - **建筑 AI / 软件研发治理技能包**:支持一把手评审、架构评审、产品与界面方案评审、交付规划、代码审查、Runtime 设计、RAG / GraphRAG、MCP / Tool Calling、Capability 证据仲裁和受控执行。
6
9
 
7
- 工程业务管理 Skill 只作为建筑工程资料治理的增强包,用于招投标、合同履约、施工日报、工程会议、变更签证和专项施工方案的证据链整理、风险提示和人工复核分流。它不是通用 HR、行政、财务或法律咨询 Prompt 集合;涉及工程款、合同法务、证照、人事和组织协同时,只做工程场景内的资料整理、风险标注和人工复核分流,不替代法务、造价、财务、监理、安全、项目经理、总工、HR 或专家签审。
10
+ AIOS 的目标不是让 AI 替代专业人员做最终判断,而是帮助使用者把工程资料和行业知识整理成可复核的清单、台账、初稿、证据链、Knowledge Pack 和人工复核事项。它强调资料来源、版本、页码、章节、适用条件、风险提示和人工复核岗位,避免把模型推断误当成工程结论。
11
+
12
+ v1.5.0 开始,AIOS 的主线从“能写工程文档”推进到“能治理工程知识”:除了标书、方案、日报、会议纪要等写作与复核型 Skill,也提供 Knowledge Pack 工作台和本地 Reference Runtime,把规范摘录、企业标准、项目资料、历史审查口径和人工复核记录治理为可编译、可查询、可评估的工程知识资产。
8
13
 
9
14
  ## 设计目标
10
-
11
- AIOS 的目标不是替代 Codex、Claude Code 或 Gemini 自带的通用工程能力,而是让它们在建筑行业平台研发中做出更专业的判断。它面向建筑行业架构师、博士 / 研究型团队和后端开发,把通用架构评审补足为面向 BIM / IFC、建筑规范、审图链路、知识库、RAG / GraphRAG、任务编排、审计证据和长期平台演进的工作方法。
12
-
13
- 没有 `.ai/` 目录时,AIOS Skill 仍应可直接使用:优先读取代码、接口、schema、配置、测试和部署入口;只有 `.ai/profile-detection.md`、项目显式 profile 或任务本身涉及建筑行业语义时,才加载 BIM、IFC、规范知识或智能审图假设。
14
-
15
- AIOS 是建筑行业增强层,不是通用任务替代器。装了 AIOS 后,建筑行业相关任务应得到更专业的证据、边界、验证和行业判断;普通非建筑任务不应被强行套用 BIM、IFC、规范、审图或工程证据链假设,必要时直接使用宿主工具的通用能力。
16
-
17
- ## 适合谁
18
-
19
- | 角色 | 可以用它做什么 |
20
- | --- | --- |
21
- | 建筑行业架构师 | 评估平台边界、BIM / IFC 数据链路、规范知识工程、审图流程和长期演进风险。 |
22
- | 博士 / 研究型团队 | 把算法、RAG / GraphRAG、评估集、实验假设和工程验收连接到可复核的研发流程。 |
23
- | 后端开发 | 拆清服务边界、任务队列、文件处理、审计日志、索引版本、缓存和多实例运行风险。 |
24
- | 业务专家 | 沉淀规范条文、审查口径、工程术语、样例和人工复核点。 |
25
- | 产品 / 项目 / 设计负责人 | 把业务目标、页面任务、工作台体验、验收标准和 AI 协作流程写进项目规则。 |
26
- | 企业负责人 / 业务一把手 | 用 `aios-ceo` 深度评价建筑行业软件 / 系统的产品定位、行业专业性、工程可信度、证据链、商业验证、阶段路线和停损信号。 |
27
- | AI / 软件工程师 | 给建筑 AI 项目接入统一 AI 编码规则、Skills、Workflows 和行业 profile。 |
28
- | 团队负责人 | 统一多工具、多模型、多 Agent 的工作边界和交付检查方式;用 `aios-compare` 比较两份文档 / AI 输出哪份更专业,用内部 `aios-prompt-compare` 判断提示词是否值得沉淀为正式 Skill。 |
29
-
30
- ## 解决什么问题
31
-
32
- - 不同 AI 工具各读各的规则,导致输出风格和边界不一致。
33
- - 项目里缺少明确的 `.ai/` 上下文目录,AI 不知道行业知识、验收标准和人工复核点。
34
- - 建筑行业项目涉及规范、BIM、图纸、模型、施工现场、知识库和 AI 检测,容易把模型推断误当成工程结论;AIOS 默认内置 profile registry,并通过自动识别结果和任务上下文启用行业规则,而不是让用户先手动合并规则文件。
35
- - AI 生成代码、文档或规则后,缺少统一的 review、验证和发布检查路径。
36
- - 普通文档对比和 Prompt 测试容易混在一起;`aios-compare` 面向用户比较两份文档或两个 AI 输出哪份更专业,`aios-prompt-compare` 作为内部测试工具,用同一输入做 weak / portable / skill-runtime 三栏对照,帮助团队判断哪些能力应沉淀为 Skill。
37
-
38
- ## 三步开始
39
-
40
- ```bash
41
- npx @archsight/aios install --target all --scope user
42
- npx @archsight/aios doctor
43
-
44
- cd /path/to/your-project
45
- npx @archsight/aios init
46
- ```
47
-
15
+
16
+ AIOS 的设计目标有五个:
17
+
18
+ 1. 让建筑 AI / 软件研发更有边界:把产品定位、架构、界面方案、交付计划、代码审查和 Runtime 设计放进可复核的工作流。
19
+ 2. 让研发团队有可验证的 Runtime 路径:涉及规范、结构计算、RAG / GraphRAG、Tool Calling 和多 Agent 协作时,优先回到项目事实、结构化知识和确定性工具证据。
20
+ 3. 让建筑行业资料工作更可复核:把标书、合同、日报、会议、变更签证和施工方案整理成有来源、有缺口、有风险、有复核岗位的工作底稿。
21
+ 4. 让工程知识可以治理:把规范摘录、企业标准、审查口径和项目经验沉淀为 Knowledge Pack,而不是散落在聊天记录和临时 Prompt 中。
22
+ 5. 让多种 AI 工具保持一致边界:同一套 Skill、Workflow 和项目规则可安装到 WorkBuddy、Codex、Claude Code、OpenCode、Gemini、Antigravity 等工具。
23
+
24
+ AIOS 是建筑行业增强层,不是通用任务替代器。普通非建筑任务不应被强行套用 BIM、IFC、规范、审图或工程证据链假设;涉及法务、造价、财务、监理、安全、项目经理、总工、专家或注册人员签审时,AIOS 只做资料整理、风险标注和人工复核分流。
25
+
26
+ ## 适合谁
27
+
28
+ AIOS 现在面向两类用户。第一类是建筑 AI / 软件研发团队,负责把行业能力做成可信系统;第二类是建筑行业知识工作从业者,负责把真实工程资料和经验转成可复核的工作底稿和知识资产。
29
+
30
+ ### 建筑 AI / 软件研发治理
31
+
32
+ | 角色 | 可以用它做什么 |
33
+ | --- | --- |
34
+ | 建筑行业软件 / AI 产品负责人 | 用 `aios-ceo`、`aios-design` 和 `aios-plan` 评估产品定位、行业专业性、工作台体验、交付路线和停损信号。 |
35
+ | 架构师 / 后端 / AI 工程师 | 用 `aios-arch`、`aios-runtime`、`aios-structural` 和 `aios-exec` 评估服务边界、数据链路、Runtime、RAG / GraphRAG、结构计算工具链和受控执行。 |
36
+ | 代码审查 / 质量负责人 | 用 `aios-review` 审查 diff、PR、AI 生成代码、安全敏感改动、Prompt / Tool / Runtime 变更、测试缺口和发布准备度。 |
37
+ | 建筑数字化 / AI 应用团队 | 把行业知识、评估样例、RAG / GraphRAG、Tool Calling 和多 Agent 流程纳入可验证的工程链路。 |
38
+ | 企业负责人 / 研发负责人 | 统一多工具、多模型、多 Agent 的研发边界和交付检查方式,评估 AIOS 在团队中的使用范围、投入顺序和风险边界。 |
39
+
40
+ ### 建筑工程资料与知识工作
41
+
42
+ | 角色 | 可以用它做什么 |
43
+ | --- | --- |
44
+ | 投标 / 技术标人员 | 复核招标文件、评分办法、资格条件和技术标要求,生成响应矩阵、资料缺口、废标风险和技术标章节初稿。 |
45
+ | 方案编制人员 / 技术负责人 | 复核专项施工方案、危险源、交底要点、专家意见和计算书缺口,生成方案章节或交底材料草稿。 |
46
+ | 项目资料员 / 项目管理人员 | 整理施工日报、工程会议纪要、待办闭环、现场问题和可追踪台账。 |
47
+ | 合同履约 / 商务人员 | 整理合同条款、履约节点、付款条件、变更签证资料链和责任边界线索。 |
48
+ | 业务专家 / 企业标准维护者 | 沉淀规范摘录、企业标准、审查口径、工程术语、样例和人工复核点,形成 Knowledge Pack。 |
49
+
50
+ ## 解决什么问题
51
+
52
+ - AI 输出只有泛泛总结,缺少资料来源、页码、章节、条款位置和人工复核岗位。
53
+ - 标书、方案、合同、日报、会议纪要和变更签证资料散落,难以形成可继续工作的矩阵、清单、台账和初稿。
54
+ - 规范摘录、企业标准、历史审查口径和项目经验沉淀在个人经验或临时文档里,难以查询、评估和复用。
55
+ - 不同 AI 工具各读各的规则,导致输出格式、风险边界和交付检查方式不一致。
56
+ - 建筑行业任务容易把模型推断误当成工程结论,需要默认保留“需核验 / 转人工复核 / 不得下结论”的边界。
57
+ - 建筑 AI / 软件团队在做产品定位、架构设计、BIM / IFC、智能审图、RAG / GraphRAG、结构计算或 Runtime 接入时,缺少统一的评审、证据仲裁和发布验证路径。
58
+
59
+ ## 快速开始
60
+
61
+ ### 只想先试用技能包
62
+
63
+ 如果只是想在 WorkBuddy 中试用标书、合同、日报、会议纪要或施工方案相关技能,优先使用:
64
+
65
+ ```bash
66
+ npx @archsight/aios@latest install --target workbuddy --scope user
67
+ ```
68
+
69
+ 安装后可检查:
70
+
71
+ ```bash
72
+ npx @archsight/aios@latest doctor
73
+ ```
74
+
75
+ 打开 WorkBuddy 后,可以先试下面几类指令:
76
+
77
+ 研发治理类:
78
+
79
+ ```text
80
+ $aios-ceo 请从一把手视角评估这个建筑行业 AI 产品的定位、行业专业性、工程可信度、证据链、商业验证、阶段路线和停损信号。
81
+ ```
82
+
83
+ ```text
84
+ $aios-arch 请评审以下建筑 AI 系统方案的服务边界、数据链路、模型 / Runtime 边界、GraphRAG 架构、Agent 工作流治理和长期复杂度风险。
85
+ ```
86
+
87
+ ```text
88
+ $aios-review 请审查以下 diff 或 PR,重点看 AI 生成代码风险、安全敏感改动、Prompt / Tool / Runtime 变更、测试缺口和发布准备度。
89
+ ```
90
+
91
+ 工程资料类:
92
+
93
+ ```text
94
+ $aios-tender-audit 请复核以下技术标资料,输出评分点响应矩阵、废标风险、资料缺口和人工复核岗位。
95
+ ```
96
+
97
+ ```text
98
+ $aios-scheme-audit 请复核以下专项施工方案,输出危险源、交底要点、计算书缺口、专家意见回查和人工复核岗位。
99
+ ```
100
+
101
+ ```text
102
+ $aios-daily-write 请基于以下现场口述、项目群记录或照片说明,生成施工日报 Markdown 草稿,并保留资料来源、待补资料和审核门禁。
103
+ ```
104
+
105
+ 面向建筑行业业务人员的完整自助说明见 [建筑行业技能包自助试用指南](docs/industry-user-trial-guide.md)。
106
+
107
+ ### 需要安装到多个 AI 工具
108
+
109
+ ```bash
110
+ npx @archsight/aios@latest install --target all --scope user
111
+ npx @archsight/aios@latest doctor
112
+ ```
113
+
114
+ 这会把 AIOS 的 Skills、Workflows、Runtime 和模板安装到当前用户目录,让 Codex、Claude Code、OpenCode、Gemini、Antigravity、WorkBuddy 等工具可以读取。
115
+
116
+ ### 需要给项目接入 AIOS 治理
117
+
118
+ ```bash
119
+ cd /path/to/your-project
120
+ npx @archsight/aios@latest init
121
+ ```
122
+
48
123
  执行后,当前业务项目会获得统一的 AI 入口文件和 `.ai/` 项目治理目录。已有 `AGENTS.md`、`CLAUDE.md`、`GEMINI.md`、`OPENCODE.md` 或 `AI_CODING_RULES.md` 的项目不会被覆盖;CLI 会补充缺失文件,并在合适的位置追加 ArchSight AIOS 引用。
49
124
 
50
125
  `init` 默认会读取项目名、README、package / pyproject 和浅层文件名,自动生成 `.ai/profile-detection.md`,并在首次创建 `.ai/project-context.md` 时预填项目名、技术栈、常用命令、代码结构和候选 AIOS 能力。用户不需要先理解 profile,也不需要手动合并 AI 规则文件。
51
-
52
- 如果你不写代码,只参与业务判断,可以先看 [建筑行业技能包自助试用指南](docs/industry-user-trial-guide.md) 和 [业务专家指南](docs/business-expert-guide.md)。如果你需要一步一步安装和验证,可以看 [快速上手](docs/quickstart.md)。
126
+
127
+ 如果你需要一步一步安装和验证,可以看 [快速上手](docs/quickstart.md)。
128
+
129
+ ## 核心能力
130
+
131
+ | 能力 | 说明 |
132
+ | --- | --- |
133
+ | 工程资料技能包 | 覆盖招投标、合同履约、施工日报、工程会议、变更签证和专项施工方案,输出清单、矩阵、台账、初稿和人工复核事项。 |
134
+ | 工程文档写作工作台 | 用 Markdown 工作母版组织标书、技术标和施工方案的资料来源、历史素材、写作 brief、草稿、复核记录和人工定稿。 |
135
+ | Knowledge Pack | 把规范摘录、企业标准、项目资料、审查口径和复核记录治理为可编译、可查询、可评估的工程知识资产。 |
136
+ | 本地 Reference Runtime | 通过 `knowledge.norm_lookup` 查询编译后的 Knowledge Pack,返回引用、版本、适用性、冲突和仲裁状态。 |
137
+ | 建筑 AI / 软件研发治理 | 覆盖 `aios-ceo`、`aios-arch`、`aios-design`、`aios-plan`、`aios-review`、`aios-runtime`、`aios-exec` 等研发评审和执行入口。 |
138
+ | 多工具安装与公共发现 | 支持 WorkBuddy、Codex、Claude Code、OpenCode、Gemini、Antigravity、`npx skills` 等工具发现和安装。 |
139
+ | Capability 证据仲裁 | 对规范、结构计算、工具调用和多 Agent 冲突保留 `Claim / Evidence / Tool Result / Decision`,避免无证据结论。 |
140
+
141
+ ## 常用技能入口
142
+
143
+ ### 工程资料与知识工作
144
+
145
+ | 场景 | 推荐入口 |
146
+ | --- | --- |
147
+ | 招投标未区分写作或审核 | `aios-tender` |
148
+ | 技术标 / 招标文件复核 | `aios-tender-audit`,已培训旧命令的团队可继续使用 `aios-commercial-tender` |
149
+ | 技术标章节生成或改写 | `aios-tender-write` |
150
+ | 合同履约复核 | `aios-contract-audit`,已培训旧命令的团队可继续使用 `aios-commercial-contract` |
151
+ | 合同条款、补充协议或履约函件草拟 | `aios-contract-draft` |
152
+ | 施工日报未区分生成或复核 | `aios-daily` |
153
+ | 施工日报生成 | `aios-daily-write` |
154
+ | 施工日报复核和问题台账 | `aios-construction-daily` |
155
+ | 工程会议未区分生成或复核 | `aios-meeting` |
156
+ | 工程会议纪要生成 | `aios-meeting-write` |
157
+ | 工程会议纪要复核和待办闭环 | `aios-construction-meeting` |
158
+ | 专项施工方案未区分写作或审核 | `aios-scheme` |
159
+ | 专项施工方案复核 | `aios-scheme-audit`,已培训旧命令的团队可继续使用 `aios-construction-scheme` |
160
+ | 专项施工方案生成或改写 | `aios-scheme-write` |
161
+ | 规范、企业标准和知识包治理 | `aios-knowledge` |
162
+
163
+ `aios-commercial-*` 和 `aios-construction-*` 系列继续保留原有领域型入口含义,适合已经在团队培训和内部流程中使用这些命令的场景;`aios-tender*`、`aios-contract-*`、`aios-daily*`、`aios-meeting*` 和 `aios-scheme*` 是更短的任务型入口,适合新用户自助试用。
164
+
165
+ ### 建筑 AI / 软件研发治理
166
+
167
+ | 场景 | 推荐入口 |
168
+ | --- | --- |
169
+ | 企业负责人 / 一把手深度评审 | `aios-ceo` |
170
+ | 架构、服务边界、数据 / 模型 / Runtime 边界和长期复杂度 | `aios-arch` |
171
+ | 建筑行业平台界面、审图工作台、BIM Viewer、规范检索和报告复核体验 | `aios-design` |
172
+ | 功能、bug、架构决策、PR / 发布顺序和 CI/CD 交付拆解 | `aios-plan` |
173
+ | diff、PR、AI 生成代码、安全敏感改动、依赖更新和发布准备度 | `aios-review` |
174
+ | Prompt、Context、Memory、MCP 权限、RAG / GraphRAG、Embedding 和多 Agent 编排 | `aios-runtime` |
175
+ | BIM、IFC、建筑规范、审图规则、领域实体和知识图谱 schema | `aios-knowledge` |
176
+ | 结构力学、荷载、边界条件、FEM 输入输出和确定性求解链路 | `aios-structural` |
177
+ | 明确范围内的代码、文档、脚本、测试和验证执行 | `aios-exec` |
178
+ | 两份文档、两个版本或两个 AI 输出的专业度对比 | `aios-compare` |
179
+ | 内部 Prompt / Skill 回归、weak/basic/runtime 三栏评测 | `aios-prompt-compare` |
53
180
 
54
181
  ## 自动行业识别
55
182
 
@@ -16,7 +16,7 @@ const home = os.homedir();
16
16
  const managedStart = "<!-- ARCHSIGHT-AIOS:START -->";
17
17
  const managedEnd = "<!-- ARCHSIGHT-AIOS:END -->";
18
18
  const antigravityPluginName = "archsight-aios";
19
- const aiosVersion = "1.5.0";
19
+ const aiosVersion = "1.5.1";
20
20
 
21
21
  const assetDirs = [
22
22
  "skills",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archsight-aios",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "面向建筑行业知识工作从业者与 AI 研发团队的 Skills、Workflow 与多 Agent 工具包 / Building-industry AI agent skills for BIM, IFC, RAG, GraphRAG, project evidence work, code review, and runtime governance.",
5
5
  "contextFileName": "GEMINI.md"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archsight/aios",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "面向建筑行业知识工作从业者与 AI 研发团队的 Skills、Workflow 与多 Agent 工具包 / Building-industry AI agent skills for BIM, IFC, RAG, GraphRAG, project evidence work, code review, and runtime governance.",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/ArchSightLabs/archsight-aios#readme",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": 1,
3
3
  "name": "archsight-aios",
4
- "version": "1.5.0",
4
+ "version": "1.5.1",
5
5
  "description": "ArchSight AIOS 的 Agent、Skill、Workflow、Runtime 和项目模板注册表,面向建筑行业知识工作者与 AI 工程团队。",
6
6
  "agents": [
7
7
  {
@@ -2,6 +2,7 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
+ import { findSensitiveTerms, loadLocalSensitiveTerms } from "./lib/local-sensitive-terms.mjs";
5
6
 
6
7
  const root = fs.realpathSync(process.cwd());
7
8
  const errors = [];
@@ -9,32 +10,7 @@ const errors = [];
9
10
  const args = parseArgs(process.argv.slice(2));
10
11
  const fixturePath = repoPath(args.fixture);
11
12
  const fixture = readJson(fixturePath);
12
-
13
- const sensitiveTerms = [
14
- "立信",
15
- "费敏",
16
- "闻总",
17
- "谭总",
18
- "茅盾中学",
19
- "鸿益",
20
- "太鑫",
21
- "飞双",
22
- "魔毯",
23
- "客户内部",
24
- "培训演示",
25
- "基础内测",
26
- "内测模式",
27
- "内测包",
28
- "嘉兴",
29
- "绍兴",
30
- "杭州",
31
- "20,000",
32
- "20000",
33
- "28,000",
34
- "28000",
35
- "17,800",
36
- "17800"
37
- ];
13
+ const sensitiveTerms = loadLocalSensitiveTerms(root);
38
14
 
39
15
  function repoPath(...parts) {
40
16
  const target = path.join(root, ...parts);
@@ -103,8 +79,7 @@ function check(condition, message) {
103
79
  }
104
80
 
105
81
  function includesSensitiveTerm(value) {
106
- const raw = typeof value === "string" ? value : JSON.stringify(value);
107
- return sensitiveTerms.filter((term) => raw.includes(term));
82
+ return findSensitiveTerms(value, sensitiveTerms);
108
83
  }
109
84
 
110
85
  function caseInput(item) {
@@ -0,0 +1,62 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ const LOCAL_TERM_FILES = [
5
+ ".env",
6
+ ".aios-sensitive-terms.local",
7
+ ".env.local",
8
+ ".env.sensitive.local"
9
+ ];
10
+
11
+ function parseTermList(value) {
12
+ if (typeof value !== "string") return [];
13
+ return value
14
+ .split(/[\n,;]+/)
15
+ .map((term) => term.trim())
16
+ .filter((term) => term.length > 0 && !term.startsWith("#"));
17
+ }
18
+
19
+ function parseEnvLine(line) {
20
+ const trimmed = line.trim();
21
+ if (!trimmed || trimmed.startsWith("#")) return [];
22
+ const separatorIndex = trimmed.indexOf("=");
23
+ if (separatorIndex === -1) return parseTermList(trimmed);
24
+
25
+ const key = trimmed.slice(0, separatorIndex).trim();
26
+ const rawValue = trimmed.slice(separatorIndex + 1).trim();
27
+ if (key !== "AIOS_SENSITIVE_TERMS") return [];
28
+
29
+ const unquoted = rawValue.replace(/^['"]|['"]$/g, "");
30
+ return parseTermList(unquoted);
31
+ }
32
+
33
+ function readLocalTermFile(filePath) {
34
+ if (!fs.existsSync(filePath)) return [];
35
+
36
+ const content = fs.readFileSync(filePath, "utf8");
37
+ return parseLocalTermContent(content);
38
+ }
39
+
40
+ function parseLocalTermContent(content) {
41
+ return content
42
+ .split(/\r?\n/)
43
+ .flatMap((line) => parseEnvLine(line));
44
+ }
45
+
46
+ export function loadLocalSensitiveTerms(root = process.cwd(), env = process.env) {
47
+ const terms = new Set(parseTermList(env.AIOS_SENSITIVE_TERMS));
48
+
49
+ for (const fileName of LOCAL_TERM_FILES) {
50
+ for (const term of readLocalTermFile(path.join(root, fileName))) {
51
+ terms.add(term);
52
+ }
53
+ }
54
+
55
+ return [...terms];
56
+ }
57
+
58
+ export function findSensitiveTerms(value, terms) {
59
+ if (!Array.isArray(terms) || terms.length === 0) return [];
60
+ const raw = typeof value === "string" ? value : JSON.stringify(value);
61
+ return terms.filter((term) => raw.includes(term));
62
+ }
@@ -2,6 +2,7 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
+ import { findSensitiveTerms, loadLocalSensitiveTerms } from "./lib/local-sensitive-terms.mjs";
5
6
 
6
7
  const root = fs.realpathSync(process.cwd());
7
8
  const errors = [];
@@ -15,32 +16,7 @@ const fixtures = fixturePaths.map((fixturePath) => ({
15
16
  path: fixturePath,
16
17
  data: readJson(repoPath(fixturePath))
17
18
  }));
18
-
19
- const sensitiveTerms = [
20
- "立信",
21
- "费敏",
22
- "闻总",
23
- "谭总",
24
- "茅盾中学",
25
- "鸿益",
26
- "太鑫",
27
- "飞双",
28
- "魔毯",
29
- "客户内部",
30
- "培训演示",
31
- "基础内测",
32
- "内测模式",
33
- "内测包",
34
- "嘉兴",
35
- "绍兴",
36
- "杭州",
37
- "20,000",
38
- "20000",
39
- "28,000",
40
- "28000",
41
- "17,800",
42
- "17800"
43
- ];
19
+ const sensitiveTerms = loadLocalSensitiveTerms(root);
44
20
 
45
21
  const requiredCaseFields = [
46
22
  "id",
@@ -91,8 +67,7 @@ function check(condition, message) {
91
67
  }
92
68
 
93
69
  function includesSensitiveTerm(value) {
94
- const raw = typeof value === "string" ? value : JSON.stringify(value);
95
- return sensitiveTerms.filter((term) => raw.includes(term));
70
+ return findSensitiveTerms(value, sensitiveTerms);
96
71
  }
97
72
 
98
73
  function validateMarkdownFixture(fixturePath, item) {
@@ -2,6 +2,7 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
+ import { findSensitiveTerms, loadLocalSensitiveTerms } from "./lib/local-sensitive-terms.mjs";
5
6
 
6
7
  const root = fs.realpathSync(process.cwd());
7
8
  const errors = [];
@@ -12,23 +13,7 @@ const outputPath = args.file ?? repoPath(defaultOutputPath);
12
13
  const fixturePath = repoPath("prompts/evaluations/engineering-business-basic-fixtures.json");
13
14
  const fixture = readJson(fixturePath);
14
15
  const outputFile = args.init ? undefined : readJson(outputPath);
15
-
16
- const sensitiveTerms = [
17
- "立信",
18
- "费敏",
19
- "闻总",
20
- "谭总",
21
- "茅盾中学",
22
- "鸿益",
23
- "太鑫",
24
- "飞双",
25
- "魔毯",
26
- "客户内部",
27
- "培训演示",
28
- "基础内测",
29
- "内测模式",
30
- "内测包"
31
- ];
16
+ const sensitiveTerms = loadLocalSensitiveTerms(root);
32
17
 
33
18
  function repoPath(...parts) {
34
19
  const target = path.join(root, ...parts);
@@ -88,8 +73,7 @@ function check(condition, message) {
88
73
  }
89
74
 
90
75
  function includesSensitiveTerm(value) {
91
- const raw = typeof value === "string" ? value : JSON.stringify(value);
92
- return sensitiveTerms.filter((term) => raw.includes(term));
76
+ return findSensitiveTerms(value, sensitiveTerms);
93
77
  }
94
78
 
95
79
  function outputText(value) {
@@ -2,6 +2,7 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
+ import { findSensitiveTerms, loadLocalSensitiveTerms } from "./lib/local-sensitive-terms.mjs";
5
6
 
6
7
  const root = fs.realpathSync(process.cwd());
7
8
  const errors = [];
@@ -10,23 +11,7 @@ const diagnostics = [];
10
11
  const fixturePath = repoPath("prompts/evaluations/engineering-business-basic-fixtures.json");
11
12
  const fixture = readJson(fixturePath);
12
13
  const args = parseArgs(process.argv.slice(2));
13
-
14
- const sensitiveTerms = [
15
- "立信",
16
- "费敏",
17
- "闻总",
18
- "谭总",
19
- "茅盾中学",
20
- "鸿益",
21
- "太鑫",
22
- "飞双",
23
- "魔毯",
24
- "客户内部",
25
- "培训演示",
26
- "基础内测",
27
- "内测模式",
28
- "内测包"
29
- ];
14
+ const sensitiveTerms = loadLocalSensitiveTerms(root);
30
15
 
31
16
  function repoPath(...parts) {
32
17
  const target = path.join(root, ...parts);
@@ -93,8 +78,7 @@ function check(condition, message) {
93
78
  }
94
79
 
95
80
  function includesSensitiveTerm(value) {
96
- const raw = typeof value === "string" ? value : JSON.stringify(value);
97
- return sensitiveTerms.filter((term) => raw.includes(term));
81
+ return findSensitiveTerms(value, sensitiveTerms);
98
82
  }
99
83
 
100
84
  function outputText(value) {
@@ -2,6 +2,7 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
+ import { findSensitiveTerms, loadLocalSensitiveTerms } from "./lib/local-sensitive-terms.mjs";
5
6
 
6
7
  const root = fs.realpathSync(process.cwd());
7
8
  const errors = [];
@@ -16,23 +17,7 @@ const scorecardSpecs = [
16
17
  scorecardPath: "prompts/evaluations/engineering-document-writing-scorecard.json"
17
18
  }
18
19
  ];
19
-
20
- const sensitiveTerms = [
21
- "立信",
22
- "费敏",
23
- "闻总",
24
- "谭总",
25
- "茅盾中学",
26
- "鸿益",
27
- "太鑫",
28
- "飞双",
29
- "魔毯",
30
- "客户内部",
31
- "培训演示",
32
- "基础内测",
33
- "内测模式",
34
- "内测包"
35
- ];
20
+ const sensitiveTerms = loadLocalSensitiveTerms(root);
36
21
 
37
22
  function repoPath(...parts) {
38
23
  const target = path.join(root, ...parts);
@@ -57,8 +42,7 @@ function check(condition, message) {
57
42
  }
58
43
 
59
44
  function includesSensitiveTerm(value) {
60
- const raw = typeof value === "string" ? value : JSON.stringify(value);
61
- return sensitiveTerms.filter((term) => raw.includes(term));
45
+ return findSensitiveTerms(value, sensitiveTerms);
62
46
  }
63
47
 
64
48
  function weightedScore(scores, criteria) {
@@ -2,23 +2,13 @@
2
2
 
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
+ import { findSensitiveTerms, loadLocalSensitiveTerms } from "./lib/local-sensitive-terms.mjs";
5
6
 
6
7
  const root = fs.realpathSync(process.cwd());
7
8
  const errors = [];
8
9
  const evidencePath = "prompts/evaluations/skill-runtime/v1.4.0-writing-host-validation.json";
9
10
  const reportPath = "prompts/evaluations/skill-runtime/v1.4.0-writing-host-validation.md";
10
-
11
- const sensitiveTerms = [
12
- "立信",
13
- "费敏",
14
- "闻总",
15
- "谭总",
16
- "客户内部",
17
- "培训演示",
18
- "基础内测",
19
- "内测模式",
20
- "内测包"
21
- ];
11
+ const sensitiveTerms = loadLocalSensitiveTerms(root);
22
12
 
23
13
  function repoPath(...parts) {
24
14
  const target = path.join(root, ...parts);
@@ -56,8 +46,7 @@ function check(condition, message) {
56
46
  }
57
47
 
58
48
  function includesSensitiveTerm(value) {
59
- const raw = typeof value === "string" ? value : JSON.stringify(value);
60
- return sensitiveTerms.filter((term) => raw.includes(term));
49
+ return findSensitiveTerms(value, sensitiveTerms);
61
50
  }
62
51
 
63
52
  const evidence = readJson(evidencePath);
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 输出为合同文本审核辅助,不构成法律意见。
10
11
  - 不判断最终责任归属,不替代法务、商务、造价、财务、授权签章负责人或项目负责人复核。
11
12
  - 不把资料未提及事项写成违约或不合格。
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 输出只能作为草稿,不构成法律意见或可签署文本。
10
11
  - 不判断最终责任归属、索赔成立、结算金额或是否可以签署。
11
12
  - 不替代法务、商务、造价、财务、项目经理、合同经办或授权签章负责人复核。
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 输出只能作为日报草稿,不替代项目经理、施工员、资料员、监理或业主确认。
10
11
  - 不把口述、群聊或照片推断写成已确认事实。
11
12
  - 没有计划基线时,不判断滞后或超前。
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 输出只能作为会议纪要草稿,不替代正式会议纪要签发、监理指令、合同通知或业主审批。
10
11
  - 不把讨论、建议或发言人线索写成正式决议。
11
12
  - 不补猜责任人、期限、承诺内容、附件或签发状态。
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 使用“AI 辅助施工方案复核”,不使用“AI 审查施工方案”。
10
11
  - 不替代专项方案审查、专家论证、施工计算、总工、监理或专业负责人判断。
11
12
  - 对规范、计算、现场条件和审批要求不明确处标为“需专业人员确认”。
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 使用 Markdown 作为工作母版,Word / PDF / PPT 只作为后续交付格式。
10
11
  - 不输出“方案合格 / 不合格 / 已通过审查”。
11
12
  - 不替代总工、专家论证、危大工程审批、结构计算、监理、安全负责人或审批主体。
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 仅用于投标文件准备辅助,不提供具体项目评标结论。
10
11
  - 不替代投标负责人、经营人员、法务人员、造价人员或专家判断。
11
12
  - 如资料未提及,应写为“需补充确认”,不能推定为满足或不满足。
@@ -6,6 +6,7 @@
6
6
 
7
7
  ## 使用边界
8
8
 
9
+ - 输入资料应先在本地完成脱敏;如包含未授权客户名称、人员姓名、联系方式、证件号码、账号、完整内部原文或其他不应外发资料,先提示用户脱敏或改为摘要,不继续展开实质分析。
9
10
  - 使用 Markdown 作为工作母版,Word / PDF / PPT 只作为后续交付格式。
10
11
  - 不编造企业资质、业绩、人员、设备、奖项、工期、金额或施工承诺。
11
12
  - 不输出中标概率、评标结论、最终投标决策或违法规避建议。