项目配置
Workflow、Conversation、Kanban 使用同一套项目配置。Studio 与 CLI Web 从工具栏打开“项目配置”,Server Web 从项目详情的配置页管理。没有声明字段时仍可添加自定义字段。
声明字段
项目根目录的 configuration.json 只声明结构和安全默认值,实际配置值通过面板管理:
{
"version": 1,
"fields": [
{ "name": "API_KEY", "type": "string", "label": "API key", "secret": true, "required": true },
{ "name": "retries", "type": "number", "defaultValue": 2 },
{ "name": "enabled", "type": "boolean", "defaultValue": false },
{ "name": "regions", "type": "string", "multiple": true, "options": [{ "value": "east" }, { "value": "west" }] },
{ "name": "metadata", "type": "json", "defaultValue": { "tags": [] } }
]
}
字段支持 string、有限 number、boolean、json 和 file,字符串可用 options 声明枚举。可选属性为 label、description、defaultValue、required、secret、control、options、accept。默认值使用原生 JSON 类型;敏感字段不要写真实默认值。配置字段与执行输入参数是两套结构。
file 字段直接选择本机文件并上传到当前连接的 Server,单文件上限 50 MiB,遵循版本字段限制并按账号隔离(个人附件不要求服务器数据写权限)。accept 可声明 MIME 类型(如 image/png、image/*)或扩展名(如 .json);不符合要求的文件不会上传。上传成功后显示文件名,保存配置才生效;失败保留原引用。单文件值是服务器元数据对象,包含 id、name、mimeType、size 和 storage: "server",不包含本地路径、文件内容或连接凭据。multiple: true 对字符串表示字符串数组,对文件表示最多 32 个服务器文件引用。清除字段只移除配置引用,不删除服务器文件。
{ "name": "imageFile", "type": "file", "label": "底图", "accept": ["image/png", "image/jpeg", "image/webp", "image/gif"] }
字段名以字母或下划线开头,后续允许字母、数字、下划线、点和连字符,最长 200 字符。字段名必须唯一。用户和小助手可以管理自定义字段,自定义字段结构属于整个项目,各套配置分别保存值。声明字段由 configuration.json 管理,自定义字段不能覆盖声明字段。重命名自定义字段会同步所有配置中的键;删除会清除所有配置中的对应值。
管理配置
Studio、CLI Web 和 Server Web 首先展示配置列表,正在使用的配置整行高亮,并显示带图标的“正在使用”标记;其他配置提供“使用此配置”按钮。点击配置名称进入详情页,再查看和编辑配置项。列表中的加号用于新建配置,行操作提供复制、重命名和删除。只有点击“使用此配置”才切换运行选择;切换期间显示进行中状态并禁用重复操作,失败后保留原选择并可重试。查看或保存其他配置的详情保留当前运行选择。详情顶部提供“返回列表”,有未保存的配置值或发布规则时,先保存或使用刷新图标放弃草稿后再返回。
“导入 / 导出”菜单集中处理 JSON 文件,菜单内注明导出包含敏感值。列表页导出全部配置,详情页可以导出正在查看的配置。字段区独立提供“添加字段”,自定义字段旁的铅笔和垃圾桶图标用于编辑与删除。底部保存区展示草稿状态;图标均带操作说明并支持键盘访问。
可以新建、复制、重命名、切换和删除命名配置,始终至少保留一套。字段可以直接编辑,无需先勾选;修改后点击底部“保存”统一生效。字段旁的重置图标清除覆盖值,有声明默认值时立即恢复默认值,没有默认值时清空并取消设置。未修改的字段保留原有状态;布尔值、多选项仍使用各自的勾选控件。缺少必填项可先保存,开始运行时才校验。新增声明字段使用默认值,移除声明字段后不再向运行暴露对应值。
移除声明字段或查看其他源码版本不会删除已保存值;再次声明同名字段时可恢复原值。同名项目声明暂时隐藏已有自定义字段定义,声明移除后恢复自定义定义。运行和导出只包含当前有效字段;显式删除自定义字段仍会清除所有配置中的对应值。
保存使用 revision 检查和原子写入。其他窗口或小助手修改配置时,面板更新已提交状态;有草稿时保留输入并提示冲突。刷新并丢弃草稿后再重新编辑;失败请求不会写入部分结果。
Studio、独立 CLI 与 CLI Web 共用本机用户目录下的配置存储。项目 package.json.id 为有效 UUID 时,按该应用 ID 绑定;同一应用的多个窗口和安装目录共用配置列表、自定义字段、值与当前选择,修改自动同步。不同应用分别存储;没有有效应用 ID 的原始目录仍按规范化后的真实路径隔离。应用配置尚不存在时,首次打开会保留当前目录已有的配置;已有应用配置不会被其他目录的旧值覆盖。会话和运行状态继续独立,等待任务恢复仍使用原目录保存的运行快照。Server 按项目和登录账号隔离,拥有项目读取权限的账号可以管理自己的配置。个人配置值不直接写入项目源码;启用分享后,仅作者显式允许携带的值进入发布模板。本地与 Server 的配置通过导入导出搬运。
导入与导出
导出当前或全部配置,得到版本为 1、kind 为 steamharness-project-configurations 的 JSON 文件,包含字段定义和完整有效值,包括敏感值。文件中的配置包含名称和值,不包含原配置 ID。文件字段导出完整服务器引用,不包含文件二进制;导入后仍需能够访问原服务器和项目中的文件。
导入默认新增配置、重新生成 ID 并保留当前选择。未存在的字段添加为自定义字段;同名字段类型、多选属性、选项或文件类型限制冲突、未知字段值、无效类型、无效 JSON 或超过 1 MiB 的请求会整批拒绝,不留下部分字段或配置。妥善保管含敏感值的导出文件。
Agent 模型列表
使用 Core Agent 的项目在配置详情第一项展示“AI 模型”。点击“添加模型”或列表中的编辑图标打开独立弹窗,在弹窗内通过分段切换选择“系统 AI”或“第三方 AI”,只展示对应表单;模型列表可同时包含两种来源。取消或按 Escape 关闭弹窗只放弃本次模型编辑,返回列表并恢复焦点。
Studio 与 CLI Web 中,当前配置的模型列表为空时,Workflow 和 Conversation 输入区的模型按钮显示“配置模型”。点击后直接进入当前配置详情并定位到“AI 模型”;Conversation 的失败消息也提供此入口。添加并保存模型后,输入区恢复已保存模型的选择。跳转保留消息草稿和当前运行配置;已有未保存的配置值或发布权限草稿时,先保存或放弃草稿再跳转。工具栏的齿轮仍从配置列表打开。
- 系统 AI:按需读取当前账号订阅,只需依次选择 Provider 和模型,显示名称自动取模型名称,无需填写模型名称。刷新目录保留模型草稿;所选订阅或模型消失时不自动改选,运行时提示检查订阅。没有可用订阅时提示管理订阅;未配置系统 AI 连接时仍可添加第三方模型。
- 第三方 AI:填写模型名称、模型 ID、API Key、Base URL 与 API 协议。支持
openai-completions、openai-responses、anthropic-messages;API Key 使用密码框,列表不展示密钥。 - 加入列表后可编辑、删除、设为默认。先应用正在编辑的模型,再保存整套配置;未完成的模型草稿会阻止保存或离开。列表第一项是默认模型,输入框只提供已保存模型的选择,不再管理 Provider。
模型列表使用保留字段 STEAMHARNESS_AGENT_MODELS(type: "json"、control: "ai-models")。Core 静态识别 createAgentNode、createAgentConversationProject、createAgentProjectParamResolver 或 defineAgentConversationExecutor 的调用后自动补入字段,不执行项目代码。本地配置服务在源码变更后更新识别结果,无需重开面板。间接封装无法被静态识别时,可在 configuration.json 显式声明此字段,使用 secret: true、defaultValue: [] 与 sharing: { "publish": true, "includeValue": false, "editable": true }。
项目只允许系统 AI 时,在源码 configuration.json 中显式声明模型字段并设置 allowThirdParty: false:
{
"version": 1,
"fields": [{
"name": "STEAMHARNESS_AGENT_MODELS",
"type": "json",
"control": "ai-models",
"allowThirdParty": false,
"secret": true,
"defaultValue": [],
"sharing": { "publish": true, "includeValue": false, "editable": true }
}]
}
未声明或设为 true 时保留两种来源。设为 false 后,Studio、CLI Web 与 Server Web 隐藏来源切换和第三方表单;直接保存、导入及小助手 CRUD 拒绝第三方条目,导入字段不能放宽项目声明。已有第三方条目保留供查看、完整备份、删除或改为系统 AI,但不会出现在运行选项中;默认选择第一项可用的系统模型。Core 同时拒绝显式 URL、API Key 和注入模型集合,项目也应移除自建直连分支。限制随运行快照冻结,等待恢复沿用原规则;发布模型字段时携带此规则而不自动携带个人值。这是项目代码声明,源码副本的持有者仍可修改代码。
发布草稿、发布预览和下载模板都遵循源码中的限制,旧草稿或模板不能放宽它。分发文件使用顶层 agentModelPolicy 保留限制,即使作者排除了整个模型字段也不丢失。包含历史第三方值的草稿仍可编辑;不携带这些值时可正常发布,携带时会拒绝发布。
每个条目包含唯一 id、name、model 和 source。source: "system" 使用 credentialId;source: "third-party" 使用 apiKind、baseUrl、apiKey。输入参数 model 是列表条目的 ID,运行时再映射到真实模型 ID。系统模型运行前校验当前账号仍有对应订阅和模型,不回退到其他订阅;第三方模型直接访问配置端点,不要求系统 AI 登录。
模型值按命名配置保存并随运行快照冻结。保存非当前配置保留运行选择;下一轮或下一次执行读取当前配置。模型列表与其他配置使用相同的导入导出、版本检查、权限和小助手 CRUD。自动字段默认发布结构而不携带值,API Key 不会自动进入发布模板;完整备份仍包含密钥,须妥善保管。
Conversation 与 Studio 小助手允许在同一会话中更换模型。修改、删除或替换配置中的模型不会隐藏已经完成的回复,也不会更改历史回复记录的模型名称;后续消息使用当前选中的可用模型并保留会话上下文。若新模型启动失败,错误由本次发送操作返回,已完成的历史回复继续正常展示。
运行时读取
const token = steamharness.getConfig<string>("API_KEY");
const task = steamharness.defineProject({
name: "configured-task",
async run(input, context) {
const enabled = context.config.enabled;
return { errCode: 0, errMessage: "", enabled };
},
});
SDK 提供 ProjectConfigurationSnapshot、context.config 和 steamharness.getConfig(key)。配置快照贯通参数解析器、executor、节点和 Agent,按运行隔离并冻结,不写入全局 process.env。运行之外的 getConfig 返回 undefined。直接使用 SDK 时可以向执行接口传入显式 configuration 快照,或通过 createLocalProjectConfigurationStore(projectDir) 管理本地配置。
显式快照也按 runId 保存,恢复时可省略 configuration,仍使用最初保存的值。宿主为保留同一 runId 的持久会话更新配置时,传入新的 configurationRunId;之后恢复该代配置需继续传入相同的 configurationRunId。本地存储的 snapshot({ runId, configuration }) 同样只在该身份首次使用时保存传入快照。
- Workflow 开始执行时冻结配置;恢复等待任务继续使用原快照。
- Conversation 的下一轮执行使用新配置;持久 Agent 等当前任务、排队输入和审批处理结束后停止旧运行,在下一次输入时用新参数重建运行配置,保留会话历史、分支和恢复状态。
- Kanban 保存后更新主页面与资源卡片预览,HTML 仍通过
window.steamHarnessKanban.getConfiguration().params读取原生值,并监听steamharness:kanban-configuration-change。指定配置 ID 的预览引用该配置;配置删除后显示不可用。
项目业务配置不自动读取 .env,不使用 .env.example,也不回退到进程环境变量。旧项目 env 和旧 Kanban 配置不迁移。请重新在面板填写配置。Server 部署、CI 和 Studio 内部通信变量继续由宿主管理。
CLI 与小助手
无界面本地接口使用 JSON 输入输出,和面板共用同一个存储:
printf '%s' '{"action":"get"}' | steamharness configuration ./my-project
小助手通过 Studio Control 的 get_configurations、manage_configurations 和 open_configurations 操作。工具的 input 是 JSON 字符串:本地指定 storage: "local" 和 projectDir;Server 指定 storage: "server"、projectId、target(draft、latest 或版本)。操作不依赖面板打开。
{
"storage": "local",
"projectDir": "/projects/my-project",
"call": { "action": "save", "revision": 3, "id": "profile-id", "values": { "enabled": true }, "unset": ["API_KEY"] }
}
查询返回字段、配置列表、当前 ID 与 revision。管理支持 create、duplicate、rename、save、select、delete、field.save、field.delete、import。读取工具的 export: true 导出全部,指定 id 导出当前配置。所有写操作必须传查询到的 revision;配置值操作显式指定 id。只读模式拒绝管理操作,目录与项目范围沿用 Studio 现有权限策略。冲突时保留拟修改内容,重新查询并协调后重试。
Server API 使用 GET /api/projects/:id/configurations?target=draft 读取,POST /api/projects/:id/configurations 提交 { "target": "draft", "call": { ... } }。成功返回统一 errCode: 0 包装,版本冲突返回 HTTP 409 和 data.code: "CONFIGURATION_CONFLICT"。配置 API 只保存静态结构和值,Server 不执行项目。
分享配置与权限(v2)
配置值、发布模板和个人覆盖值相互独立。作者在“发布与权限”中选择配置集与默认配置,分别设置 publish(发布字段)、includeValue(携带值)、editable(允许接收者修改)。未设置的规则默认是发布字段、允许修改、不携带值;defaultValue 也按值过滤。v1 项目保持原行为,保存发布草稿后才启用分享过滤,不会自动发布历史个人值。
配置项使用带边界的分组,模型使用独立列表并标明默认项。没有“发布与权限”入口时直接展示配置项,隐藏单独的“配置值”标签;作者仍可通过两个标签切换。Server Web 的配置值在宽屏分列展示,布尔值与名称同排,多选项横向排列。Server Web、Studio 与 CLI Web 的发布界面集中展示配置集与默认配置,字段权限按列对齐;JSON 子路径按需展开,更新发布值和字段从操作菜单进入,预览使用眼睛图标。
{
"version": 2,
"fields": [
{ "name": "privateToken", "type": "string", "secret": true, "sharing": { "publish": false } },
{ "name": "userToken", "type": "string", "secret": true },
{ "name": "endpoint", "type": "string", "defaultValue": "https://api.example.com", "sharing": { "includeValue": true, "editable": false } },
{ "name": "preferences", "type": "json", "defaultValue": { "region": "default", "theme": "auto" }, "sharing": { "includeValue": true }, "paths": { "/region": { "editable": false } } }
]
}
JSON 对象的路径使用 JSON Pointer:/ 编码为 ~1,~ 编码为 ~0。未声明的路径继承父规则,更具体的规则优先;整个字段不发布时,所有子字段都排除。数组作为整体编辑。面板提供子字段编辑及原始 JSON 编辑,服务端按实际变化检查所有路径;替换父对象、清空值、导入及小助手操作均不能绕过锁定。违规批次整体拒绝,返回 CONFIGURATION_FORBIDDEN(HTTP 403)。必填且只读的字段没有可发布值时不能发布。
JSON 父路径不发布、子路径单独发布时,子路径仍保留继承的携带值与编辑规则;过滤父路径不会解除子路径的锁定。
发布前可查看接收者预览。保存草稿会冻结所选配置的值;修改个人值后,需要显式“更新发布值”并重新保存草稿。发布接口同时校验源码摘要和发布草稿版本,并在临时目录生成过滤后的 configuration.json、configuration.template.json 和 configuration-assets/,不改写作者目录。已发布模板与版本固定;源码下载、分享链接和 Store 分发该版本的同一份内容。完整备份仍包含全部可读取值,不能用完整备份代替分享模板。
项目维护者、所有者或系统管理员可以保存官方草稿、管理官方模板。开发者可以发布已准备的项目版本,但不能修改官方规则。下载或复制项目、请求中的角色参数都不能获得原项目权限。下载用户管理自己的命名配置及自定义字段,不能修改作者字段定义、权限或模板;运行时合并模板与允许的个人值。个人配置只保存实际覆盖值,未修改的初始值随模板升级;仍可编辑的个人修改和自定义字段继续保留,新锁定路径停止应用旧覆盖值。类型冲突保留草稿并提示处理。运行中的 Workflow 和等待恢复任务继续使用原快照。
附件发布时复制为不可变副本,只携带保留字段引用的文件。下载会验证源码和附件摘要,把已验证模板与附件缓存到源码之外;离线可使用已验证版本并修改获准的个人值,官方草稿修改、发布和新版本下载需要联网。重新选择文件必须上传成功才能保存。下载权限仅授予相应模板和附件,不授予原项目其他数据的访问权限。
源码升级到尚未验证的模板时,配置读写会提示先联网下载该版本,个人值保持原样,运行中的任务仍可恢复原快照。附件上传使用当前已验证版本的权限,不受最新版权限变化影响。
发布接口与小助手
GET /api/projects/:id/configurations返回个人配置、fieldCapabilities与锁定原因;作者还会收到publication和当前sourceHash。 对 v2 项目,非模板管理者的默认请求读取最新已发布模板,即使其有权读取源码草稿;尚未发布的角色配置会提示先发布模板。POST /api/projects/:id/configurations支持publication.save(revision加publication,草稿包含自身revision、字段、配置集和defaultConfigurationId)和publication.preview。草稿版本冲突返回 HTTP 409。GET /api/projects/:id/configurations/template?target=1.0.0只读取已发布模板。POST /api/projects/:id/configurations/files?target=1.0.0&key=background&fileName=map.png&mimeType=image/png按指定版本权限上传个人配置附件;GET /api/projects/:id/configurations/files/:fileId?target=1.0.0只读取授权附件。- 发布
POST /api/projects/:id/publish时携带expectedSourceHash、expectedVersion和expectedConfigurationRevision;后者是发布草稿版本。
Studio Control 的 get_configurations 会返回权限,preview: true 返回接收者预览;manage_configurations 支持 publication.save。这些操作不依赖面板打开,官方修改必须连接原项目的 Server 并联网;只读模式拒绝所有写入。
分发模板不会包含被排除的字段或子路径名称;生成的不可读规则摘要保留同名冲突与隐藏路径覆盖检查。这些摘要不替代源码下载的身份和完整性验证。
业务角色由项目及祖先组继承计算。所有访客均可管理自己的个人配置,仍受已发布版本字段限制;维护者及以上角色才可管理官方配置与发布规则。此角色规则不改变本地配置和运行快照。
按项目角色限制配置
需要固定运行模式时,在 configuration.json v2 中声明 profilePolicy。未声明的项目继续使用原来的个人配置行为。
{
"version": 2,
"fields": [{"name":"MODE","type":"string","sharing":{"publish":true,"includeValue":true,"editable":false}}],
"profilePolicy": {
"version": 1,
"defaultProfileKey": "ask",
"manageMinimumRole": "developer",
"profiles": [
{"key":"ask","name":"Ask","minimumRole":"guest","fixedValues":{"MODE":"ask"},"tags":["Read only"]},
{"key":"build","name":"Build","minimumRole":"developer","fixedValues":{"MODE":"build"},"tags":["Collect and write"]}
]
}
}
key 是不可由个人元数据更改的稳定标识;minimumRole 使用项目与所属群组继承后的 guest、developer、maintainer、owner 角色。description 和 tags 用于列表摘要,不展示密钥。每个基础配置必须固定相同的字段集合;固定值覆盖个人值且不能清除。默认配置必须向访客开放,固定值必须允许随模板发布。
访客只看到可用的基础配置,不能增删、复制、改名、导入或管理字段,可以编辑作者开放的模型等值。达到 manageMinimumRole 后可新建、复制、管理个人配置;每套个人配置继承关联的 profileKey、最低角色与固定值,不能以改名、标签、导入或指定 templateId 降低限制。基础配置的名字与身份由源码维护。列表返回 capabilities、configurationCapabilities 和锁定原因;打开详情不会切换运行配置,输入框只读显示当前模式。
本地受限配置按应用、Server 与账号分别保存,同账号多窗口共享。未登录、退出登录或联网确认失败时仅提供访客默认配置,不复用先前的 Build 权限。读取和参数发现复用短期角色缓存,不随输入逐键联网;保存、发送、队列启动、恢复和受限工具执行前重新联网确认。历史消息及磁盘上的个人值保留,编辑中的草稿不会成为授权依据。
提供的 configuration 与旧运行快照必须重新校验当前角色、账号、稳定标识和固定值;无权使用的配置明确拒绝,运行中的 Build 不会被改成 Ask 继续执行。官方发布模板使用版本 3 冻结策略;旧宿主应提示升级并拒绝执行。项目可使用 steamharness.getProjectConfiguration()?.profilePolicyVersion 检查宿主支持情况。个人导出和配置响应只含当前可见的配置与附件;源码分发仍使用作者冻结的完整官方模板,个人凭据不会自动发布。
Server 依据实际认证身份及项目、群组角色授权,客户端提供的角色和标签无效。维护者及以上沿用官方模板管理权限。Studio Control 面板关闭时也使用同一服务;其只读模式另外拒绝写入。本规则不阻止用户修改自己的源码副本。
显式传入及恢复的运行快照同样校验官方模板的字段与 JSON 子路径锁定,并合并当前源码的系统 AI 限制。等待任务随快照记录原已验证模板,升级后继续校验并使用原值;当前角色、固定模式和模型来源限制仍须满足新规则。快照不能通过省略或放宽 agentModelPolicy 接入第三方模型。