6.9 资源打包与分发
本篇说明四类资源共用的文件组织和打包方法。先完成员工、团队、应用或SKILL中的一个例子,再按这里的步骤更新和分发。
先看两层文件
| 文件 | 用来做什么 |
|---|---|
employee.json、team.json、app.json 或 skill.json | 接收方选择导入的分享文件,包含实际文件正文 |
sources/teloa.json | 内部资源清单,列出资源、固定版本、文件路径和关系 |
sources/roles/、skills/ 等 | 作者修改的源文件,重新打包后进入分享文件 |
下载四类资源示例,每份 ZIP 已带完整 JSON、sources/ 与 pack.mjs。分享文件和内部清单不是同一份 JSON。
一份完整的内部清单
应用示例的 sources/teloa.json 只声明一项技能:
{
"format": "teloa.business-package/v2",
"id": "example-app-brief",
"version": "1.0.1",
"title": "Evidence brief app",
"description": "A local authoring example with no account connection or automatic execution.",
"domain": "general",
"scope": "general",
"resources": [
{
"id": "evidence-brief",
"kind": "skill",
"title": "evidence-brief",
"version": "1.0.1",
"required": true,
"source": {
"kind": "local",
"path": "skills/evidence-brief/SKILL.md"
}
}
],
"relations": [],
"entrypoints": [
"evidence-brief"
]
}对应正文位于 sources/skills/evidence-brief/SKILL.md。员工和团队再添加 role 资源,并用 role-skill 关系连接方法;其他资源和版本字段见格式参考。
代码里的 teloa.business-package 是清单格式名,不是第五类产品。外层用 subject 指明 AI 员工、AI 团队、应用或 SKILL:员工恰好一位,团队至少两位,应用不含员工,独立 SKILL 恰好一项技能。
修改后重新打包
例如修改员工说明后,在解压目录运行:
node pack.mjs employee.json应用、团队和技能分别把参数换成 app.json、team.json、skill.json。脚本读取外层已列出的文件,将 sources/ 正文写回分享文件:
import {readFile, writeFile, realpath} from 'node:fs/promises'
import {resolve, sep} from 'node:path'
const file = process.argv[2]
if (!file) throw Error('Usage: node pack.mjs employee.json')
const share = JSON.parse(await readFile(file, 'utf8'))
const sourceRoot = await realpath('sources')
for (const item of share.files) {
if (typeof item.path !== 'string' || item.path.includes('\\') ||
/[\x00-\x1f\x7f]/.test(item.path) ||
item.path.split('/').some(part => !part || part === '.' || part === '..')) {
throw Error('Unsafe source path')
}
const source = await realpath(resolve(sourceRoot, item.path))
if (!source.startsWith(sourceRoot + sep)) throw Error('Source escapes the package')
item.text = await readFile(source, 'utf8')
}
const manifest = JSON.parse(share.files.find(f => f.path === 'teloa.json').text)
share.id = manifest.id
share.version = manifest.version
await writeFile(file, JSON.stringify(share, null, 2) + '\n')新增资源时,同时修改内部 resources、relations 和外层 files 列表,并创建相应源文件。修改实际内容后提高包版本;改变了资源定义时也更新该资源版本与固定引用。脚本同步外层与内部的包身份和版本,不自动决定所有资源的版本。
格式检查
在已准备依赖的 Teloa 源码根目录,将要检查的分享 JSON 复制到当前目录,再运行。检查单份文件时只在数组中列出这一份;以下例子检查四份:
node --input-type=module <<'JS'
import {readFileSync} from 'node:fs'
import {readTemplateShare} from './packages/contract/src/template-share.mjs'
for (const subject of ['employee', 'team', 'app', 'skill']) {
const value = JSON.parse(readFileSync(`${subject}.json`, 'utf8'))
console.log(readTemplateShare(value).subject)
}
JS应输出 employee、team、app、skill。这是格式读取检查,不会添加或执行资源。没有源码环境时,可直接在员工页的 导入模板 中选择分享 JSON 查看预览。
接收与分发
检查预览中的成员、技能、资料和来源,再明确添加到测试业务。员工默认暂停;按实际状态配置模型、安装能力、连接账号和授权。完成原教程的小任务后,再通过离线文件或在线链接分发。
分享 JSON 最多 8 MiB,单份文件正文最多 2 MiB。密码、模型密钥、账号会话和执行授权不放进包里;发布前检查随附资料和正文是否有权公开。
需要完整业务配置时
内部清单 v2 组织常规资源,v3 增加固定模型依赖,v4 增加完整业务配置。它们是按所需能力选择的格式,不是要求作者把版本号逐级升级。完整配置包含对象、视图、页面与看板;不能把真实业务记录、同步账号或默认动作授权一起分发。字段与导入限制见格式参考。
若直接导入内部资源目录或 ZIP,使用市场的 创建 > 导入模板 流程,选择清单与随附文件;若接收本篇的分享 JSON,使用员工页的 导入模板。两种入口读取的文件结构不同。