@mokuyoaxis/dsh-iris 0.1.3 → 0.2.0

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 (91) hide show
  1. package/.dsh/skills/iris-compose-media/SKILL.md +23 -49
  2. package/.dsh/skills/iris-compose-media/references/task-v2-recovery.md +30 -0
  3. package/.dsh/skills/iris-compose-media/references/workflows.md +38 -0
  4. package/.dsh/skills/iris-verify-ui/SKILL.md +3 -25
  5. package/.dsh/skills/iris-verify-ui/agents/openai.yaml +4 -0
  6. package/.dsh/skills/iris-verify-ui/references/verdict-and-degradation.md +31 -0
  7. package/CHANGELOG.md +77 -2
  8. package/README.en.md +98 -19
  9. package/README.md +98 -19
  10. package/bin/dsh-iris.js +392 -13
  11. package/docs/AGENT_QUICKSTART.md +35 -0
  12. package/docs/ARCHITECTURE.md +82 -52
  13. package/docs/ARTIFACT_LIBRARY.md +24 -0
  14. package/docs/ARTIFACT_MANIFEST.md +60 -0
  15. package/docs/CORE_RUNTIME_CONTRACT.md +83 -0
  16. package/docs/DSH_CORE_MIGRATION.md +106 -0
  17. package/docs/DSH_RC2_ADAPTATION.md +36 -0
  18. package/docs/HEADLESS_CLI.md +217 -0
  19. package/docs/HOST_ADAPTER_CONTRACT.md +105 -0
  20. package/docs/HOST_DOCTOR.md +49 -0
  21. package/docs/MODEL_PORT_CONTRACT.md +300 -0
  22. package/docs/PROVIDER_ADAPTER_CONTRACT.md +138 -0
  23. package/docs/PROVIDER_HEALTH.md +39 -0
  24. package/docs/PROVIDER_RUNTIME_HARNESS.md +33 -0
  25. package/docs/PROVIDER_SUBMISSION_CONTRACT.md +2 -2
  26. package/docs/ROADMAP.md +42 -76
  27. package/docs/SECURITY.md +10 -5
  28. package/docs/TASK_SEMANTICS.md +3 -2
  29. package/docs/assets/diagrams/iris-architecture.png +0 -0
  30. package/docs/assets/diagrams/iris-architecture.svg +5 -5
  31. package/docs/assets/logo/README.md +55 -0
  32. package/docs/assets/logo/iris-bubble-concept.svg +67 -0
  33. package/docs/assets/logo/iris-bubble.svg +14 -0
  34. package/docs/assets/logo/iris-interim-flower.png +0 -0
  35. package/docs/assets/logo/iris-logo-mono-inverse.svg +78 -0
  36. package/docs/assets/logo/iris-logo-mono.svg +78 -0
  37. package/docs/assets/logo/iris-logo.svg +78 -0
  38. package/docs/assets/logo/iris-mark-mono-inverse.svg +42 -0
  39. package/docs/assets/logo/iris-mark-mono.svg +42 -0
  40. package/docs/assets/logo/iris-mark.svg +42 -0
  41. package/docs/releases/0.1.4.md +59 -0
  42. package/docs/releases/0.2.0.md +48 -0
  43. package/lib/actions.js +673 -525
  44. package/lib/adapters.js +58 -21
  45. package/lib/api.js +182 -16
  46. package/lib/artifacts.js +239 -0
  47. package/lib/bundled-skills.js +5 -5
  48. package/lib/client.js +1116 -86
  49. package/lib/command-service.js +420 -0
  50. package/lib/config.js +245 -49
  51. package/lib/core-artifact-store.js +598 -0
  52. package/lib/core-artifacts.js +4 -0
  53. package/lib/core-attention.js +103 -0
  54. package/lib/core-contract.js +105 -0
  55. package/lib/core-doctor.js +41 -0
  56. package/lib/core-lease-recovery.js +170 -0
  57. package/lib/core-runtime.js +232 -0
  58. package/lib/core-tasks.js +560 -0
  59. package/lib/core-user-projection.js +192 -0
  60. package/lib/doctor.js +260 -30
  61. package/lib/dsh-core-adapter.js +599 -0
  62. package/lib/dsh-host-adapter.js +240 -0
  63. package/lib/generation-input.js +95 -0
  64. package/lib/guard.js +3 -3
  65. package/lib/host-contract.js +131 -0
  66. package/lib/host-runtime.js +156 -0
  67. package/lib/index.js +255 -166
  68. package/lib/locate.js +1 -1
  69. package/lib/media.js +16 -6
  70. package/lib/model-invoker.js +218 -0
  71. package/lib/model-port-contract.js +333 -0
  72. package/lib/models.js +97 -11
  73. package/lib/prompt-optimizer.js +10 -20
  74. package/lib/provider-adapter.js +397 -0
  75. package/lib/provider-adapters.js +342 -0
  76. package/lib/provider-catalog.js +171 -0
  77. package/lib/provider-contract.js +72 -3
  78. package/lib/provider-health.js +59 -0
  79. package/lib/provider-protocol.js +51 -2
  80. package/lib/provider-task-runner.js +328 -0
  81. package/lib/render.js +43 -12
  82. package/lib/tasks.js +45 -9
  83. package/lib/vision.js +51 -56
  84. package/package.json +20 -14
  85. package/user_guide.md +67 -12
  86. package/docs/assets/diagrams/iris-architecture.drawio +0 -1
  87. package/docs/assets/diagrams/iris-task-lifecycle.drawio +0 -1
  88. package/docs/assets/diagrams/iris-workflow-compose.drawio +0 -1
  89. package/docs/releases/0.1.1.md +0 -51
  90. package/docs/releases/0.1.2.md +0 -26
  91. package/docs/releases/0.1.3.md +0 -30
