@infinisys/fabric 0.0.0-stage → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +74 -2
- package/cordis.patch.yml +635 -0
- package/package.json +40 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Infinity System contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,75 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @infinisys/fabric
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
一个 bundle,把 Infinity Fabric 的全部插件按支持顺序装进同一个 profile。
|
|
4
|
+
|
|
5
|
+
> 启用它等于一次接管十二处 DSH 默认行为(品牌行、团队行、`web` 行、`subagent` 容量等)。后果与逐条退回方式见 [docs/disclaimer.md](https://gitfox.studio/infinity/Fabric/blob/master/docs/disclaimer.md)。
|
|
6
|
+
|
|
7
|
+
它自己不含任何 Host/Client 代码:`cordis.patch.yml` 是十二个成员包补丁的**生成结果**(`pnpm run meta` 生成,`scripts/check.mjs` 会拦住忘记重建的版本)。所以「装了什么」仍然由每个 `is-*` 包自己的补丁决定,这里只有一份顺序表和一个开关。
|
|
8
|
+
|
|
9
|
+
## 它做了什么
|
|
10
|
+
|
|
11
|
+
启用后,profile 里等价于同时启用了这十二个 bundle:
|
|
12
|
+
|
|
13
|
+
| 顺序 | 包 | 作用 |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| 1 | `@infinisys/is-identity` | 品牌与部署身份(在原生品牌行上盖一层纯文字 Infinity System,可整体关掉) |
|
|
16
|
+
| 2 | `@infinisys/is-settings` | Infinity 设置页与 `infinitySettings` 服务 |
|
|
17
|
+
| 3 | `@infinisys/is-devops` | GitFox 面板与 `infinity_devops` / `infinity_git` 工具 |
|
|
18
|
+
| 4 | `@infinisys/is-fabric-team` | 团队协作模式预设与 `infinityTeam` 服务(关闭原生 Team 工具/UI) |
|
|
19
|
+
| 5 | `@infinisys/is-im` | IM 网关与「IM 网关」设置卡片 |
|
|
20
|
+
| 6 | `@infinisys/is-team-language` | 团队语言桥与 `/infinity/translate` |
|
|
21
|
+
| 7 | `@infinisys/is-update` | 版本与更新卡片 |
|
|
22
|
+
| 8 | `@infinisys/is-offpeak` | 峰谷调度卡片 |
|
|
23
|
+
| 9 | `@infinisys/is-toolchain-cache` | 构建缓存与 `TMPDIR` 重定向 |
|
|
24
|
+
| 10 | `@infinisys/is-disk-guard` | 会话投影的写盘预算 |
|
|
25
|
+
| 11 | `@infinisys/is-web-access` | 抓取放行(把 profile 的 `web` 行指到 `infinity-http`) |
|
|
26
|
+
| 12 | `@infinisys/is-stream-guard` | SSE 帧错误重试 |
|
|
27
|
+
|
|
28
|
+
顺序不是装饰:`is-settings` 要先于 `is-devops` 与 `is-fabric-team` 提供 `infinitySettings`,`is-identity` 用 `priority: -1` 盖住原生品牌位、顺序不敏感,`is-web-access` 要排在 `@deepseek-ai/dsh-web-app` 之后才有 `web` 行可改。
|
|
29
|
+
|
|
30
|
+
## 为什么是一份生成文件,而不是指向兄弟包的路径清单
|
|
31
|
+
|
|
32
|
+
`dsh.bundle.patch` 也接受路径数组,但那些路径是相对**包目录**拼出来的字符串。装到 profile 后包目录是 `node_modules/@infinisys/fabric`,兄弟包在 pnpm 的严格布局里可能不在同一层——路径清单在某些安装方式下会静默指向不存在的文件。一份跟着包走的 `cordis.patch.yml` 没有这个前提。
|
|
33
|
+
|
|
34
|
+
改成员补丁后记得重建:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm run meta # 重新生成 packages/fabric/cordis.patch.yml
|
|
38
|
+
pnpm run check # 生成文件过期时这里会失败
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 安装
|
|
42
|
+
|
|
43
|
+
成员包写在这份清单的 `dependencies` 里,每条是 `^<成员版本>`,所以从 registry 装一次就全了:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
dsh plugin --profile web add @infinisys/fabric
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
想直接指向 checkout(发布前、或改代码即时生效):
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
node scripts/link-meta.mjs --link # 把 ^<版本> 换成 link:../is-*
|
|
53
|
+
dsh plugin --profile web add /path/to/Fabric/packages/fabric /path/to/Fabric/packages/is-*
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`--link` 只在本地用,提交前跑 `node scripts/link-meta.mjs --registry` 换回来(`scripts/check.mjs` 只接受 registry 形式)。`pnpm` 对 `link:` 依赖的处理随版本而异,可能不会替你把成员包搬进 profile,所以 checkout 装法要把十三个目录一起写进同一条命令。
|
|
57
|
+
|
|
58
|
+
成员之间必须成套的关系只有三处(`is-devops` 要 `is-settings`,`is-fabric-team` 要 `is-settings` 加 `is-devops`,`is-disk-guard` 建议配 `is-stream-guard`),单个安装时的命令见 [依赖关系](../../docs/dependencies.md)。
|
|
59
|
+
|
|
60
|
+
装完在 Plugins 页面启用 `@infinisys/fabric`(或把 `@infinisys/fabric` 加进 `$DSH_HOME/profiles/web/package.json` 的 `dsh.profile.bundles`),重启一次 Web。
|
|
61
|
+
|
|
62
|
+
## 只想装一部分
|
|
63
|
+
|
|
64
|
+
不要启用这个元包。按需单独启用对应的 `is-*` 包即可,每个包的补丁是独立的。
|
|
65
|
+
|
|
66
|
+
反过来,一旦启用了元包,就不要再单独启用任何 `is-*` 包:同一个插件会被注册两次,重复的行 id 会让 profile 加载失败。
|
|
67
|
+
|
|
68
|
+
想关掉其中某个插件但保留其余:在 profile 的 `cordis.patch.yml` 里追加一行覆盖,例如
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
- id: is-im
|
|
72
|
+
disabled: true
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
profile 补丁层永远在 bundle 层之后应用,所以这一行会生效。注意有些包除了插入自己的行,还改动了已有行(`is-fabric-team` 关掉原生 Team 两行、`is-web-access` 改 `web` 行),只停用插入的行不会把这些改动还原,具体见 [安装与退回](../../docs/install.md)。`is-identity` 不改任何已有行:它只是在运行时以 `priority: -1` 压过官方品牌位,`brand: false` 或卸载后官方品牌自然回来。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
# GENERATED FILE — do not edit.
|
|
2
|
+
#
|
|
3
|
+
# The Infinity Fabric one-bundle install: every member patch, in dependency
|
|
4
|
+
# order, so one package (and one on/off switch) carries the whole stack.
|
|
5
|
+
# Edit packages/<member>/cordis.patch.yml instead, then run `pnpm run meta`.
|
|
6
|
+
# `scripts/check.mjs` fails while this file is stale.
|
|
7
|
+
|
|
8
|
+
# ---- @infinisys/is-identity -------------------------------------------------
|
|
9
|
+
# The shipped `ui-brand-official` row stays enabled. Infinity registers the same
|
|
10
|
+
# single brand seats at `priority: -1`, which shadows the official wordmark at
|
|
11
|
+
# the default 0 without colliding with it, so switching the Infinity brand off
|
|
12
|
+
# gives the official brand back instead of the shell's local-build fallback.
|
|
13
|
+
- insert:
|
|
14
|
+
- id: is-identity
|
|
15
|
+
name: '@infinisys/is-identity'
|
|
16
|
+
config:
|
|
17
|
+
# Infinity System branding (sidebar name, browser tab, favicon and
|
|
18
|
+
# accent) and Infinity Glass (the backdrop frost and the surface alpha
|
|
19
|
+
# that lets it show) are on by default. Set `brand: false` or
|
|
20
|
+
# `frost: false` in the profile's own patch to give that layer back to
|
|
21
|
+
# the shell; the settings page exposes both switches as well.
|
|
22
|
+
brand: true
|
|
23
|
+
frost: true
|
|
24
|
+
|
|
25
|
+
# ---- @infinisys/is-settings -------------------------------------------------
|
|
26
|
+
- insert:
|
|
27
|
+
- id: is-settings
|
|
28
|
+
name: '@infinisys/is-settings'
|
|
29
|
+
config: {}
|
|
30
|
+
|
|
31
|
+
# ---- @infinisys/is-devops ---------------------------------------------------
|
|
32
|
+
- insert:
|
|
33
|
+
- id: is-devops
|
|
34
|
+
name: '@infinisys/is-devops'
|
|
35
|
+
config: {}
|
|
36
|
+
|
|
37
|
+
# ---- @infinisys/is-fabric-team ----------------------------------------------
|
|
38
|
+
# Infinity Fabric AI Team bundle.
|
|
39
|
+
#
|
|
40
|
+
# Adds four Agent presets that together make up Team Collaboration Mode:
|
|
41
|
+
#
|
|
42
|
+
# fabric-team Assistant/Lead coordination only: no shell, no write
|
|
43
|
+
# fabric-team-worker dev / test / ci implementation surface (guarded paths)
|
|
44
|
+
# fabric-team-readonly qa / secure / hr review surface: read-only, no shell
|
|
45
|
+
# fabric-team-docs docs seat: writes documentation paths, no shell
|
|
46
|
+
#
|
|
47
|
+
# The tool surface is structural: a role gets the preset that mounts exactly the
|
|
48
|
+
# tools it may use, so an Assistant or Lead cannot do implementation work even
|
|
49
|
+
# when Host provisioning fails. The Host row (`is-fabric-team`) registers the
|
|
50
|
+
# `infinity_team` tool, the per-role git/write guards, the `/infinity/team/state`
|
|
51
|
+
# snapshot and the GitFox-tracked governance state.
|
|
52
|
+
#
|
|
53
|
+
# This bundle requires the official Agent Teams profile bundle for its base
|
|
54
|
+
# rows, but runs the Fabric team on the Subagent runtime: the native
|
|
55
|
+
# tool-agent-team and ui-agent-team rows are disabled below so the session has
|
|
56
|
+
# exactly one visible identity, the Assistant. Do NOT insert another
|
|
57
|
+
# tool-agent-team row here.
|
|
58
|
+
|
|
59
|
+
# The native Agent Teams root is hard-coded as the Lead. Fabric Team uses the
|
|
60
|
+
# Subagent runtime instead and owns the Assistant identity, so the native Team
|
|
61
|
+
# tools and roster UI stay off in this profile.
|
|
62
|
+
- id: tool-agent-team
|
|
63
|
+
disabled: true
|
|
64
|
+
|
|
65
|
+
- id: ui-agent-team
|
|
66
|
+
disabled: true
|
|
67
|
+
|
|
68
|
+
# The Assistant + Lead + eight roles are 10 members; allow enough live children
|
|
69
|
+
# for the auto-provisioned tree (root -> lead -> eight teammates).
|
|
70
|
+
- id: subagent
|
|
71
|
+
config:
|
|
72
|
+
maxActiveSubagents: 16
|
|
73
|
+
maxDepth: 3
|
|
74
|
+
|
|
75
|
+
- insert:
|
|
76
|
+
- id: is-fabric-team
|
|
77
|
+
name: '@infinisys/is-fabric-team'
|
|
78
|
+
config: {}
|
|
79
|
+
|
|
80
|
+
# ---------------------------------------------------------------- coordinator
|
|
81
|
+
# The session root (Assistant) and the Lead. Coordination and read-only
|
|
82
|
+
# inspection only: the shell and the write/edit tools are not mounted at all.
|
|
83
|
+
- id: preset-fabric-team
|
|
84
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
85
|
+
config:
|
|
86
|
+
id: fabric-team
|
|
87
|
+
name: 团队协作模式
|
|
88
|
+
description: >-
|
|
89
|
+
Infinity Fabric 团队协作模式:助手先提取需求并由 Lead 带队;QA、后端、前端与安全必须一致投票;
|
|
90
|
+
所有会议、决策与工作流都通过 GitFox 跟踪;HR 管理长期身份。
|
|
91
|
+
助手与 Lead 只有协调与只读工具,结构上没有 shell 和写文件能力。
|
|
92
|
+
order: 5
|
|
93
|
+
plugins:
|
|
94
|
+
- id: persona
|
|
95
|
+
name: '@deepseek-ai/dsh-persona'
|
|
96
|
+
config:
|
|
97
|
+
prefix: >-
|
|
98
|
+
You are the coordinator of the Infinity Fabric AI Team, powered by the {{model}} model.
|
|
99
|
+
The session root is the Assistant: it owns user intake and the final answer. The Lead
|
|
100
|
+
teammate turns tracked requirements into plans, decisions and assigned tasks. You have
|
|
101
|
+
no shell and no file-writing tools by construction: never implement work yourself,
|
|
102
|
+
never decide without unanimous votes, never work untracked, and never claim a gate
|
|
103
|
+
passed without a successful infinity_team result.
|
|
104
|
+
- id: agent-instructions
|
|
105
|
+
name: '@deepseek-ai/dsh-agent-instructions'
|
|
106
|
+
config:
|
|
107
|
+
maxBytes: 65536
|
|
108
|
+
- id: time-context
|
|
109
|
+
name: '@deepseek-ai/dsh-time-context'
|
|
110
|
+
- id: fabric-team-mode
|
|
111
|
+
name: '@infinisys/is-fabric-team/mode'
|
|
112
|
+
config:
|
|
113
|
+
role: coordinator
|
|
114
|
+
# Read-only filesystem: no write, no edit tool is ever registered.
|
|
115
|
+
- id: tool-fs
|
|
116
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
117
|
+
config:
|
|
118
|
+
read: true
|
|
119
|
+
readImage: true
|
|
120
|
+
write: false
|
|
121
|
+
edit: false
|
|
122
|
+
- id: tool-fs-search
|
|
123
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
124
|
+
config:
|
|
125
|
+
sampleOverCapGlobResults: false
|
|
126
|
+
- id: tool-web
|
|
127
|
+
name: '@deepseek-ai/dsh-tool-web'
|
|
128
|
+
config:
|
|
129
|
+
fetch: true
|
|
130
|
+
searchTimeoutMs: 60000
|
|
131
|
+
- id: tool-ask-user
|
|
132
|
+
name: '@deepseek-ai/dsh-tool-ask-user'
|
|
133
|
+
- id: tool-todo
|
|
134
|
+
name: '@deepseek-ai/dsh-tool-todo'
|
|
135
|
+
config:
|
|
136
|
+
allowParallelInProgress: true
|
|
137
|
+
- id: command-goal
|
|
138
|
+
name: '@deepseek-ai/dsh-command-goal'
|
|
139
|
+
- id: tool-goal
|
|
140
|
+
name: '@deepseek-ai/dsh-tool-goal'
|
|
141
|
+
- id: present
|
|
142
|
+
name: '@deepseek-ai/dsh-tool-present'
|
|
143
|
+
- id: planning
|
|
144
|
+
name: cordis:group
|
|
145
|
+
group: true
|
|
146
|
+
isolate:
|
|
147
|
+
planMode: true
|
|
148
|
+
config:
|
|
149
|
+
- id: plan-mode
|
|
150
|
+
name: '@deepseek-ai/dsh-plan-mode'
|
|
151
|
+
config:
|
|
152
|
+
section: |
|
|
153
|
+
You are in plan mode. Stay in plan mode until the user approves your plan through exit_plan_mode or switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
|
|
154
|
+
|
|
155
|
+
Explore first. Use non-mutating reads, searches and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan.
|
|
156
|
+
|
|
157
|
+
A plan is only complete when it names the tracked requirement, the decision that needs unanimous votes, every affected boundary, the tests and the evidence each workflow gate expects. Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices that inspection cannot answer. Submit the plan through exit_plan_mode.
|
|
158
|
+
- id: compaction
|
|
159
|
+
name: cordis:group
|
|
160
|
+
group: true
|
|
161
|
+
isolate:
|
|
162
|
+
compaction: true
|
|
163
|
+
toolResultPruner: true
|
|
164
|
+
config:
|
|
165
|
+
- id: compaction-basic
|
|
166
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
167
|
+
- id: command-compact
|
|
168
|
+
name: '@deepseek-ai/dsh-command-compact'
|
|
169
|
+
- id: tool-result-pruner
|
|
170
|
+
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
171
|
+
config:
|
|
172
|
+
thresholdChars: 8192
|
|
173
|
+
headChars: 4096
|
|
174
|
+
tailChars: 1024
|
|
175
|
+
- id: tool-plugin-manager
|
|
176
|
+
name: '@deepseek-ai/dsh-plugin-manager/tools'
|
|
177
|
+
disabled: true
|
|
178
|
+
- id: tool-plugin-market
|
|
179
|
+
name: '@deepseek-ai/dsh-plugin-market/tools'
|
|
180
|
+
disabled: true
|
|
181
|
+
|
|
182
|
+
# ---------------------------------------------------------------- watchdog
|
|
183
|
+
# The Lead's peer. Read-only, no team tools: its only control surface is
|
|
184
|
+
# infinity_watchdog, registered by the Host at creation.
|
|
185
|
+
- id: preset-fabric-team-watchdog
|
|
186
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
187
|
+
config:
|
|
188
|
+
id: fabric-team-watchdog
|
|
189
|
+
name: 团队监督员
|
|
190
|
+
description: >-
|
|
191
|
+
Lead 的同级监督员:读团队事件流与账本,判断是否真的在推进;可暂停/恢复团队、
|
|
192
|
+
关闭陈旧条目、向 Lead 或人类升级。没有 shell、写文件、投票或实施工具。
|
|
193
|
+
order: 6
|
|
194
|
+
plugins:
|
|
195
|
+
- id: persona
|
|
196
|
+
name: '@deepseek-ai/dsh-persona'
|
|
197
|
+
config:
|
|
198
|
+
prefix: >-
|
|
199
|
+
You are the Watchdog of the Infinity Fabric AI Team, the Lead's peer. You judge
|
|
200
|
+
whether the team is making real progress, and you intervene when it is not. You
|
|
201
|
+
cannot implement, vote, intake, merge or write files: your only control surface is
|
|
202
|
+
the infinity_watchdog tool. Read the team's language; do not reduce your judgement
|
|
203
|
+
to a status code.
|
|
204
|
+
- id: agent-instructions
|
|
205
|
+
name: '@deepseek-ai/dsh-agent-instructions'
|
|
206
|
+
config:
|
|
207
|
+
maxBytes: 65536
|
|
208
|
+
- id: time-context
|
|
209
|
+
name: '@deepseek-ai/dsh-time-context'
|
|
210
|
+
- id: tool-fs
|
|
211
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
212
|
+
config:
|
|
213
|
+
read: true
|
|
214
|
+
readImage: false
|
|
215
|
+
write: false
|
|
216
|
+
edit: false
|
|
217
|
+
- id: tool-fs-search
|
|
218
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
219
|
+
config:
|
|
220
|
+
sampleOverCapGlobResults: false
|
|
221
|
+
- id: tool-web
|
|
222
|
+
name: '@deepseek-ai/dsh-tool-web'
|
|
223
|
+
config:
|
|
224
|
+
fetch: true
|
|
225
|
+
searchTimeoutMs: 60000
|
|
226
|
+
- id: tool-ask-user
|
|
227
|
+
name: '@deepseek-ai/dsh-tool-ask-user'
|
|
228
|
+
- id: tool-todo
|
|
229
|
+
name: '@deepseek-ai/dsh-tool-todo'
|
|
230
|
+
config:
|
|
231
|
+
allowParallelInProgress: false
|
|
232
|
+
- id: compaction
|
|
233
|
+
name: cordis:group
|
|
234
|
+
group: true
|
|
235
|
+
isolate:
|
|
236
|
+
compaction: true
|
|
237
|
+
toolResultPruner: true
|
|
238
|
+
config:
|
|
239
|
+
- id: compaction-basic
|
|
240
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
241
|
+
- id: command-compact
|
|
242
|
+
name: '@deepseek-ai/dsh-command-compact'
|
|
243
|
+
- id: tool-result-pruner
|
|
244
|
+
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
245
|
+
config:
|
|
246
|
+
thresholdChars: 8192
|
|
247
|
+
headChars: 4096
|
|
248
|
+
tailChars: 1024
|
|
249
|
+
|
|
250
|
+
# ------------------------------------------------------------------- worker
|
|
251
|
+
# Implementation seats: backend, frontend, delivery/CI and test. A shell is
|
|
252
|
+
# present, but direct git is refused and write/edit stays inside the role's
|
|
253
|
+
# write scopes (enforced by the Host git/write guards).
|
|
254
|
+
- id: preset-fabric-team-worker
|
|
255
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
256
|
+
config:
|
|
257
|
+
id: fabric-team-worker
|
|
258
|
+
name: 团队协作模式(执行成员)
|
|
259
|
+
description: >-
|
|
260
|
+
团队执行席位(后端、前端、交付/CI、测试)。在 Lead 分配的 claim 内实现并写测试;
|
|
261
|
+
直接 git 被禁用,只能使用 infinity_git;写路径受角色白名单约束。
|
|
262
|
+
order: 6
|
|
263
|
+
plugins:
|
|
264
|
+
- id: persona
|
|
265
|
+
name: '@deepseek-ai/dsh-persona'
|
|
266
|
+
config:
|
|
267
|
+
prefix: >-
|
|
268
|
+
You are an implementation seat of the Infinity Fabric AI Team, powered by the {{model}}
|
|
269
|
+
model. Implement only inside the claim the Lead assigned and inside your role's write
|
|
270
|
+
scopes; write tests before production code; never approve your own work; drive git only
|
|
271
|
+
through infinity_git; a denied tool call is final.
|
|
272
|
+
- id: agent-instructions
|
|
273
|
+
name: '@deepseek-ai/dsh-agent-instructions'
|
|
274
|
+
config:
|
|
275
|
+
maxBytes: 65536
|
|
276
|
+
- id: time-context
|
|
277
|
+
name: '@deepseek-ai/dsh-time-context'
|
|
278
|
+
- id: fabric-team-mode
|
|
279
|
+
name: '@infinisys/is-fabric-team/mode'
|
|
280
|
+
config:
|
|
281
|
+
role: worker
|
|
282
|
+
- id: tool-bash
|
|
283
|
+
name: '@deepseek-ai/dsh-tool-bash'
|
|
284
|
+
disabled: !!js process.platform === 'win32'
|
|
285
|
+
- id: tool-pwsh
|
|
286
|
+
name: '@deepseek-ai/dsh-tool-pwsh'
|
|
287
|
+
disabled: !!js process.platform !== 'win32'
|
|
288
|
+
- id: tool-fs
|
|
289
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
290
|
+
- id: tool-fs-search
|
|
291
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
292
|
+
config:
|
|
293
|
+
sampleOverCapGlobResults: false
|
|
294
|
+
- id: tool-jobs
|
|
295
|
+
name: '@deepseek-ai/dsh-tool-jobs'
|
|
296
|
+
- id: skill-filesystem
|
|
297
|
+
name: '@deepseek-ai/dsh-skill-filesystem'
|
|
298
|
+
- id: tool-skill
|
|
299
|
+
name: '@deepseek-ai/dsh-tool-skill'
|
|
300
|
+
- id: tool-web
|
|
301
|
+
name: '@deepseek-ai/dsh-tool-web'
|
|
302
|
+
config:
|
|
303
|
+
fetch: true
|
|
304
|
+
searchTimeoutMs: 60000
|
|
305
|
+
- id: tool-ask-user
|
|
306
|
+
name: '@deepseek-ai/dsh-tool-ask-user'
|
|
307
|
+
- id: tool-todo
|
|
308
|
+
name: '@deepseek-ai/dsh-tool-todo'
|
|
309
|
+
config:
|
|
310
|
+
allowParallelInProgress: true
|
|
311
|
+
- id: present
|
|
312
|
+
name: '@deepseek-ai/dsh-tool-present'
|
|
313
|
+
- id: planning
|
|
314
|
+
name: cordis:group
|
|
315
|
+
group: true
|
|
316
|
+
isolate:
|
|
317
|
+
planMode: true
|
|
318
|
+
config:
|
|
319
|
+
- id: plan-mode
|
|
320
|
+
name: '@deepseek-ai/dsh-plan-mode'
|
|
321
|
+
config:
|
|
322
|
+
section: |
|
|
323
|
+
You are in plan mode. Plan only: no edits, no builds that rewrite tracked files, no commits. A plan names the claim, the failing test written first, and the evidence the next gate expects. Submit it through exit_plan_mode.
|
|
324
|
+
- id: compaction
|
|
325
|
+
name: cordis:group
|
|
326
|
+
group: true
|
|
327
|
+
isolate:
|
|
328
|
+
compaction: true
|
|
329
|
+
toolResultPruner: true
|
|
330
|
+
config:
|
|
331
|
+
- id: compaction-basic
|
|
332
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
333
|
+
- id: command-compact
|
|
334
|
+
name: '@deepseek-ai/dsh-command-compact'
|
|
335
|
+
- id: tool-result-pruner
|
|
336
|
+
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
337
|
+
config:
|
|
338
|
+
thresholdChars: 8192
|
|
339
|
+
headChars: 4096
|
|
340
|
+
tailChars: 1024
|
|
341
|
+
|
|
342
|
+
# ----------------------------------------------------------------- readonly
|
|
343
|
+
# Review seats: QA, Security and HR. No shell and no write/edit tool at all.
|
|
344
|
+
- id: preset-fabric-team-readonly
|
|
345
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
346
|
+
config:
|
|
347
|
+
id: fabric-team-readonly
|
|
348
|
+
name: 团队协作模式(评审成员)
|
|
349
|
+
description: >-
|
|
350
|
+
团队评审席位(QA、安全、HR)。结构上只有只读工具:不实现、不写文件、不起 shell,
|
|
351
|
+
只验证、评审和投票,证据必须可追踪。
|
|
352
|
+
order: 7
|
|
353
|
+
plugins:
|
|
354
|
+
- id: persona
|
|
355
|
+
name: '@deepseek-ai/dsh-persona'
|
|
356
|
+
config:
|
|
357
|
+
prefix: >-
|
|
358
|
+
You are a review seat of the Infinity Fabric AI Team, powered by the {{model}} model.
|
|
359
|
+
You have read-only tools by construction: never implement or modify files, only verify,
|
|
360
|
+
review and vote with tracked evidence. Never approve delivery on behalf of the Lead,
|
|
361
|
+
and never trade a finding for schedule pressure.
|
|
362
|
+
- id: agent-instructions
|
|
363
|
+
name: '@deepseek-ai/dsh-agent-instructions'
|
|
364
|
+
config:
|
|
365
|
+
maxBytes: 65536
|
|
366
|
+
- id: time-context
|
|
367
|
+
name: '@deepseek-ai/dsh-time-context'
|
|
368
|
+
- id: fabric-team-mode
|
|
369
|
+
name: '@infinisys/is-fabric-team/mode'
|
|
370
|
+
config:
|
|
371
|
+
role: worker
|
|
372
|
+
- id: tool-fs
|
|
373
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
374
|
+
config:
|
|
375
|
+
read: true
|
|
376
|
+
readImage: true
|
|
377
|
+
write: false
|
|
378
|
+
edit: false
|
|
379
|
+
- id: tool-fs-search
|
|
380
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
381
|
+
config:
|
|
382
|
+
sampleOverCapGlobResults: false
|
|
383
|
+
- id: tool-web
|
|
384
|
+
name: '@deepseek-ai/dsh-tool-web'
|
|
385
|
+
config:
|
|
386
|
+
fetch: true
|
|
387
|
+
searchTimeoutMs: 60000
|
|
388
|
+
- id: tool-ask-user
|
|
389
|
+
name: '@deepseek-ai/dsh-tool-ask-user'
|
|
390
|
+
- id: tool-todo
|
|
391
|
+
name: '@deepseek-ai/dsh-tool-todo'
|
|
392
|
+
config:
|
|
393
|
+
allowParallelInProgress: false
|
|
394
|
+
- id: planning
|
|
395
|
+
name: cordis:group
|
|
396
|
+
group: true
|
|
397
|
+
isolate:
|
|
398
|
+
planMode: true
|
|
399
|
+
config:
|
|
400
|
+
- id: plan-mode
|
|
401
|
+
name: '@deepseek-ai/dsh-plan-mode'
|
|
402
|
+
config:
|
|
403
|
+
section: |
|
|
404
|
+
You are in plan mode. Plan only: no edits, no builds that rewrite tracked files, no commits. A plan names the claim, the failing test written first, and the evidence the next gate expects. Submit it through exit_plan_mode.
|
|
405
|
+
- id: compaction
|
|
406
|
+
name: cordis:group
|
|
407
|
+
group: true
|
|
408
|
+
isolate:
|
|
409
|
+
compaction: true
|
|
410
|
+
toolResultPruner: true
|
|
411
|
+
config:
|
|
412
|
+
- id: compaction-basic
|
|
413
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
414
|
+
- id: command-compact
|
|
415
|
+
name: '@deepseek-ai/dsh-command-compact'
|
|
416
|
+
- id: tool-result-pruner
|
|
417
|
+
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
418
|
+
config:
|
|
419
|
+
thresholdChars: 8192
|
|
420
|
+
headChars: 4096
|
|
421
|
+
tailChars: 1024
|
|
422
|
+
|
|
423
|
+
# --------------------------------------------------------------------- docs
|
|
424
|
+
# Documentation seat: may write documentation paths, never a shell.
|
|
425
|
+
- id: preset-fabric-team-docs
|
|
426
|
+
name: '@deepseek-ai/dsh-agent-preset'
|
|
427
|
+
config:
|
|
428
|
+
id: fabric-team-docs
|
|
429
|
+
name: 团队协作模式(文档成员)
|
|
430
|
+
description: >-
|
|
431
|
+
团队文档席位。只能写文档路径(docs/、README、包内 README),没有 shell;
|
|
432
|
+
不实现生产代码,不投票技术决策。
|
|
433
|
+
order: 8
|
|
434
|
+
plugins:
|
|
435
|
+
- id: persona
|
|
436
|
+
name: '@deepseek-ai/dsh-persona'
|
|
437
|
+
config:
|
|
438
|
+
prefix: >-
|
|
439
|
+
You are the Documentation seat of the Infinity Fabric AI Team, powered by the {{model}}
|
|
440
|
+
model. You may write documentation paths only and you have no shell: never implement
|
|
441
|
+
production code, never vote on technical decisions, and keep README, architecture and
|
|
442
|
+
user-facing copy aligned with the shipped behavior.
|
|
443
|
+
- id: agent-instructions
|
|
444
|
+
name: '@deepseek-ai/dsh-agent-instructions'
|
|
445
|
+
config:
|
|
446
|
+
maxBytes: 65536
|
|
447
|
+
- id: time-context
|
|
448
|
+
name: '@deepseek-ai/dsh-time-context'
|
|
449
|
+
- id: fabric-team-mode
|
|
450
|
+
name: '@infinisys/is-fabric-team/mode'
|
|
451
|
+
config:
|
|
452
|
+
role: worker
|
|
453
|
+
- id: tool-fs
|
|
454
|
+
name: '@deepseek-ai/dsh-tool-fs'
|
|
455
|
+
- id: tool-fs-search
|
|
456
|
+
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
457
|
+
config:
|
|
458
|
+
sampleOverCapGlobResults: false
|
|
459
|
+
- id: tool-web
|
|
460
|
+
name: '@deepseek-ai/dsh-tool-web'
|
|
461
|
+
config:
|
|
462
|
+
fetch: true
|
|
463
|
+
searchTimeoutMs: 60000
|
|
464
|
+
- id: tool-ask-user
|
|
465
|
+
name: '@deepseek-ai/dsh-tool-ask-user'
|
|
466
|
+
- id: tool-todo
|
|
467
|
+
name: '@deepseek-ai/dsh-tool-todo'
|
|
468
|
+
config:
|
|
469
|
+
allowParallelInProgress: false
|
|
470
|
+
- id: present
|
|
471
|
+
name: '@deepseek-ai/dsh-tool-present'
|
|
472
|
+
- id: planning
|
|
473
|
+
name: cordis:group
|
|
474
|
+
group: true
|
|
475
|
+
isolate:
|
|
476
|
+
planMode: true
|
|
477
|
+
config:
|
|
478
|
+
- id: plan-mode
|
|
479
|
+
name: '@deepseek-ai/dsh-plan-mode'
|
|
480
|
+
config:
|
|
481
|
+
section: |
|
|
482
|
+
You are in plan mode. Plan only: no edits, no builds that rewrite tracked files, no commits. A plan names the claim, the failing test written first, and the evidence the next gate expects. Submit it through exit_plan_mode.
|
|
483
|
+
- id: compaction
|
|
484
|
+
name: cordis:group
|
|
485
|
+
group: true
|
|
486
|
+
isolate:
|
|
487
|
+
compaction: true
|
|
488
|
+
toolResultPruner: true
|
|
489
|
+
config:
|
|
490
|
+
- id: compaction-basic
|
|
491
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
492
|
+
- id: command-compact
|
|
493
|
+
name: '@deepseek-ai/dsh-command-compact'
|
|
494
|
+
- id: tool-result-pruner
|
|
495
|
+
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
496
|
+
config:
|
|
497
|
+
thresholdChars: 8192
|
|
498
|
+
headChars: 4096
|
|
499
|
+
tailChars: 1024
|
|
500
|
+
|
|
501
|
+
# ---- @infinisys/is-im -------------------------------------------------------
|
|
502
|
+
- insert:
|
|
503
|
+
- id: is-im
|
|
504
|
+
name: '@infinisys/is-im'
|
|
505
|
+
config: {}
|
|
506
|
+
|
|
507
|
+
# ---- @infinisys/is-team-language --------------------------------------------
|
|
508
|
+
# Team language bridge: the English record, the user-language translation,
|
|
509
|
+
# and the settings card that chooses the translation engine.
|
|
510
|
+
#
|
|
511
|
+
# The Fabric AI Team keeps working in English. This row adds the prompt section
|
|
512
|
+
# that makes every user-facing artifact carry a translation into the user's
|
|
513
|
+
# language, without touching the tracked English record.
|
|
514
|
+
- insert:
|
|
515
|
+
- id: is-team-language
|
|
516
|
+
name: '@infinisys/is-team-language'
|
|
517
|
+
config: {}
|
|
518
|
+
|
|
519
|
+
# ---- @infinisys/is-update ---------------------------------------------------
|
|
520
|
+
- insert:
|
|
521
|
+
- id: is-update
|
|
522
|
+
name: '@infinisys/is-update'
|
|
523
|
+
config: {}
|
|
524
|
+
|
|
525
|
+
# ---- @infinisys/is-offpeak --------------------------------------------------
|
|
526
|
+
- insert:
|
|
527
|
+
- id: is-offpeak
|
|
528
|
+
name: '@infinisys/is-offpeak'
|
|
529
|
+
config: {}
|
|
530
|
+
|
|
531
|
+
# ---- @infinisys/is-toolchain-cache ------------------------------------------
|
|
532
|
+
- insert:
|
|
533
|
+
- id: is-toolchain-cache
|
|
534
|
+
name: '@infinisys/is-toolchain-cache'
|
|
535
|
+
config: {}
|
|
536
|
+
|
|
537
|
+
# ---- @infinisys/is-disk-guard -----------------------------------------------
|
|
538
|
+
# Infinity disk guard.
|
|
539
|
+
#
|
|
540
|
+
# A projection checkpoint is one whole per-session document replaced atomically
|
|
541
|
+
# (temp + fsync + rename + directory fsync), and a team session writes one per
|
|
542
|
+
# agent. Measured on a live profile: 8.3 MB of whole-document rewrite per two
|
|
543
|
+
# minutes against 0.7 MB of genuinely new data, 93% of it this cache — a parity
|
|
544
|
+
# RAID turns each of those into read-modify-write of the stripes.
|
|
545
|
+
#
|
|
546
|
+
# Three things make that cache cheap, in the order they cost:
|
|
547
|
+
#
|
|
548
|
+
# 1. It stays a cache. One checkpoint per minute (or per two thousand events)
|
|
549
|
+
# instead of per five seconds, and a turn end flushes the session log without
|
|
550
|
+
# rewriting the whole document — the next throttled checkpoint carries it.
|
|
551
|
+
# A stale cache costs replay time on the next start, never a message.
|
|
552
|
+
# 2. It stops carrying history it can refold. The context timeline, the context
|
|
553
|
+
# headers and the turn outline grow with the conversation, so the same bytes
|
|
554
|
+
# were rewritten for the rest of a session's life. The cache keeps a recent
|
|
555
|
+
# window; the session log keeps all of it.
|
|
556
|
+
# 3. Session creation and disposal still checkpoint immediately: a new document
|
|
557
|
+
# and a session going cold have no later checkpoint to fall back on.
|
|
558
|
+
# 4. The same disease one process over. The context-compression proxy in front of
|
|
559
|
+
# the model keeps every session twice — a SQLite index it reads, plus a legacy
|
|
560
|
+
# JSON envelope it still rewrites whole — and on the measured machine that one
|
|
561
|
+
# process wrote 11 MB/s and read 107 MB/s of its own state while the disk sat
|
|
562
|
+
# at 96%. The guard passes it a slower save cadence, a larger journal window
|
|
563
|
+
# and more sessions kept in memory when the host launches it; `envelope: off`
|
|
564
|
+
# drops the duplicate copy and `quickCheck: off` skips the whole-index
|
|
565
|
+
# integrity scan every start pays for.
|
|
566
|
+
# 5. And it stops the save itself from carrying the whole row. One save is a
|
|
567
|
+
# single upsert over every column of `sessions`, the multi-megabyte state
|
|
568
|
+
# blobs included, so a save that only moves `updated_at` still drags them
|
|
569
|
+
# along. A preload attached at launch compares each save with the previous one
|
|
570
|
+
# and writes only the columns that moved; a save that carries nothing new
|
|
571
|
+
# writes nothing. It hooks the proxy's own SQLite binding at runtime — no file
|
|
572
|
+
# of the proxy is edited, and an unfamiliar statement shape is passed through
|
|
573
|
+
# unchanged.
|
|
574
|
+
# 6. And it stops a burst of saves from paying a burst of fsyncs. SQLite commits
|
|
575
|
+
# every statement on its own, so the proxy's thousands of small rows a minute
|
|
576
|
+
# became thousands of tiny writes a second — measured with `iostat -x`: 1,100
|
|
577
|
+
# to 1,400 writes/s of 4 to 24 KB, 70 to 120 ms each, the device 96 to 100 %
|
|
578
|
+
# busy while the CPU sat at 1 %. The hook now holds the burst in one
|
|
579
|
+
# transaction and commits it on a short window (200 ms), so the same saves pay
|
|
580
|
+
# one fsync per window instead of one per row. A crash can lose at most that
|
|
581
|
+
# window, which the proxy regenerates from its own journal.
|
|
582
|
+
- insert:
|
|
583
|
+
- id: is-disk-guard
|
|
584
|
+
name: '@infinisys/is-disk-guard'
|
|
585
|
+
config:
|
|
586
|
+
projectionCache:
|
|
587
|
+
writeIntervalMs: 60000
|
|
588
|
+
writeEveryEvents: 2000
|
|
589
|
+
coalesceTurnEnd: true
|
|
590
|
+
rows:
|
|
591
|
+
contextTimeline:
|
|
592
|
+
surface: 300
|
|
593
|
+
requests: 80
|
|
594
|
+
commands: 120
|
|
595
|
+
events: 200
|
|
596
|
+
contextHeaders:
|
|
597
|
+
headers: 2
|
|
598
|
+
turnOutline:
|
|
599
|
+
turns: 30
|
|
600
|
+
proxy:
|
|
601
|
+
debounceMs: 15000 # 每 15 秒才落一次盘;一次保存是整份状态重写,间隔直接决定写盘量
|
|
602
|
+
walJournalSizeLimitBytes: 67108864
|
|
603
|
+
residentMaxBytes: 2147483648
|
|
604
|
+
envelope: off # 索引已是唯一读取路径;旧信封文件留在盘上不动
|
|
605
|
+
watermark: on # 把代理的水印带回下一轮请求,命中重发快路径(换掉每回合的整段解析)
|
|
606
|
+
quickCheck: off # 开机全库自检要读完整索引(实测 688MB);要保留就写 on
|
|
607
|
+
batchMs: 200 # 一批保存合成一个事务,一次 fsync;0 关闭批提交(20 – 2000)
|
|
608
|
+
|
|
609
|
+
# ---- @infinisys/is-web-access -----------------------------------------------
|
|
610
|
+
# The Infinity web access bundle.
|
|
611
|
+
#
|
|
612
|
+
# `web` names which fetch provider `ctx.web.fetch` resolves, and a patch
|
|
613
|
+
# replaces the targeted row's whole `config` — so every key the base row owns is
|
|
614
|
+
# restated here, including the search provider this bundle does not change.
|
|
615
|
+
#
|
|
616
|
+
# `infinity-http` is the provider registered below. It keeps the shipped
|
|
617
|
+
# retrieval rules (HTTP(S) only, no credentials, same-origin redirects, size and
|
|
618
|
+
# character caps) and adds the one thing the shipped provider hard-codes: whether
|
|
619
|
+
# a destination that resolves to a non-public address is refused. That answer is
|
|
620
|
+
# a user setting, read per request, so flipping the switch needs no restart.
|
|
621
|
+
- id: web
|
|
622
|
+
config:
|
|
623
|
+
searchProvider: deepseek-official
|
|
624
|
+
fetchProvider: infinity-http
|
|
625
|
+
|
|
626
|
+
- insert:
|
|
627
|
+
- id: is-web-access
|
|
628
|
+
name: '@infinisys/is-web-access'
|
|
629
|
+
config: {}
|
|
630
|
+
|
|
631
|
+
# ---- @infinisys/is-stream-guard ---------------------------------------------
|
|
632
|
+
- insert:
|
|
633
|
+
- id: is-stream-guard
|
|
634
|
+
name: '@infinisys/is-stream-guard'
|
|
635
|
+
config: {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infinisys/fabric",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "One bundle that applies every Infinity Fabric plugin in the supported order.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://gitfox.studio/infinity/Fabric.git",
|
|
9
|
+
"directory": "packages/fabric"
|
|
10
|
+
},
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=22.13.0",
|
|
13
|
+
"dsh": ">=0.2.2-rc.1 <0.3.0"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@infinisys/is-identity": "^0.3.0",
|
|
21
|
+
"@infinisys/is-settings": "^0.1.0",
|
|
22
|
+
"@infinisys/is-devops": "^0.1.0",
|
|
23
|
+
"@infinisys/is-fabric-team": "^0.1.1",
|
|
24
|
+
"@infinisys/is-im": "^0.1.0",
|
|
25
|
+
"@infinisys/is-team-language": "^0.1.0",
|
|
26
|
+
"@infinisys/is-update": "^0.1.0",
|
|
27
|
+
"@infinisys/is-offpeak": "^0.1.0",
|
|
28
|
+
"@infinisys/is-toolchain-cache": "^0.1.0",
|
|
29
|
+
"@infinisys/is-disk-guard": "^0.7.0",
|
|
30
|
+
"@infinisys/is-web-access": "^0.1.0",
|
|
31
|
+
"@infinisys/is-stream-guard": "^0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"cordis.patch.yml",
|
|
35
|
+
"README.md",
|
|
36
|
+
"package.json"
|
|
37
|
+
],
|
|
38
|
+
"dsh": {
|
|
39
|
+
"bundle": {
|
|
40
|
+
"patch": "./cordis.patch.yml"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
6
43
|
}
|