🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

创作编排台 full-aigc-plugins/artcraft-plugin

DeepSeek Harness
full-aigc-plugins16 天前有提交已提供中文文档扫描:含敏感能力

把一份需求拆成矢量、位图、动效与影片工程并调度交付

30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/19 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add full-aigc-plugins/artcraft-plugin
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · vision
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 16 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 121 处,展示前 75 条)
  • 读取本地文件
    dsh/lib/index.js:139
    if (!existsSync(SKILLS_DIR)) return []
  • 读取本地文件
    dsh/lib/index.js:143
    entries = await readdir(SKILLS_DIR, { withFileTypes: true })
  • 读取本地文件
    dsh/lib/index.js:151
    if (!existsSync(file)) continue
  • 读取本地文件
    dsh/lib/index.js:153
    const parsed = parseSkill(await readFile(file, 'utf8'))
  • 读取本地文件
    dsh/lib/index.js:179
    if (!existsSync(COMMANDS_DIR)) return []
  • 读取本地文件
    dsh/lib/index.js:183
    entries = await readdir(COMMANDS_DIR, { withFileTypes: true })
  • 写入本地文件
    dsh/lib/index.js:271
    mkdir(DATA_DIR, { recursive: true }).catch(() => {})
  • 读取本地文件
    src/adapters/collected_output.ts:13
    const bytes=(await stat(join(root,location))).size;
  • 读取本地文件
    src/adapters/collected_output.ts:18
    const bytes=await readFile(join(root,'manifest.json'));
  • 读取本地文件
    src/adapters/font_output.ts:20
    const bytes=(await stat(join(root,location))).size;
  • 读取本地文件
    src/adapters/font_output.ts:24
    const content=await readFile(join(root,location));
  • 读取本地文件
    src/adapters/public_skill.ts:74
    const bytes=await readFile(join(source.root,'manifest.json'));
  • 读取本地文件
    src/adapters/public_skill.ts:83
    await verifyArtifact({...source.artifact,location,sha256:digest,version:digest,bytes:(await stat(join(source.root,location))).size,mediaType:'applicat
  • 读取本地文件
    src/adapters/public_skill.ts:121
    if(await readFile(locked.python).then(hash)!==locked.pythonSha256)throw new Error('launcher_identity_mismatch');
  • 读取本地文件
    src/adapters/public_skill.ts:123
    if(!isAbsolute(file.path) || await readFile(file.path).then(hash)!==file.sha256)throw new Error('launcher_file_identity_mismatch');
  • 写入本地文件
    src/adapters/public_skill.ts:126
    await mkdir(root,{recursive:true});
  • 写入本地文件
    src/adapters/public_skill.ts:127
    await writeFile(planFile,JSON.stringify(plan),'utf8');
  • 写入本地文件
    src/adapters/public_skill.ts:129
    await writeFile(strictRunner,strictMcpRunner,'utf8');
  • 读取本地文件
    src/adapters/public_skill.ts:135
    args.push(asset.kind==='lut'?'--lut-asset':asset.input.artifact.mediaType===imageSequenceMime?(segmented?'--segmented-sequence-asset':'--sequence-asse
  • 读取本地文件
    src/adapters/public_skill.ts:140
    protocolVersion:'craft-artifact/v1',assetId,version:sha256,sha256,bytes:(await stat(join(delivery,location))).size,mediaType,producerTaskId:taskId,sou
  • 读取本地文件
    src/adapters/video_factory.ts:27
    pluginRoot=await realpath(pluginRoot);
  • 读取本地文件
    src/adapters/video_factory.ts:28
    const manifest=JSON.parse(await readFile(join(pluginRoot,'plugin.json'),'utf8'));
  • 读取本地文件
    src/adapters/video_factory.ts:29
    const pkg=JSON.parse(await readFile(join(pluginRoot,'package.json'),'utf8'));
  • 读取本地文件
    src/adapters/video_factory.ts:32
    const add=async(path:string)=>{if(!(await lstat(path)).isFile())throw new Error('video_factory_source_invalid');files.push({path,sha256:hash(await rea
  • 读取本地文件
    src/adapters/video_factory.ts:32
    const add=async(path:string)=>{if(!(await lstat(path)).isFile())throw new Error('video_factory_source_invalid');files.push({path,sha256:hash(await rea
  • 读取本地文件
    src/adapters/video_factory.ts:33
    const walk=async(path:string)=>{for(const entry of await readdir(path,{withFileTypes:true})){const child=join(path,entry.name);if(entry.isSymbolicLink
  • 写入本地文件
    src/adapters/video_factory.ts:56
    const root=join(locked.outputRoot,hash(taskId));await mkdir(root,{recursive:true});
  • 写入本地文件
    src/adapters/video_factory.ts:60
    await writeFile(planFile,JSON.stringify(plan));
  • 写入本地文件
    src/adapters/video_factory.ts:62
    await writeFile(job,JSON.stringify(value));
  • 读取本地文件
    src/adapters/video_factory_driver.ts:8
    const job=JSON.parse(readFileSync(process.argv[2],'utf8'));
  • 读取本地文件
    src/adapters/video_factory_driver.ts:9
    if(hash(readFileSync(job.input.path))!==job.input.sha256)throw new Error('video_factory_input_changed');
  • 执行外部命令来自配置/变量
    src/adapters/video_factory_driver.ts:11
    const invoke=(args:string[])=>JSON.parse(execFileSync(job.nodeExecutable,[job.entry,...args],{encoding:'utf8',env,maxBuffer:16*1024*1024,timeout:30000
  • 读取本地文件
    src/adapters/video_factory_driver.ts:15
    if(hash(readFileSync(job.input.path))!==job.input.sha256)throw new Error('video_factory_input_changed');
  • 读取本地文件
    src/adapters/video_factory_driver.ts:16
    writeFileSync(job.output,JSON.stringify({schema:'craft-video-evaluation/v1',input:job.input,planSha256:hash(readFileSync(job.planFile)),result})+'\n',
  • 写入本地文件
    src/adapters/video_factory_driver.ts:16
    writeFileSync(job.output,JSON.stringify({schema:'craft-video-evaluation/v1',input:job.input,planSha256:hash(readFileSync(job.planFile)),result})+'\n',
  • 读取本地文件
    src/artifacts/project_package.ts:14
    const base=await realpath(root),path=join(base,location),actual=await realpath(path),delta=relative(base,actual);
  • 读取本地文件
    src/artifacts/project_package.ts:15
    if(!delta || delta.startsWith('../') || isAbsolute(delta) || !(await lstat(path)).isFile())throw new Error('package_location_invalid');
  • 读取本地文件
    src/artifacts/project_package.ts:19
    const before=await lstat(path),digest=createHash('sha256');let bytes=0;
  • 读取本地文件
    src/artifacts/project_package.ts:21
    for await(const chunk of createReadStream(path)){bytes+=(chunk as Buffer).length;digest.update(chunk);}
  • 读取本地文件
    src/artifacts/project_package.ts:22
    const after=await lstat(path);
  • 读取本地文件
    src/artifacts/project_package.ts:40
    const text=await readFile(await filePath(root,'project.json'));
  • 写入本地文件
    src/artifacts/project_package.ts:94
    await mkdir(dirname(destination),{recursive:true});
  • 写入本地文件
    src/artifacts/project_package.ts:101
    await mkdir(dirname(join(stage,location)),{recursive:true});await writeFile(join(stage,location),buffer,{flag:'wx',mode:0o600});
  • 写入本地文件
    src/artifacts/project_package.ts:101
    await mkdir(dirname(join(stage,location)),{recursive:true});await writeFile(join(stage,location),buffer,{flag:'wx',mode:0o600});
  • 写入本地文件
    src/artifacts/project_package.ts:107
    await mkdir(dirname(join(stage,target)),{recursive:true});
  • 写入本地文件
    src/artifacts/project_package.ts:108
    await copyFile(path,join(stage,target),constants.COPYFILE_EXCL);
  • 写入本地文件
    src/artifacts/project_package.ts:151
    const text=json(manifest),digest=hash(text);await writeFile(join(stage,'project.json'),text,{flag:'wx',mode:0o600});
  • 删除本地文件递归
    src/artifacts/project_package.ts:161
    await rm(stage,{recursive:true,force:true});
  • 删除本地文件
    src/artifacts/project_package.ts:162
    if(reservedInode!==undefined){try{if((await lstat(destination)).ino===reservedInode)await rmdir(destination);}catch{}}
  • 读取本地文件
    src/cli.ts:16
    const version=JSON.parse(readFileSync(new URL('../package.json',import.meta.url),'utf8')).version;
  • 读取本地文件
    src/cli.ts:40
    await access(flags.database);
  • 读取本地文件
    src/cli.ts:53
    const registry=JSON.parse(await readFile(flags.registry,'utf8'));
  • 读取本地文件
    src/cli.ts:60
    const plan=JSON.parse(await readFile(flags.plan,'utf8'));
  • 写入本地文件
    src/cli.ts:73
    await mkdir(dirname(flags.database),{recursive:true});
  • 读取本地文件
    src/planning/film_duration.ts:24
    const manifestBytes=await readFile(join(root,'manifest.json'));
  • 读取本地文件
    src/planning/film_duration.ts:34
    const bytes=await readFile(join(root,location));
  • 读取本地文件
    src/planning/native_brief_output.ts:17
    const manifestBytes=await readFile(join(root,'manifest.json'));
  • 读取本地文件
    src/planning/native_brief_output.ts:27
    const bytes=await readFile(join(root,'native.json'));
  • 读取本地文件
    src/planning/native_brief_output.ts:52
    const image=await readFile(join(root,output.location));
  • 读取本地文件
    src/planning/photo_variant_output.ts:27
    const manifestBytes=await readFile(join(root,'manifest.json'));
  • 读取本地文件
    src/planning/photo_variant_output.ts:36
    const bytes=await readFile(join(root,name));if(digest(bytes)!==expected)throw new Error('photo_variant_evidence_stale');return JSON.parse(bytes.toStri
  • 发起网络请求
    src/planning/workflow_engine.ts:55
    validateTask(this.request(plan,node,'preflight','preflight',[]));
  • 发起网络请求
    src/planning/workflow_engine.ts:164
    const request=this.request(plan,node,taskId,'wf-node:'+planHash({key,id,fingerprint}),inputs);
  • 读取本地文件
    src/protocol/contracts.ts:15
    const taskSchema: Schema = JSON.parse(readFileSync(new URL('../../schemas/craft-task-v1.json', import.meta.url), 'utf8'));
  • 读取本地文件
    src/protocol/contracts.ts:16
    const artifactSchema: Schema = JSON.parse(readFileSync(new URL('../../schemas/craft-artifact-v1.json', import.meta.url), 'utf8'));
  • 读取本地文件
    src/protocol/contracts.ts:81
    const schema=JSON.parse(readFileSync(new URL('../../schemas/craft-exchange-loss-v1.json',import.meta.url),'utf8'));
  • 读取本地文件
    src/protocol/contracts.ts:115
    const base = await realpath(root);
  • 读取本地文件
    src/protocol/contracts.ts:116
    const target = await realpath(resolve(base, location));
  • 读取本地文件
    src/protocol/contracts.ts:138
    const target=await allowedPath(root,native.location),before=await stat(target);
  • 读取本地文件
    src/protocol/image_sequence.ts:41
    if((await lstat(current)).isSymbolicLink())invalid('symlink');
  • 读取本地文件
    src/protocol/image_sequence.ts:42
    for(const part of location.split('/')){current=join(current,part);if((await lstat(current)).isSymbolicLink())invalid('symlink');}
  • 读取本地文件
    src/protocol/image_sequence.ts:43
    const before=await lstat(target);if(!before.isFile()||before.size>4*1024*1024)invalid('descriptor_limit');
  • 读取本地文件
    src/protocol/image_sequence.ts:44
    const content=await readFile(target);if(content.length!==before.size||sha(content)!==expectedSha)invalid('descriptor_changed');
  • 读取本地文件
    src/protocol/image_sequence.ts:65
    if(!isDeepStrictEqual((await readdir(directory)).sort(),expected.sort()))invalid('file_set');
  • 读取本地文件
    src/protocol/image_sequence.ts:67
    const path=join(directory,frame.location),beforeFrame=await lstat(path);
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

从一份简报出发,统筹 VectorCraft、PhotoCraft、EffectCraft 和 FilmCraft 项目。

README

由 DeepSeek 最新模型翻译生成
ArtCraft 插件市场导航 本插件所属分类:AIGC 内容创作。 | 分类 | 插件市场入口 | 用途 | | 全栈开发 | Full Stack Plugins | 架构与 UI 设计、代码理解、质量检查、代码审查、流程治理与服务器运维 | | AIGC 内容创作 | Full AIGC Plugins | 图像、视频、音频、音乐、3D 与多模态内容创作 | 把一份需求变成相互协同的 VectorCraft、PhotoCraft、EffectCraft 与 FilmCraft 工程,并保留冻结计划、持久账本与哈希绑定的交付证据。 项目定位 ArtCraft 是四个 -craft 创作工具的编排层:把混合需求(品牌图形、海报、动态片头、带字幕短片)拆成依赖图,安装该图所需的固定运行时与领域技能,以“每个工程一个写入者”的方式执行,并完整保留原生工程、素材摘要与回执。 它不是新编辑器。矢量文档归 VectorCraft,位图工程归 PhotoCraft,合成归 EffectCraft,时间线归 FilmCraft;ArtCraft 负责路由、调度、修订范围、打包与审阅证据。剪映有独立插件,不在本插件范围内。
展开完整文档(README 剩余 1 节)
ArtCraft

插件市场导航

本插件所属分类:AIGC 内容创作。

| 分类 | 插件市场入口 | 用途 |
| 全栈开发 | Full Stack Plugins | 架构与 UI 设计、代码理解、质量检查、代码审查、流程治理与服务器运维 |
| AIGC 内容创作 | Full AIGC Plugins | 图像、视频、音频、音乐、3D 与多模态内容创作 |

把一份需求变成相互协同的 VectorCraft、PhotoCraft、EffectCraft 与 FilmCraft 工程,并保留冻结计划、持久账本与哈希绑定的交付证据。

项目定位

ArtCraft 是四个 -craft 创作工具的编排层:把混合需求(品牌图形、海报、动态片头、带字幕短片)拆成依赖图,安装该图所需的固定运行时与领域技能,以“每个工程一个写入者”的方式执行,并完整保留原生工程、素材摘要与回执。

它不是新编辑器。矢量文档归 VectorCraft,位图工程归 PhotoCraft,合成归 EffectCraft,时间线归 FilmCraft;ArtCraft 负责路由、调度、修订范围、打包与审阅证据。剪映有独立插件,不在本插件范围内。

| 11 个技能 | 4 个原生领域 | 1 条执行通道 | macOS arm64 |
| 路由与生命周期 | 矢量、位图、动效、影片 | artcraft-harness 脚本 | 唯一已验证平台 |

状态与版本

0.1.0-dev.142+codex.20261018 · 开发预览 · project-status.json → marketplaceEligible: false、supportedPluginHosts: []。

安装

前置条件

- macOS arm64。这是唯一具备首用证据的平台,其他平台不作承诺。
- PATH 上有 Python 3.11 或更新版本。固定 Node 运行时由 bootstrap 脚本自行安装,不需要全局 Node。
- 不需要 sudo,不修改 PATH:安装落在用户数据目录(默认 ~/.local/share/craft-runtimes,可用 --runtime-home 或 CRAFT_RUNTIME_HOME 指定)。
- 首次使用需要网络,或通过 --node-archive、--bundle-dir、--native-archive-dir 提供固定的离线制品。

开发安装

codex plugin marketplace add full-aigc-plugins/artcraft-plugin
codex plugin add artcraft@full-aigc-plugins-artcraft

project-status.json 仍记录 marketplaceEligible: false,且 supportedPluginHosts 为空,因此请把它当作 0.1.0-dev. 候选的开发安装;本包没有面向生产的市场条目。

仓库带有 Codex(.codex-plugin/)、Claude Code(.claude-plugin/)、ZCode(.zcode-plugin/)与 Kimi(kimi.plugin.json)清单,但本候选尚未通过宿主发现验收。

快速开始

把 HARNESS_DIR 指向宿主实际加载的技能目录,然后安装固定运行时。系统解释器和 PATH 都不会被修改。

: "${HARNESS_DIR:?请设为已加载 artcraft-harness 的 SKILL.md 所在目录}"
python3 -I -B "$HARNESS_DIR/scripts/bootstrap.py" --runtime-only

bootstrap 返回包含 nodeExecutable 与 entryPoint 的 JSON;此时 skills 为空,因为还没有安装领域运行时。接着运行内置的四领域示例,再核对账本与重新打开的原生工程:

python3 "$HARNESS_DIR/scripts/workflow.py" \
"$SKILL_DIR/examples/brand-campaign.json" \
--output /absolute/path/brand-project \
--authorization brand-project-authorized \
--asset voice=/absolute/path/voice.wav

flowchart LR
A[需求与素材] --> B[artcraft-use 拆解路由]
B --> C[固定运行时与领域技能]
C --> D[冻结计划、SQLite 账本、DAG]
D --> E[矢量 / 位图 / 动效 / 影片工程]
E --> F[交付包与审阅证据]

示例需要真实的 voice WAV。没有音频时,应修改计划并去掉 audioRequired,而不是为了通过交付检查而生成假配音。

可完成的工作

| 工作流 | 内置路径 | 可验证输出 |
| 混合品牌项目 | artcraft-use → harness workflow | 四个原生工程、收集素材、预览与交付账本 |
| 替换 Logo 或素材 | artcraft-cli-revise | 受影响节点重建、无关节点复用、旧交付保留 |
| 恢复中断的任务 | artcraft-cli-recover | 采用原执行、不重放写入、保留停止证据 |
| 打包并迁移 | artcraft-cli-deliver | 移动后、删除原件后仍可核验的交付包 |
| 审阅混合交付 | artcraft-cli-review | 绑定当前插件与素材版本的具名观察记录 |
| 查询原生能力 | artcraft-cli → 领域命令组件 | 带已安装版本真实参数的命令目录 |

技能

| 技能 | 作用 |
| artcraft-use | 默认入口:拆解需求、选择工具、依赖交接与交付核验 |
| artcraft-cli | 查询公开 CLI 能力,执行明确命令与诊断 |
| artcraft-cli-setup | 首次安装、摘要校验、版本检查与缺失运行时排障 |
| artcraft-cli-plan | 规划品牌、海报、片头与宣传片的工具、DAG 与交付约束 |
| artcraft-cli-execute | 执行已有计划,核对输入版本与并发写入 |
| artcraft-cli-assets | 登记素材摘要、来源与子工程依赖 |
| artcraft-cli-revise | 替换 Logo 或资产,修改原生子工程并更新下游节点 |
| artcraft-cli-recover | 检查任务状态、取消原任务、调度器退出后恢复 |
| artcraft-cli-deliver | 收集原生工程、素材、计划与证据,迁移后核验 |
| artcraft-cli-review | 检查技术证据与视觉、文案、音频一致性 |
| artcraft-harness | 唯一的执行实现:bootstrap、workflow、审阅、修订、打包 |

配置

| 变量 / 参数 | 用途 |
| HARNESS_DIR | 已加载 artcraft-harness 技能的绝对目录;所有脚本从 $HARNESS_DIR/scripts/ 执行 |
| SKILL_DIR | 已加载领域 SKILL.md 所在目录;仅用于该技能的 examples/ 与 references/ |
| CRAFT_RUNTIME_HOME / --runtime-home | 隔离的运行时安装根目录 |
| --authorization | 既有任务授权范围的引用,不是凭据 |
| --output | 绝对输出目录;必须是新目录,已归属的目录不会被覆盖 |

本包自身不声明 MCP server(没有 mcp.json)。全部流程通过 harness 脚本与固定的原生 CLI 执行。

架构与安全

- 技能源码位于独立的 artcraft-skills 仓库,以锁定快照形式进入插件;skills.lock.json 固定源码提交与每个技能的 SHA-256。
- 受信配置固定解释器、脚本与原生可执行文件路径。计划载荷无法指定 shell、解释器或可执行文件。
- Python 以隔离模式运行且不写字节码缓存。每个工程目录只有一个写入者;计划修订被冻结,输入在使用前重新核对。
- 未知结果一律不重放:中断的原生写入保留租约,必须先完成核对。
- 证据是带哈希的单次运行 JSON;docs/README.md 是架构文档索引,行为规范见 OpenSpec。

故障排查

| 现象 | 处理方式 |
| 返回 unsupported_platform | 仅接受 macOS arm64;不要安装其他平台制品 |
| 下载或摘要不匹配 | 固定制品缺失或被改动;恢复网络,或提供已核验的离线制品 |
| 返回 runtime_upgrade_busy | 先在旧运行时上完成或可信停止任务,再迁移;不要删除租约 |
| 缺少 voice 素材 | 修改计划并去掉 audioRequired;不要合成配音 |
| 保存结果未知 | 读取 failure.json、暂存工程与停止证据;不要重跑同一写入 |
| 需要 Image Factory 或剪映 | 两者都未接入;剪映请使用其独立插件 |

升级

codex plugin marketplace upgrade full-aigc-plugins-artcraft
codex plugin add artcraft@full-aigc-plugins-artcraft

运行时身份与技能身份相互独立:复用某个版本会重新核验其文件,损坏的版本会明确失败,而不是被静默替换或升级。

贡献与支持

改动前先读 AGENTS.md:行为变更必须先走 OpenSpec,且没有真实交付证据不得勾选任务。文档与规范校验:

python3 scripts/validate_docs.py
openspec validate establish-v1-plugin --strict --no-interactive

这两条只校验文档与规范。缺陷请提交到 <https://github.com/full-aigc-plugins/artcraft-plugin/issues>。

许可证

本仓库原创内容采用 Apache-2.0。随包安装的 Node 运行时与四个上游创作 CLI 各自保留其许可证。受限的上游 ArtCraft/Services 代码与品牌素材未被复制;按版本绑定的历史见 RELEASE-HISTORY.md。
预览分享卡片长什么样 ↓full-aigc-plugins/artcraft-plugin
分享 · DeepSeek Harness Hub
full-aigc-plugins/artcraft-plugin

把一份需求拆成矢量、位图、动效与影片工程并调度交付

这是你的仓库?认领条目

回到顶部