@@ -0,0 +1,39 @@
1
+ # Provider 与能力健康状态
2
+
3
+ 状态:v0.1.4 候选契约。
4
+
5
+ Iris 用持久化证据描述“当前配置是否存在、最近是否实际成功、是否出现明确凭据失败”。它不是后台监控,也不等同于 Host Doctor。
6
+
7
+ ## 四种状态
8
+
9
+ | 状态 | 颜色 | 含义 |
10
+ |---|---|---|
11
+ | `unconfigured` | 灰色 | 当前能力没有启用且带凭据的候选模型 |
12
+ | `configured` | 蓝色 | 已配置,但没有 7 天内的成功证据;旧证据过期后也回到此状态 |
13
+ | `verified` | 绿色 | 该 Provider × Model × Capability 在 7 天内通过显式实测或真实任务成功 |
14
+ | `failed` | 暗红色 | 最近的决定性证据是 401、403 或明确的认证/权限失败 |
15
+
16
+ 状态按 `Provider × Model × Capability` 记录,不因同名模型而合并。模型、Key、Base URL、协议或能力模型等关键配置变化会清空相关旧证据;移除模型或能力标签也会移除不再成立的记录。
17
+
18
+ ## 什么会改变状态
19
+
20
+ 显式“模型实测”和正常用户任务都会产生证据。视觉、图片和 TTS 可从模型池逐项实测;视频与转写不会发送空样本探针,应使用真实的视频生成或音频转写任务验证。成功受理、同步完成或视觉成功会刷新绿色及其成功时间。
21
+
22
+ Iris 不做定时后台探测,也不会为了让图标变绿而产生隐形请求或费用。429/额度限制、网络错误、5xx、内容安全、用户取消和受理未知属于临时或不确定事实:它们可以记录为最近观察,但不会把 7 天内的绿色覆盖成红色。只有明确认证或权限失败才会变暗红;移除 API Key 后回到灰色。
23
+
24
+ ## failover 与泡泡汇总
25
+
26
+ 每项能力按当前有序 failover 候选汇总:
27
+
28
+ 1. 任一路候选为绿色,能力为绿色;
29
+ 2. 否则任一路为蓝色,能力为蓝色;
30
+ 3. 只有所有已配置候选都为暗红时,能力才为暗红;
31
+ 4. 没有候选时为灰色。
32
+
33
+ 主泡泡再按五项能力使用同一保守规则汇总。汇总证据时间只从决定汇总颜色的候选中选择,例如绿色不会显示另一条较新蓝色临时观察的时间。界面同时显示文字和证据时间,不要求用户只凭颜色判断。
34
+
35
+ ## 与诊断的区别
36
+
37
+ Host Doctor 只检查 DSH、Iris 注册、Host Port、客户端版本和 UI Slot 是否装载;它零网络、零计费,不能证明 API Key 或具体模型可用。Provider 健康来自模型实测和真实业务请求,才回答供应商侧是否近期成功。离线 `dsh-iris doctor` 则检查本地运行时、配置、存储与任务一致性,三者不能互相替代。
38
+
39
+ 健康事实保存在 `$DSH_HOME/iris/v1/providers.json`,状态 API 仅返回脱敏标量。错误说明会移除 Authorization、Key、签名参数、私有路径和已配置的完整 API Key。
@@ -0,0 +1,33 @@
1
+ # FakeProvider 生命周期验收器
2
+
3
+ FakeProvider harness 是 Core 的零网络生命周期验收器,不是可配置的正式供应商,也不会出现在用户模型列表中。它以脚本化 fixture 驱动真实 Provider Adapter v0、Core Runtime、Task/Attempt v0 和 Artifact v0,验证远端任务边界而不产生 API 请求或费用。
4
+
5
+ ## 覆盖链路
6
+
7
+ ```text
8
+ Task → 写前 Attempt → submit → accepted → poll
9
+ ├─ pending → 重启 → poll
10
+ ├─ succeeded → download → Artifact
11
+ ├─ failed / unknown / canceled
12
+ └─ cancel → confirmed / unknown
13
+ ```
14
+
15
+ - `submit` 前必须先持久化稳定 Attempt ID;写前失败时 Provider 调用次数为零。
16
+ - 只有明确 `not_accepted` 才能进入下一候选;`accepted` 或 `acceptance_unknown` 后禁止自动重提。
17
+ - 已落盘 `remoteTaskId` 的任务可由新 Runtime 恢复观察;停在 `submitting` 且没有受理结果的记录只能恢复为 `unknown`。
18
+ - Provider 成功与本地交付是两个事实。下载失败保留 `outcome=succeeded`、`deliveryState=failed`;重新交付只执行 `poll/download`。
19
+ - 只有 Provider 明确返回 `canceled` 才记录 `remote_confirmed`;不支持或结果未知均保持 `outcome=unknown`。
20
+ - 取消响应落盘前中断会恢复为未知;待交付或下载中断保留远端成功并标记交付失败,不自动重新生成。
21
+ - 下载 URL 只在单次调用内存中传递,不写入 Task。成功文件进入 Core Artifact,Host URL、DSH attachment 和会话展示不属于 Core 事实。
22
+
23
+ ## 当前限制
24
+
25
+ 每次 `observe` 只轮询一次,不拥有后台 timer;同一 Runtime 内同一 Task 的并发操作以 `IRIS_PROVIDER_TASK_BUSY` 拒绝。交付只验收一个 `image/png` 产物;重新交付需有持久化的远端任务 ID。Task v0 尚未迁移 0.1.4 的任务文件,也未形成公开 package export。多产物、内容哈希、关系边、索引重建和孤儿回收由 Artifact Manifest 阶段完成。
26
+
27
+ 运行单项验收:
28
+
29
+ ```bash
30
+ node tests/provider-task-runner.mjs
31
+ ```
32
+
33
+ 完整回归仍使用 `npm test` 和 `npm run lint`。
@@ -1,6 +1,6 @@
1
1
  # Iris Provider 提交契约 v0
2
2
 
3
- 状态:**v0.1.3 最小内部契约,已覆盖现有生成能力。** 图片、视频、转写与 TTS 均执行本契约;完整 discovery、poll、cancel、download conformance 留到 v0.1.4。
3
+ 状态:**v0.1.3 最小提交契约已实现;v0.1.4 已纳入完整 Provider Adapter v0。** 图片、视频、转写与 TTS 均执行本契约;discovery、poll、cancel、download 与 error mapping 见 [完整生命周期契约](PROVIDER_ADAPTER_CONTRACT.md)。
4
4
 
5
5
  ## 提交结果
6
6
 
@@ -57,4 +57,4 @@ Provider `submit()` 必须返回以下四种结构之一:
57
57
 
58
58
  429 等可证明未创建任务的明确 4xx 拒绝可进入下一候选;408、409、425、499、5xx、网络异常、超时和成功响应缺少必要结果一律停止并记录 `acceptance=unknown`。同步生成已经成功后,下载或落盘失败记录为 `outcome=succeeded / deliveryState=failed`,不会重新生成。
59
59
 
60
- 视频、转写与 TTS 也已使用相同边界:视频和转写分别持久化 `prepare/upload/submit` stage,上传失败只表示生成请求未受理;TTS 同步成功则先记 `completed/accepted` 再交付音频。工作台已经消费稳定的人类状态,并提供重新观察、重新交付、提醒已读/恢复和需确认费用的知情重试;v0.1.4 再完成 discovery、poll、cancel、download 等完整 Provider conformance。
60
+ 视频、转写与 TTS 使用同一受理边界,但提交前输入准备不自动成为 Core 事实。当前 s2v 仍走 legacy 链并可在 legacy Attempt 记录上传错误;Core 转写的 `audio_path` 在 Host/CLI 边界先上传,失败以脱敏的 `stage=upload / acceptance=not_accepted` 返回调用方,零 submit、零 Core Task。准备成功后才创建 Core Task/Attempt 并进入写前 submit;TTS 同步成功则先记 `completed/accepted` 再交付音频。工作台消费稳定的人类状态,并提供重新观察、重新交付、提醒已读/恢复和需确认费用的知情重试。v0.1.4 已将 discovery、submit、poll、cancel、download 与 error mapping 收口到统一 Adapter,并由零网络 conformance runner 覆盖现有 DashScope/OpenAI Images 路径。
package/docs/ROADMAP.md CHANGED
@@ -1,100 +1,66 @@
1
1
  # 路线图
2
2
 
3
- dsh-iris 已具备媒体生成、视觉处理和任务管理主流程。长期方向是宿主无关的多模态生产运行时,DSH 是首个受支持宿主。当前仍通过 DSH 插件使用,独立 Core、CLI 和工作台尚未实现。
4
-
5
- 变更详情见[变更记录](../CHANGELOG.md),完整工具清单见[README](../README.md)。
3
+ Iris 正从 DSH 媒体插件演进为可独立运行、可接入不同 Agent 宿主的媒体生产核心。本文只列当前状态与后续方向;历史版本的具体改动见[变更记录](../CHANGELOG.md),内部实现顺序不在公开路线图中展开。
6
4
 
7
5
  ## 当前状态
8
6
 
