@aid-framework/generator-sdk
插件合同 AID 框架 发电机。 它定义 好一个发电机 实值,并供应每台发电机所需的三样东西,以便安全地重新运行:a 很明显,一种所有权和漂移算法, 和决定主义契约.
如果你正在写一个目标——一个新的语言,一个新的托管平台——这就是你执行的软件包. 狦
仅是 使用 AID,你不能直接调用它: aid gen 已经.
spec ← ir ← generator-sdk ← generator-<target> ← cli
安装
npm install @aid-framework/generator-sdk
要求节点.js 24或更新.
这三项工作
- 说出你是什么. 显示对象的ID、你接受的IR范围、你的能力 荣誉,还有你们对战的时间.
- 永远不要破坏人类的编辑. 文件分为发电机拥有的一级和开发商拥有的一级,以及 再生拒绝覆盖其字节已改变的生成文件 .
- 释出同样的字节两次. 鉴于同一IR,生成器必须输出同字节相同的输出——否 时间戳,没有主机名,没有绝对路径,没有随机性.
名单
import type { GeneratorManifestInput } from '@aid-framework/generator-sdk';
const input: GeneratorManifestInput = {
name: 'my-target',
target: 'my-target',
version: '0.1.0',
irRange: '^0.1.0',
capabilities: ['http-trigger', 'json-schema', 'otel'],
emitsAgainst: {
structuredOutput: 'zod',
tracing: 'otel-genai',
},
output: {
root: 'app',
generatedDir: 'generated',
businessDir: 'business',
},
};
const parsed = parseManifest(input);
if (!parsed.ok) throw new Error(JSON.stringify(parsed.diagnostics, null, 2));
checkIRSupport(parsed.manifest, IR_VERSION); // [] when irRange covers this IR
validateGeneratorSet([parsed.manifest]); // [] when the set is coherent
emitsAgainst 这使得两个目标具有可比性。 目标排放活性模型和OTel跨度不是
与一个放出Zod和另一个追踪器可以互换,声明是这样说的 数据 而不是说
以传道而行.
| 密钥 | 词汇 |
|---|---|
runtime | 输出的运行时间被配对,例如. py-fastapi |
orchestration | ORCHESTRATIONS |
tracingBackend | TRACING_BACKENDS,比如说. otel-genai |
structuredOutput | STRUCTURED_OUTPUTS,比如说. zod, (中文(简体) ), pydantic |
校验返回诊断, 绝不丢出例外, 以相同的编译器样式形状
@aid-framework/spec 财务报告和审定财务报表 @aid-framework/ir名称空格 generator/*。 。 。 . validateGeneratorSet
另外拒绝两台发电机 声称相同 target。 。 。 .
一个清单是数据,这就是为什么能力进入IR门作为论据:
import { targetCapabilityDeclarations } from '@aid-framework/generator-sdk';
import { runGates } from '@aid-framework/ir';
runGates(ir, { targetCapabilities: targetCapabilityDeclarations(manifests) });
generated/ 财务报告和审定财务报表 business/
两级分裂是再生安全的原因.
| 级别 | 拥有者 | 在再生时 |
|---|---|---|
generated/ | 生成器 | 覆写——永远不要手写 |
business/ | 你们 | 如果缺少, 那么创建一次 没碰过 |
business/ 是接合:这是生成的代码调用。 这就是你的提示,工具处理者和
域逻辑是活的,这就是为什么再生成不会花费你的工作.
所有权由 一条小路而不是根据发电机的声称。 每条计划路线都恢复正常了,
因此,一个生成器无法逃脱自己的根,不能要求一个 business/ 路径生成,且无法写入
显示文件本身.
import {
isBusinessPath, isGeneratedPath, isReservedPath, ownerForPath, validatePlan,
} from '@aid-framework/generator-sdk';
漂移算法
这是整个安全故事,分五个步骤:
- 计划.
plan(ir)是纯洁的。 它什么也没有写. - 检查生成的文件 . 如果计划
generated/文件存在,其散列不是记录在 很明显,是人类编辑的 不覆盖 。 将旁边的新内容写成<path>.aid-rej失败 以向导. - 创建商务文件 . 惟有相去不见. 永远不要覆盖.
- 解剖写法,然后更新清单.
- 报告 创建 / 更新 / 不变 / 保留 / 冲突 .
步骤2就是重点。 一个能无条件摧毁人类的信号的发电机
不同意,损失是沉默的。 拒绝,保留被拒绝的字节, 并命名逃跑——
--force 以丢弃编辑器 —— 将无声数据丢失变成你明确作出的决定.
import { hasDrift, planRegeneration, regenerate } from '@aid-framework/generator-sdk';
// Pure: computes what would happen and writes nothing.
const preview = planRegeneration(plan, { sink, manifest });
if (hasDrift(preview)) {
// preview.actions carries { kind: 'drift', path, recordedSha256, actualSha256 }
}
const { report, manifest: next } = regenerate(plan, { sink, manifest, provenance });
RegenerationAction 实值 create | update | unchanged | keep-business | drift这样 --dry-run 从《京都议定书》
同样的代码路径写.
两个限制是故意的:
- 下方的文件
generated/存在但已经 没有 清单上的记录被视为漂移,而不是 因为它不能被证明是未经修改的. - Stale 生成的文件 - 已记录但不再计划 - 被报告,但从未被删除,除非进行搜索 明确要求。 删减是一次没有恢复的行动.
决定主义
合同范围窄而绝对: 没有时间戳,没有主机名称,没有绝对路径,没有随机性 内 生成代码 。 一次印章将每次再生变成diff,而金文件测试比较了字节.
import { checkDeterminism } from '@aid-framework/generator-sdk';
const violations = checkDeterminism(files); // { path, pattern, line, excerpt }[]
| 导出 | 目的 |
|---|---|
normalizeNewlines, (中文(简体) ), ensureTrailingNewline, (中文(简体) ), normalizeText | 线路结束和后继的新线正常化 |
sha256Hex, (中文(简体) ), stableId | 内容散乱和稳定身份 |
compareIds, (中文(简体) ), sortById, (中文(简体) ), sortByPath, (中文(简体) ), stableSortBy | 由稳定身份而不是由行走顺序排序 |
generatedBanner | 非编辑标题及其标记 |
DETERMINISM_PATTERNS, (中文(简体) ), scanForNonDeterminism | 规则集和每个文件检查器 |
checkDeterminism | 在文件集上运行整个规则 |
scanForNonDeterminism 就是让发电机自己的测试在发出时间戳时 失败。 这是
是什么使得合同可以检验 而不是渴望.
合同适用于 生成代码, 绝不建模输出。预计完成情况会有所不同 通过取样而不是比较字节来说明这一点.
磁盘上的显示
aid.manifest.json 记录出处——生成器名称和版本,IR版本,光谱版本——外加一条目
每个文件 : path, (中文(简体) ), owner, (中文(简体) ), sha256, (中文(简体) ), generator, (中文(简体) ), generatorVersion。记录使得上文第2步
也许吧.
import { manifestFor, parseAidManifestJson, serializeAidManifest } from '@aid-framework/generator-sdk';
const written = manifestFor(files, provenance);
const text = serializeAidManifest(written); // canonical: sorted keys, LF, one trailing newline
生成器接口
import type { Generator } from '@aid-framework/generator-sdk';
export const myGenerator: Generator = {
name: manifest.name,
target: manifest.target,
version: manifest.version,
irRange: manifest.irRange,
plan: (ir) => planMyTarget(ir),
emit: (plan) => plan.files,
};
每个身份字段都会从清单中读出 所以一个清单中可以验证出装载器 然后它运行的发电机 不可对他们所描述的目标、版本或IR范围有异议.
API 密码
| 导出 | 目的 |
|---|---|
parseManifest, (中文(简体) ), parseManifestJson, (中文(简体) ), validateManifest, (中文(简体) ), validateGeneratorSet | 明确处理 |
checkIRSupport, (中文(简体) ), supportsIR | IR 范围兼容性 |
managedRoots, (中文(简体) ), targetCapabilityDeclarations | (一) 成交门 |
validatePlan, (中文(简体) ), isRecord | 计划审定 |
planRegeneration, (中文(简体) ), regenerate, (中文(简体) ), checkDrift, (中文(简体) ), hasDrift | 漂移算法 |
staleGeneratedFiles, (中文(简体) ), generatedFiles | 上一次运行的库存 |
createNodeSink, (中文(简体) ), createMemorySink | 磁盘和内质再生汇 |
ownerForPath, (中文(简体) ), isGeneratedPath, (中文(简体) ), isBusinessPath, (中文(简体) ), isReservedPath, (中文(简体) ), escapesRoot | 所有权的前提 |
rejectionPath | 拒绝的字节停放的地方 |
manifestFor, (中文(简体) ), parseAidManifest, (中文(简体) ), serializeAidManifest | 磁盘显示 |
checkDeterminism, (中文(简体) ), DETERMINISM_PATTERNS, (中文(简体) ), scanForNonDeterminism | 决定主义 |
parseRange, (中文(简体) ), satisfies, (中文(简体) ), compareVersions | 共享 semver 词汇 |
许可证
阿帕奇 - 2.0。由 AID 框架生成的代码是 不受该许可证的限制.