9
- 现有功能包括:
10
-
11
- - 图像、视频、语音生成和音频转写
12
- - 看图问答、OCR、定位、裁剪与像素比较
13
- - 视频抽帧和多模态摘要
14
- - 多供应商模型池与复合模型身份
15
- - 浏览器上传、会话附件和宿主路径输入
16
- - 异步任务恢复、取消传播、SSE 状态更新和授权媒体链接
17
- - 面向 Agent 与用户的统一视频生成实现
18
- - 两个随包 Agent Skills:UI 视觉验收与多步骤媒体编排;0.1.2 会在插件启用时自动注册
19
-
20
- 当前发布版本为 `v0.1.2`。0.1.1 完成配置独立、安全与工程收口,并把 Web loader 适配固定到已验证的 DSH `0.1.2-rc.1` 接口;更高预览版在进入支持范围前需要重新运行宿主 canary。
21
-
22
- ## 已完成:0.1.1
7
+ 当前版本为 `0.2.0`,保留包名 `@mokuyoaxis/dsh-iris`,同时提供 DeepSeek Harness 插件和 Headless CLI。它提供:
23
8
 
24
- ### 配置独立与工程收口
9
+ - 图片、视频和语音生成,音频转写;
10
+ - 看图问答、OCR、目标定位、裁剪、像素比较、视频抽帧和摘要;
11
+ - 多供应商模型池与能力分配;
12
+ - 可恢复的异步任务、受理边界和人工接管;
13
+ - 独立作品库、Iris 工作台、🫧 提示词优化入口;
14
+ - 两项随包 Agent Skill;
15
+ - Host/Provider Adapter、离线 Doctor 和零网络一致性测试。
25
16
 
26
- - 对齐公开文档和已发布标签,明确当前能力与未来方向。
27
- - Iris 独立保存配置;ai-paint 仅作为维护者未公开的本地前身和可选迁移来源,不是用户依赖。停止默认读取,仅保留显式指定本地来源的一次性安全导入。
28
- - 用 Node.js 调度测试,去除对 POSIX Shell 循环的依赖。
29
- - 绑定供应商凭据与协议端点,统一私有存储权限和流式原子落盘,并验证损坏配置恢复。
30
- - 将付费能力实测改为单项显式确认,视频与转写不做空样本自动探针。
31
- - 默认将 Iris HTTP 路由限制在回环 Host,为反代提供显式信任列表和认证部署说明。
32
- - 增加 Linux/Windows 与 Node.js 20.10/22 CI 矩阵、发布前测试护栏,并以当前 DSH 预览版完成宿主烟测。
33
- - 核对打包清单,记录真实环境和未验证平台。
17
+ 0.2.0 建立实例化 Core Runtime,打通无 DSH 的 crop、四种媒体生成提交、Task 观察与 Artifact 管理,并提供带内容哈希、关系边、可重建 Index 和孤儿恢复的 Artifact Manifest v0。crop 与图片、视频、语音、转写的新任务全部落到共享 Core Task/Attempt/Artifact:Host 负责有界观察、启动接管和 attachment/UI 投影;统一作品区与五类用户状态投影覆盖四种媒体工作,CLI、DSH API 和 UI 共用同一 Command Service 的人工控制面(重新观察、重新取回、取消、重试为新任务)。迁移过程中积累了真实 Provider canary 记录,详细范围与后续待验项以验收文档为准。s2v 数字人视频、视觉理解与提示词优化仍走原有链路;Core 公开 API 未冻结,详见 [Headless CLI](HEADLESS_CLI.md)、[FakeProvider 生命周期验收器](PROVIDER_RUNTIME_HARNESS.md)、[Artifact Manifest](ARTIFACT_MANIFEST.md)和 [DSH → Core 渐进迁移](DSH_CORE_MIGRATION.md)。
34
18
 
35
- ## 已完成:0.1.2
19
+ 第二个真实 Host Adapter 实现并验收后,计划将现有 GitHub 仓库更名为 Iris,并新建 `@mokuyoaxis/iris` npm 包,复用发布工作流。当前 0.2.0 保留名称;旧包后续单独维护另行决定。CLI、测试 fixture 与媒体 Provider 不算第二个 Host Adapter。
36
20
 
37
- ### 可见、可达与唯一身份
38
-
39
- - 保留 npm 包名 `@mokuyoaxis/dsh-iris`,以 “Iris Media for DSH” 作为展示名,并使用唯一 Cordis 行 ID 避免与另一款 `dsh-iris` 同装冲突。
40
- - 插件启用时自动注册两项随包 Skill,不要求用户克隆仓库、切换 cwd 或修改默认 Skill 搜索目录。
41
- - 中英文 README 直接展示已脱敏的 Android 真机截图与代表性生成图,完整流程保留独立画廊;根目录 `screenshots.json` 控制插件市场展示顺序。
42
- - 在 DSH 对话输入框提供可独立关闭的无框 🫧 提示词优化入口:使用半透明玻璃悬浮窗和窄屏底部面板,支持当前会话/固定模型路由、独立 thinking 策略与保守输出预算、预览写回,以及 JSON 导入导出和恢复默认。
43
- - 泡泡快捷历史只展示运行中任务与成功产物;功能状态灯不再依赖用户逐张点开卡片。
44
- - 本版不新增供应商分支,也不声称已完成独立 Core、任务语义 v2 或离线诊断。
21
+ 已发布 Iris `0.1.4` 的历史 DSH 范围为 `>=0.1.2-rc.1 <0.1.3-0` 和 `0.1.5-rc.1`,旧宿主应固定安装 `@mokuyoaxis/dsh-iris@0.1.4`。Iris `0.2.0` 只声明支持准确的 DSH `0.2.0-rc.2`,已通过真实安装服务隔离验收;历史旧版验收不继承到当前版本。修正与实机待验项见 [rc.2 适配说明](DSH_RC2_ADAPTATION.md)。其他版本需先通过独立 Host canary 才会加入支持范围,具体安装与市场版本选择见 [README](../README.md#最快开始)。
45
22
 
46
23
  ## 下一步
47
24
 
48
- ### 当前发行候选 0.1.3:可信任务与适配边界
49
-
50
- - 图片、视频、转写与 TTS 已区分未受理、已受理与受理未知,并使用一个 Task、多 Attempt、独立观察/交付/取消事实;规范见[Task/Attempt v2 语义契约](TASK_SEMANTICS.md)。
51
- - 零网络故障矩阵已覆盖提交响应丢失、受理后持久化失败、轮询耗尽、取消未知、各阶段重启、下载/落盘、上传残留、SSE 慢消费者与人工接管;证据见[故障注入矩阵](FAULT_INJECTION.md)。
52
- - 最小 Provider 提交契约和 Core 依赖守卫已冻结;完整 Host Adapter 和 Provider conformance 顺延到 0.1.4,避免把可靠性修复变成大重构。
53
- - 离线 `doctor()`、`dsh-iris doctor [--json]`、[架构](ARCHITECTURE.md)与[安全边界](SECURITY.md)已经提供;依赖 DSH 运行时的扩展诊断顺延到 0.1.4。
54
- - 在具备稳定录制条件后补充真实短视频证据;不以伪造或不稳定链接阻塞 0.1.2。
25
+ ### 后续 0.2.x
55
26
 
56
- ### 0.2.0:独立 Core 与产物记录
27
+ - 收藏、标签、搜索、筛选和批量导出;
28
+ - Artifact 关系边冻结 `retried-from` 类型,补全重试谱系(0.2.0 仅有 Task 级 `retriedFrom`);
29
+ - Core Task/Artifact 删除、清理与孤儿 purge(0.2.0 的 Headless CLI 和 DSH 工作台都保持 Core 只读;工作台现有删除、清空与孤儿清理只作用于 legacy `outputs/`);
30
+ - 鸢尾花与泡泡视觉身份;
31
+ - Gemini、Fal 和后续 Replicate Provider;
32
+ - 将提示词优化收口为 Core Prompt Engine 与共享 `prompt.optimize` Command,由 CLI 和 DSH 入口共同消费;DSH 只负责草稿读取、预览和写回;
33
+ - 冻结中立 TextModel Port,把 Ollama、兼容文本端点及其他文本模型后端与媒体 Provider Catalog 分离,避免通用文本模型淹没 Iris 媒体模型界面;
34
+ - 接入 ComfyUI、本地 TTS 等本地媒体 Provider,并补齐 `auth: none`、`billing: none`、同步完成语义和本地/远程 UI 区分;
35
+ - 有可信价格来源后的成本与策略展示。
57
36
 
58
- - 统一 Agent、工作台与 CLI 的命令执行核心,将 DSH 集成集中到宿主适配器。
59
- - 为产物保存内容哈希、来源和派生关系,支持检查与导出。
60
- - 在未安装 DSH 的干净环境完成本地动作和供应商任务验收。
61
- - 建立 Iris 正式产品视觉身份:以简约鸢尾花和泡泡为核心母题,完成可缩放 Logo、图标、单色版与深浅色适配,并替换临时字标。
62
- - 在统一 Provider Adapter 与 conformance 测试稳定后,依次接入 Gemini、Fal,并把 Replicate 排入后续 0.2.x。
37
+ ### 0.3 及以后
63
38
 
64
- ### 后续方向
65
-
66
- - 0.3:有界、可恢复的媒体工作流,以及用户显式启动的本地 API 和最小独立工作台。
67
- - 0.4:根据真实消费者需要开放供应商和宿主适配契约。
68
- - 1.0:冻结经过验证的公共契约和升级策略。版本表示目标聚合点,不代表发布日期承诺。
39
+ - `0.3`:Recipe、可恢复 Flow、显式启动的本地 API 和最小独立工作台;
40
+ - `0.4`:在有真实消费者后公开 Provider/Host SDK;
41
+ - `1.0`:冻结经过多宿主和升级验证的公共契约。
69
42
 
70
43
  ## 兼容性与限制
71
44
 
72
- - Node.js 最低版本为 20.10。
73
- - 图片处理依赖 `sharp`,非标准 libc 或移动终端环境可能没有可用的预编译包。
74
- - 视频抽帧与视频摘要依赖 `ffmpeg` 和 `ffprobe`。
75
- - WSL、远程浏览器和容器部署应优先使用上传或会话附件,避免混淆浏览器路径与宿主路径。
76
- - HTML 截图运行在离线沙箱中,远程资源和页面脚本不可用。
77
- - 模型发现只能列出候选项,具体能力需要通过实际请求确认。
78
- - Node 测试调度器不依赖 Bash,Linux/Windows × Node.js 20.10/22 自动化矩阵已经通过;原生 Windows/WSL 的 DSH 宿主实机冒烟仍待补充。
45
+ - Iris 0.2.0 的 Node.js 最低版本为 22.0.0;DSH 要求更高版本时以 DSH 为准。
46
+ - 图片处理依赖 `sharp`;视频抽帧和摘要依赖 `ffmpeg`、`ffprobe`。
47
+ - DSH 仍处于快速演进期。单个 Host Port 可以降级,但 DSH 若改变插件加载协议,仍需更新 DSH Adapter。
48
+ - 模型发现只列出候选项;真实能力必须由用户显式验证。
49
+ - 原生 Windows/WSL 的完整 DSH 宿主冒烟仍待补充。
50
+ - Headless CLI 当前开放 crop、图片/视频/语音/转写提交、Task 查询/单步观察与 Artifact 检查/导出;必须显式指定绝对数据根,且不会自动循环观察。0.2.0 的 Headless CLI 与 DSH 工作台都不提供 Core Task/Artifact 删除或清理能力;工作台现有破坏性动作只处理 legacy `outputs/`。Core 删除能力计划在 0.2.x 开放。
79
51
 
80
52
  ## 质量要求
81
53
 
82
- 计划中的改动应满足以下条件:
83
-
84
- - `npm test` 通过,并为新增行为补充有针对性的测试。
85
- - 不泄露供应商密钥、宿主绝对路径或未授权媒体内容。
86
- - 不在远端任务受理后自动重提生成请求。
87
- - 不让局部配置更新覆盖未修改字段。
88
- - 在支持的平台上保持 Agent 工具与工作台行为一致。
89
- - 发布前检查 npm 包内容和公开文档中的相对链接。
54
+ - 已受理或受理未知的远端任务不得自动重提。
55
+ - 同一数据根不得出现两个写者;reader 不产生隐式写入。
56
+ - Core/CLI 在 DSH/Cordis 不可解析时仍能装载和运行本地动作。
57
+ - Task、Attempt 和 Artifact 不保存凭据、私有 URL 或不必要的宿主绝对路径。
58
+ - 每项新增行为需有失败路径测试;发布前执行打包、敏感信息和仓库外安装检查。
90
59
 
91
60
  ## 暂不计划
92
61
 
93
- - 在插件内实现账号、权限或多租户系统。
94
- - 接管 DeepSeek Harness 的通用聊天模型配置。
95
- - 由 DSH 插件隐式启动独立后台服务或额外监听端口。
96
- - 在本地工作台阶段建设公网 SaaS、组织账号和多租户系统。
97
- - 自动探测全部模型能力并触发可能计费的请求。
98
- - 仅为未来可能使用的供应商预建没有调用方的适配层。
99
- - 为 0.1.2 临时接入尚无统一契约与测试基线的新供应商。
100
- - 为展示效果伪造实机截图、生成结果或短视频证据。
62
+ - 在插件中建设账号、多租户、计费或公网 SaaS;
63
+ - 由 DSH 插件隐式启动 daemon 或额外监听端口;
64
+ - 自动探测全部模型并产生不可见费用;
65
+ - 为没有真实调用方的 Provider 或 Host 预建空适配器;
66
+ - 在 Core 稳定前拆分多个 npm 包或重写技术栈。
package/docs/SECURITY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Iris 安全边界
2
2
 
3
- 状态:v0.1.3 当前实现。安全目标是避免凭据泄露、路径越权、跨站写入和因错误重试造成重复计费;Iris 与 DSH 仍是本机同一信任域内的预览软件,不构成多租户安全边界。
3
+ 状态:v0.1.4 候选实现。安全目标是避免凭据泄露、路径越权、跨站写入和因错误重试造成重复计费;Iris 与 DSH 仍是本机同一信任域内的预览软件,不构成多租户安全边界。
4
4
 
5
5
  ## 信任模型
6
6
 
@@ -15,6 +15,8 @@
15
15
 
16
16
  API、SSE 和 Doctor 只返回凭据存在性或掩码提示。Provider 错误会移除 Bearer token、常见 Key、签名查询参数、堆栈和私有绝对路径。不要把 `providers.json`、环境变量或含签名的临时 URL 上传到 Issue。
17
17
 
18
+ 健康证据与供应商配置同存于 `providers.json`,只保存模型、能力、时间、来源、错误分类、可选 HTTP 状态和脱敏短说明;状态 API 不返回完整 Key。关键凭据、端点或协议变化会清空旧证据,避免把另一组配置的成功错误沿用为当前事实。
19
+
18
20
  `ai-paint` 是维护者未公开的本地前身,不是用户依赖。Iris 只有在用户显式设置 `IRIS_IMPORT_WORKBENCH_CONFIG` 为绝对路径且自身配置为空时才做一次性导入,不扫描其他项目,也不回写来源文件。
19
21
 
20
22
  ## 受理与费用安全
@@ -26,13 +28,16 @@ API、SSE 和 Doctor 只返回凭据存在性或掩码提示。Provider 错误
26
28
  - “知情重试”必须单独确认可能重复任务或重复计费,并创建带 `retryOf/manualRetries` 关系的新 Task。创建后只归档原提醒,不改写原任务的未知事实;当前只对能从安全记录无损重建的文生图和文生视频开放,文件型输入和截断文本要求用户从原始输入重新发起。
27
29
  - “标为已读/恢复提醒”只操作有界的本地 `attentionEvents` 审计元数据,不发送网络请求,也不把用户处置等同于供应商已经受理。
28
30
  - Iris 当前没有凭空假设 DashScope 的远端取消协议。停止本地观察后若远端结果无法确认,状态保持 unknown。
31
+ - Provider 健康不做后台探测。只有 401、403 或明确认证/权限分类可变为暗红;429、网络、5xx、内容安全、取消与未知受理不得覆盖近期成功或授权自动重提。
29
32
 
30
33
  ## 文件、上传与媒体访问
31
34
 
32
35
  - 浏览器上传使用大小上限、随机文件名、`.part` 临时文件和完成后的原子改名;中断时清理临时文件,过期副本按 TTL 回收。
33
36
  - 输出文件名由 Iris 生成或通过 `basename` 收口,API 不返回宿主绝对路径。
34
- - 媒体播放链接使用随机能力令牌。令牌应视为临时访问凭据,不应发布到公网。
35
- - 清理任务元数据默认不删除产物;删除孤儿产物需要独立确认。
37
+ - legacy 任务与独立作品的媒体链接使用随机 128-bit 能力令牌。令牌应视为临时访问凭据,不应发布到公网。
38
+ - Core 媒体路由 `/iris/api/core/artifact/<artifact_id>/media` **没有独立 token**。它使用随机 96-bit Artifact ID 作为不可猜测的持有者标识,并叠加默认回环/显式 trusted Host、浏览器 `Origin`/`Sec-Fetch-Site` 拒绝跨站、`Cross-Origin-Resource-Policy: same-origin`、`Referrer-Policy: no-referrer` 与每次 SHA-256 校验。任何能访问受信 Host 且持有 Artifact ID 的客户端都能读取对应媒体;`IRIS_TRUSTED_HOSTS` 不是身份认证。不要把 Core Artifact ID 或媒体 URL 发布到不受信任位置。
39
+ - 清理任务元数据默认不删除作品;独立作品索引不保存 Prompt、Provider、Model 或任务关系。
40
+ - 删除单件作品、清空作品库或删除真正的孤儿文件都需要独立确认。作品删除会保留任务历史,但旧媒体链接将失效。
36
41
  - 符号链接不会被私有树权限收紧逻辑跟随。Doctor 会把 Iris 数据根为符号链接视为硬错误。
37
42
 
38
43
  ## Web 与渲染
@@ -44,9 +49,9 @@ API、SSE 和 Doctor 只返回凭据存在性或掩码提示。Provider 错误
44
49
 
45
50
  ## 离线 Doctor
46
51
 
47
- `dsh-iris doctor` 不启动 DSH,不发送供应商或计费请求,也不打印 API Key。它会在 Iris 数据目录或最近可写父目录创建一个随机小文件并立即删除,用于验证真实写权限。`--json` 与文本输出使用同一结果模型,退出码为:`0` 正常、`1` 有警告、`2` 有硬错误。
52
+ `dsh-iris doctor` 不启动 DSH,不发送供应商或计费请求,也不打印 API Key。默认 DSH 模式会在 Iris 数据目录或最近可写父目录创建一个随机小文件并立即删除,用于验证真实写权限;开发中的显式 `--data-root <abs>` Core 模式只读检查指定根的结构、索引、任务和租约,不做写探针,也不自动释放租约。`--json` 与文本输出使用同一结果模型,退出码为:`0` 正常、`1` 有警告、`2` 有硬错误。
48
53
 
49
- Doctor 不能证明 DSH 工具注册、浏览器、附件服务、客户端资源或真实 Provider 在线;这些属于后续 Host 扩展诊断。
54
+ Doctor 不能证明 DSH 工具注册、浏览器、附件服务、客户端资源或真实 Provider 在线;这些仍需各自验证。
50
55
 
51
56
  ## 报告问题
52
57
 
@@ -1,6 +1,6 @@
1
1
  # Iris Task/Attempt v2 语义契约
2
2
 
3
- 状态:**v0.1.3 已实现。** Task v2 已覆盖图片、视频、转写与 TTS,包括同步/异步、上传/提交、混合协议候选、工作台稳定用户态、状态流防倒退、重新观察、重新交付、提醒已读/恢复和知情人工重试。正式 Artifact Manifest、完整 Provider/Host Adapter 和宿主扩展诊断仍属于后续版本。
3
+ 状态:**v0.1.3 已实现;v0.1.4 Host/Provider Adapter、Host Doctor 与作品库 v0 已接入。** Task v2 已覆盖图片、视频、转写与 TTS,包括同步/异步、上传/提交、混合协议候选、工作台稳定用户态、状态流防倒退、重新观察、重新交付、提醒已读/恢复和知情人工重试。作品库 v0 只分离本地作品生命周期;正式 Artifact Manifest 仍属于后续工作。
4
4
 
5
5
  ## 1. 为什么需要 v2
6
6
 
@@ -94,6 +94,7 @@ Task v2 至少包含以下事实轴;字段值采用可序列化的 snake_case
94
94
  - 交付失败只允许重新下载/落盘,不允许重新生成。
95
95
  - 只有本地产物完成原子落盘并可读后,才写 `deliveryState=ready`。
96
96
  - 供应商明确返回生成失败时才写 `outcome=failed`。
97
+ - 任务历史与本地作品是两个生命周期:删除终态任务不得隐式删除作品,删除作品也不得改写任务事实;媒体是否仍可访问由作品库单独呈现。
97
98
 
98
99
  ## 7. 观察、超时与恢复
99
100
 
@@ -143,5 +144,5 @@ Task v2 至少包含以下事实轴;字段值采用可序列化的 snake_case
143
144
 
144
145
  - 不在语义冻结阶段重写全部任务存储或 UI。
145
146
  - 不新增 Gemini、Fal、Replicate 等供应商分支。
146
- - v0.1.3 包含零网络、可独立运行的离线 Doctor v0 与最薄 CLI;依赖 DSH `ctx` 的宿主扩展诊断、完整 Host Adapter 和 Artifact Manifest 不属于本版。
147
+ - v0.1.3 包含零网络、可独立运行的离线 Doctor v0 与最薄 CLI;v0.1.4 已接入 Host/Provider Adapter、Host Doctor 和不含谱系的作品库 v0。完整 Artifact Manifest 仍属于后续版本。
147
148
  - 不用更多自动重试换取表面成功率。
@@ -31,8 +31,8 @@
31
31
  <text x="590" y="170" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">GUI 动作卡</text>
32
32
  <text x="590" y="190.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">会话内的 Iris 操作入口</text>
33
33
  <rect x="790" y="138" width="290" height="72" rx="9" fill="#f5f6f8" stroke="#b9c2ce" stroke-width="1.6"/>
34
- <text x="935" y="170" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">Iris 工作台(三座位)</text>
35
- <text x="935" y="190.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">设置 · 进度 · 悬浮泡泡</text>
34
+ <text x="935" y="170" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">Iris 工作台(四座位)</text>
35
+ <text x="935" y="190.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">设置 · 进度 · 悬浮泡泡 · 提示词优化</text>
36
36
  <rect x="200" y="268" width="540" height="74" rx="9" fill="#eef3ff" stroke="#4d6bfe" stroke-width="1.6"/>
37
37
  <text x="470" y="301" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">统一动作层 · lib/actions.js</text>
38
38
  <text x="470" y="321.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">参数校验 · 输入解析(上传 / 会话附件 / 宿主路径)· failover 编排</text>
@@ -46,8 +46,8 @@
46
46
  <text x="236" y="557" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">任务系统 · lib/tasks.js</text>
47
47
  <text x="236" y="577.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">异步轮询 · 重启恢复 · 取消传播</text>
48
48
  <rect x="430" y="524" width="300" height="74" rx="9" fill="#eaf7ef" stroke="#2e9e5b" stroke-width="1.6"/>
49
- <text x="580" y="557" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">文件与媒体 · lib/media.js</text>
50
- <text x="580" y="577.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">uploads/ outputs/ · 令牌媒体链接 · Range 流式</text>
49
+ <text x="580" y="557" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">媒体与作品 · media.js + artifacts.js</text>
50
+ <text x="580" y="577.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">独立索引 · 令牌链接 · Range 流式</text>
51
51
  <rect x="790" y="524" width="290" height="74" rx="9" fill="#eef3ff" stroke="#4d6bfe" stroke-width="1.6"/>
52
52
  <text x="935" y="557" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">Web 客户端 · lib/client.js</text>
53
53
  <text x="935" y="577.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">三座位 UI · 共享状态订阅 + SSE</text>
@@ -56,7 +56,7 @@
56
56
  <text x="935" y="321.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">随包注册 iris-verify-ui / iris-compose-media</text>
57
57
  <rect x="66" y="690" width="470" height="56" rx="8" fill="#ffffff" stroke="#b9c2ce" stroke-width="1.3" stroke-dasharray="5 4"/>
58
58
  <text x="301" y="714" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">本地数据 · $DSH_HOME/iris/v1/</text>
59
- <text x="301" y="734.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">providers.json · tasks.json · uploads/ · outputs/(POSIX 0700 / 0600)</text>
59
+ <text x="301" y="734.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">providers.json · tasks.json · artifacts.json · uploads/ · outputs/</text>
60
60
  <rect x="580" y="706" width="560" height="64" rx="9" fill="#f5f6f8" stroke="#b9c2ce" stroke-width="1.6"/>
61
61
  <text x="860" y="734" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="14.5" font-weight="600" fill="#1f2328">媒体 / 视觉服务商</text>
62
62
  <text x="860" y="754.5" text-anchor="middle" font-family="'PingFang SC','Hiragino Sans GB','Noto Sans CJK SC','Noto Sans SC','Microsoft YaHei',sans-serif" font-size="12" font-weight="400" fill="#5b6472">DashScope 百炼 · OpenAI Images 兼容服务(凭据只发往官方 HTTPS 域名)</text>
@@ -0,0 +1,55 @@
1
+ # IRIS 视觉资产
2
+
3
+ 悬浮泡泡目前采用 `iris-bubble.svg` 曲线鸢尾花(2026-09-30 概念替换)。2026-09-15 的像素块(cell)Logo 与图标集保留作为历史设计资产。旧 `docs/assets/iris-wordmark.svg` 已不再使用,源码文件暂留作历史兼容。
4
+
5
+ **当前 README 头图为 `iris-interim-flower.png`**(2026-09-17):维护者自生成素材裁剪的灰度线稿鸢尾花,仅取花形、已去除源图中的第三方字标;属临时展示标。泡泡的新概念图标与正式品牌 Logo 分别评审,未把本次泡泡替换视为完整品牌定稿。
6
+
7
+ ## 悬浮泡泡概念
8
+
9
+ - [矢量图标](iris-bubble.svg):64×64 逻辑画布,透明背景、曲线花瓣、紫色层次、金色花心与青绿叶片;推荐以 26px 图元放入现有 44px 按钮。
10
+ - [概念展示](iris-bubble-concept.svg):放大花形、实际按钮尺寸与四种健康状态的并列预览。
11
+ - `lib/client.js` 的 `IRIS_MARK_PARTS` 保持相同的路径顺序与实色;内联 SVG 没有外部资源、字体、滤镜或 ID 引用。
12
+ - 本次只替换按钮图元;Android 浏览器的实际渲染仍需目视确认。
13
+
14
+ ## 历史像素资产
15
+
16
+ 设计语言:质朴、纯矩形像素块、无渐变无圆角;母题为鸢尾花(浅色旗瓣、深色垂瓣、橙色髯毛、细茎)+ 3×5 像素字 IRIS。全部资产由 `scripts/gen-logo.mjs` 从像素矩阵生成——**矩阵即设计源**,修改请先改矩阵再重新生成,保证可编辑可复现。
17
+
18
+ ## 文件
19
+
20
+ | 文件 | 用途 |
21
+ |---|---|
22
+ | `iris-logo.svg`(208×80) | 主锁定标志:彩色图形标 + 字标,浅色底适用(README、文档头) |
23
+ | `iris-logo-mono.svg` | 单色墨(`#1E1E24`),浅底单色场景 |
24
+ | `iris-logo-mono-inverse.svg` | 单色反白(`#F5F3FF`),深色底场景 |
25
+ | `iris-mark.svg`(88×96) | 历史紧凑型像素图形标,含 1 cell 留白 |
26
+ | `iris-mark-mono.svg` / `iris-mark-mono-inverse.svg` | 图形标的单色与反白版 |
27
+
28
+ ## 几何
29
+
30
+ - 基准单元 cell = 8 逻辑像素;`shape-rendering="crispEdges"`,缩放时保持锐利像素边缘。
31
+ - 图形标 9 列 × 10 行;字标每字 3×5 cell、字间距 1 cell;图形标与字标之间 2 cell;字标垂直居中于图形标。
32
+ - 旧 UI 内联版本曾采用同一剪影的反白像素块;当前泡泡使用上方曲线图标。
33
+
34
+ ## 最小尺寸与留白
35
+
36
+ - 锁定标志最小宽度 **104px(13 cell)**;再小请改用图形标。
37
+ - 图形标最小 **16px**(cell ≥ 1.6px),低于此尺寸仅保留剪影亦可辨识。
38
+ - 四周留白 ≥ 1 cell(图形标文件已内置 1 cell,锁定标志需自行留出)。
39
+ - 不要拉伸、旋转、加渐变/阴影/描边,不要改配色(深浅色场景请换用对应版本,不要叠滤色变)。
40
+
41
+ ## 配色
42
+
43
+ | 角色 | 色值 |
44
+ |---|---|
45
+ | 旗瓣 | `#8C77EE` |
46
+ | 垂瓣 | `#3F32A8` |
47
+ | 花心(髯毛) | `#F0B23E` |
48
+ | 茎 | `#4A9E6F` |
49
+ | 字标 | `#26204F` |
50
+ | 单色墨 | `#1E1E24` |
51
+ | 反白 | `#F5F3FF` |
52
+
53
+ ## 许可证
54
+
55
+ 原创美术资产,随仓库以 MIT License 发布;像素资产的来源矩阵在 `scripts/gen-logo.mjs`,新泡泡图标的矢量源在 `iris-bubble.svg`。再分发请保留来源与许可证。
@@ -0,0 +1,67 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="960" height="520" viewBox="0 0 960 520" role="img" aria-label="Iris floating flower concept">
2
+ <title>Iris floating flower — bubble concept</title>
3
+ <desc>Curved iris icon, enlarged silhouette and actual 44 pixel buttons with unconfigured, configured, verified and failed states.</desc>
4
+ <defs>
5
+ <g id="flower">
6
+ <path fill="#7db9a4" d="M30.5 39h3v18h-3z"/>
7
+ <path fill="#7db9a4" d="M32 55C24 55 20 50 19 44C26 45 31 48 32 55Z"/>
8
+ <path fill="#9cd1b7" d="M32 54C40 53 44 49 45 43C38 44 33 48 32 54Z"/>
9
+ <path fill="#b5a0f3" d="M29 31C18 30 11 22 15 14C24 13 30 20 29 31Z"/>
10
+ <path fill="#b5a0f3" d="M35 31C46 30 53 22 49 14C40 13 34 20 35 31Z"/>
11
+ <path fill="#e0d4ff" d="M32 7C24 13 23 23 32 34C41 23 40 13 32 7Z"/>
12
+ <path fill="#9b80df" d="M31 31C22 24 11 28 8 36C12 45 24 47 31 34Z"/>
13
+ <path fill="#9b80df" d="M33 31C42 24 53 28 56 36C52 45 40 47 33 34Z"/>
14
+ <path fill="#c4aff6" d="M32 29C24 35 23 44 32 50C41 44 40 35 32 29Z"/>
15
+ <path fill="#f2ce83" d="M32 31C29 32 28 34 29 36L32 40L35 36C36 34 35 32 32 31Z"/>
16
+ </g>
17
+ </defs>
18
+ <rect width="960" height="520" rx="24" fill="#f4f1f9"/>
19
+ <g font-family="sans-serif">
20
+ <text x="48" y="58" fill="#352950" font-size="28" font-weight="700" letter-spacing="4">IRIS</text>
21
+ <text x="48" y="85" fill="#786b8b" font-size="13" letter-spacing="2">FLOATING FLOWER / CONCEPT 02</text>
22
+ <text x="912" y="58" text-anchor="end" fill="#786b8b" font-size="12">SVG · 2026.09.30</text>
23
+ <rect x="32" y="112" width="400" height="376" rx="20" fill="#24212e"/>
24
+ <circle cx="232" cy="286" r="116" fill="#302b3c" stroke="#484056"/>
25
+ <use href="#flower" transform="translate(136 190) scale(3)"/>
26
+ <text x="232" y="449" text-anchor="middle" fill="#c4b5df" font-size="12" letter-spacing="2">CURVED PETALS · AMBER HEART</text>
27
+ <rect x="452" y="112" width="476" height="376" rx="20" fill="#ffffff"/>
28
+ <text x="482" y="151" fill="#352950" font-size="16" font-weight="600">44 px button · 26 px flower</text>
29
+ <text x="482" y="174" fill="#786b8b" font-size="12">Existing health ring and task badge</text>
30
+ <rect x="480" y="193" width="420" height="146" rx="14" fill="#26262e"/>
31
+ <g opacity=".55">
32
+ <circle cx="538" cy="256" r="22" fill="#32323c" stroke="#3a3a44"/>
33
+ <use href="#flower" transform="translate(525 243) scale(.40625)"/>
34
+ </g>
35
+ <circle cx="638" cy="256" r="25" fill="none" stroke="#6f9df6" opacity=".16" stroke-width="5"/>
36
+ <circle cx="638" cy="256" r="22" fill="#32323c" stroke="#6f9df6"/>
37
+ <use href="#flower" transform="translate(625 243) scale(.40625)"/>
38
+ <circle cx="738" cy="256" r="25" fill="none" stroke="#6fcf6f" opacity=".20" stroke-width="5"/>
39
+ <circle cx="738" cy="256" r="22" fill="#32323c" stroke="#6fcf6f"/>
40
+ <use href="#flower" transform="translate(725 243) scale(.40625)"/>
41
+ <g opacity=".72">
42
+ <circle cx="838" cy="256" r="25" fill="none" stroke="#b9656d" opacity=".16" stroke-width="5"/>
43
+ <circle cx="838" cy="256" r="22" fill="#32323c" stroke="#b9656d"/>
44
+ <use href="#flower" transform="translate(825 243) scale(.40625)"/>
45
+ </g>
46
+ <g fill="#bab3c7" font-size="10" text-anchor="middle">
47
+ <text x="538" y="306">UNCONFIGURED</text>
48
+ <text x="638" y="306">CONFIGURED</text>
49
+ <text x="738" y="306">VERIFIED</text>
50
+ <text x="838" y="306">FAILED</text>
51
+ </g>
52
+ <text x="482" y="377" fill="#786b8b" font-size="12">At 2×</text>
53
+ <circle cx="578" cy="409" r="44" fill="#32323c" stroke="#6f9df6" stroke-width="2"/>
54
+ <use href="#flower" transform="translate(552 383) scale(.8125)"/>
55
+ <circle cx="612" cy="377" r="16" fill="#d9a941"/>
56
+ <text x="612" y="382" text-anchor="middle" fill="#1a1a1e" font-size="15" font-weight="700">2</text>
57
+ <g transform="translate(672 393)">
58
+ <circle r="8" fill="#e0d4ff"/>
59
+ <circle cx="30" r="8" fill="#b5a0f3"/>
60
+ <circle cx="60" r="8" fill="#9b80df"/>
61
+ <circle cx="90" r="8" fill="#f2ce83"/>
62
+ <circle cx="120" r="8" fill="#7db9a4"/>
63
+ </g>
64
+ <text x="664" y="427" fill="#786b8b" font-size="12">Lilac · lavender · amber · sage</text>
65
+ <text x="482" y="469" fill="#93869f" font-size="11">Bubble icon proposal · brand wordmark reviewed separately</text>
66
+ </g>
67
+ </svg>
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-label="Iris" focusable="false">
2
+ <title>Iris — 曲线鸢尾花</title>
3
+ <desc>悬浮泡泡的概念图标:三片旗瓣、舒展垂瓣、金色花心与青绿叶片,透明背景。</desc>
4
+ <path fill="#7db9a4" d="M30.5 39h3v18h-3z"/>
5
+ <path fill="#7db9a4" d="M32 55C24 55 20 50 19 44C26 45 31 48 32 55Z"/>
6
+ <path fill="#9cd1b7" d="M32 54C40 53 44 49 45 43C38 44 33 48 32 54Z"/>
7
+ <path fill="#b5a0f3" d="M29 31C18 30 11 22 15 14C24 13 30 20 29 31Z"/>
8
+ <path fill="#b5a0f3" d="M35 31C46 30 53 22 49 14C40 13 34 20 35 31Z"/>
9
+ <path fill="#e0d4ff" d="M32 7C24 13 23 23 32 34C41 23 40 13 32 7Z"/>
10
+ <path fill="#9b80df" d="M31 31C22 24 11 28 8 36C12 45 24 47 31 34Z"/>
11
+ <path fill="#9b80df" d="M33 31C42 24 53 28 56 36C52 45 40 47 33 34Z"/>
12
+ <path fill="#c4aff6" d="M32 29C24 35 23 44 32 50C41 44 40 35 32 29Z"/>
13
+ <path fill="#f2ce83" d="M32 31C29 32 28 34 29 36L32 40L35 36C36 34 35 32 32 31Z"/>
14
+ </svg>
@@ -0,0 +1,78 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="208" height="80" viewBox="0 0 208 80" role="img" aria-label="IRIS 标志(单色反白)" shape-rendering="crispEdges">
2
+ <title>IRIS 标志(单色反白)</title>
3
+ <desc>像素块鸢尾花与 IRIS 像素字标,反白,深底色适用</desc>
4
+ <rect x="32" y="0" width="8" height="8" fill="#F5F3FF"/>
5
+ <rect x="24" y="8" width="8" height="8" fill="#F5F3FF"/>
6
+ <rect x="32" y="8" width="8" height="8" fill="#F5F3FF"/>
7
+ <rect x="40" y="8" width="8" height="8" fill="#F5F3FF"/>
8
+ <rect x="16" y="16" width="8" height="8" fill="#F5F3FF"/>
9
+ <rect x="24" y="16" width="8" height="8" fill="#F5F3FF"/>
10
+ <rect x="32" y="16" width="8" height="8" fill="#F5F3FF"/>
11
+ <rect x="40" y="16" width="8" height="8" fill="#F5F3FF"/>
12
+ <rect x="48" y="16" width="8" height="8" fill="#F5F3FF"/>
13
+ <rect x="16" y="24" width="8" height="8" fill="#F5F3FF"/>
14
+ <rect x="24" y="24" width="8" height="8" fill="#F5F3FF"/>
15
+ <rect x="32" y="24" width="8" height="8" fill="#F5F3FF"/>
16
+ <rect x="40" y="24" width="8" height="8" fill="#F5F3FF"/>
17
+ <rect x="48" y="24" width="8" height="8" fill="#F5F3FF"/>
18
+ <rect x="0" y="32" width="8" height="8" fill="#F5F3FF"/>
19
+ <rect x="24" y="32" width="8" height="8" fill="#F5F3FF"/>
20
+ <rect x="32" y="32" width="8" height="8" fill="#F5F3FF"/>
21
+ <rect x="40" y="32" width="8" height="8" fill="#F5F3FF"/>
22
+ <rect x="64" y="32" width="8" height="8" fill="#F5F3FF"/>
23
+ <rect x="0" y="40" width="8" height="8" fill="#F5F3FF"/>
24
+ <rect x="8" y="40" width="8" height="8" fill="#F5F3FF"/>
25
+ <rect x="24" y="40" width="8" height="8" fill="#F5F3FF"/>
26
+ <rect x="32" y="40" width="8" height="8" fill="#F5F3FF"/>
27
+ <rect x="40" y="40" width="8" height="8" fill="#F5F3FF"/>
28
+ <rect x="56" y="40" width="8" height="8" fill="#F5F3FF"/>
29
+ <rect x="64" y="40" width="8" height="8" fill="#F5F3FF"/>
30
+ <rect x="8" y="48" width="8" height="8" fill="#F5F3FF"/>
31
+ <rect x="16" y="48" width="8" height="8" fill="#F5F3FF"/>
32
+ <rect x="32" y="48" width="8" height="8" fill="#F5F3FF"/>
33
+ <rect x="48" y="48" width="8" height="8" fill="#F5F3FF"/>
34
+ <rect x="56" y="48" width="8" height="8" fill="#F5F3FF"/>
35
+ <rect x="16" y="56" width="8" height="8" fill="#F5F3FF"/>
36
+ <rect x="24" y="56" width="8" height="8" fill="#F5F3FF"/>
37
+ <rect x="32" y="56" width="8" height="8" fill="#F5F3FF"/>
38
+ <rect x="40" y="56" width="8" height="8" fill="#F5F3FF"/>
39
+ <rect x="48" y="56" width="8" height="8" fill="#F5F3FF"/>
40
+ <rect x="32" y="64" width="8" height="8" fill="#F5F3FF"/>
41
+ <rect x="32" y="72" width="8" height="8" fill="#F5F3FF"/>
42
+ <rect x="88" y="16" width="8" height="8" fill="#F5F3FF"/>
43
+ <rect x="96" y="16" width="8" height="8" fill="#F5F3FF"/>
44
+ <rect x="104" y="16" width="8" height="8" fill="#F5F3FF"/>
45
+ <rect x="96" y="24" width="8" height="8" fill="#F5F3FF"/>
46
+ <rect x="96" y="32" width="8" height="8" fill="#F5F3FF"/>
47
+ <rect x="96" y="40" width="8" height="8" fill="#F5F3FF"/>
48
+ <rect x="88" y="48" width="8" height="8" fill="#F5F3FF"/>
49
+ <rect x="96" y="48" width="8" height="8" fill="#F5F3FF"/>
50
+ <rect x="104" y="48" width="8" height="8" fill="#F5F3FF"/>
51
+ <rect x="120" y="16" width="8" height="8" fill="#F5F3FF"/>
52
+ <rect x="128" y="16" width="8" height="8" fill="#F5F3FF"/>
53
+ <rect x="120" y="24" width="8" height="8" fill="#F5F3FF"/>
54
+ <rect x="136" y="24" width="8" height="8" fill="#F5F3FF"/>
55
+ <rect x="120" y="32" width="8" height="8" fill="#F5F3FF"/>
56
+ <rect x="128" y="32" width="8" height="8" fill="#F5F3FF"/>
57
+ <rect x="120" y="40" width="8" height="8" fill="#F5F3FF"/>
58
+ <rect x="136" y="40" width="8" height="8" fill="#F5F3FF"/>
59
+ <rect x="120" y="48" width="8" height="8" fill="#F5F3FF"/>
60
+ <rect x="136" y="48" width="8" height="8" fill="#F5F3FF"/>
61
+ <rect x="152" y="16" width="8" height="8" fill="#F5F3FF"/>
62
+ <rect x="160" y="16" width="8" height="8" fill="#F5F3FF"/>
63
+ <rect x="168" y="16" width="8" height="8" fill="#F5F3FF"/>
64
+ <rect x="160" y="24" width="8" height="8" fill="#F5F3FF"/>
65
+ <rect x="160" y="32" width="8" height="8" fill="#F5F3FF"/>
66
+ <rect x="160" y="40" width="8" height="8" fill="#F5F3FF"/>
67
+ <rect x="152" y="48" width="8" height="8" fill="#F5F3FF"/>
68
+ <rect x="160" y="48" width="8" height="8" fill="#F5F3FF"/>
69
+ <rect x="168" y="48" width="8" height="8" fill="#F5F3FF"/>
70
+ <rect x="192" y="16" width="8" height="8" fill="#F5F3FF"/>
71
+ <rect x="200" y="16" width="8" height="8" fill="#F5F3FF"/>
72
+ <rect x="184" y="24" width="8" height="8" fill="#F5F3FF"/>
73
+ <rect x="192" y="32" width="8" height="8" fill="#F5F3FF"/>
74
+ <rect x="200" y="32" width="8" height="8" fill="#F5F3FF"/>
75
+ <rect x="200" y="40" width="8" height="8" fill="#F5F3FF"/>
76
+ <rect x="184" y="48" width="8" height="8" fill="#F5F3FF"/>
77
+ <rect x="192" y="48" width="8" height="8" fill="#F5F3FF"/>
78
+ </svg>