halfcode-compiler.xnl 0.2.2 → 0.2.4
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.
- package/README.md +14 -0
- package/dist/application-assembly.js +1 -1
- package/dist/{index-96qHPZj2.d.ts → index-D7UtYNm7.d.ts} +1 -1
- package/dist/{index-DdRHFKSQ.d.ts → index-DihSfO7X.d.ts} +33 -2
- package/dist/{index-D2mpux6L.d.ts → index-DjvNDidT.d.ts} +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +14 -4
- package/dist/kind-definition.d.ts +1 -1
- package/dist/{resource-core-Byhqyadq.d.ts → resource-core-UAvFx3m-.d.ts} +1 -1
- package/dist/resource-core.d.ts +3 -3
- package/dist/resource-core.js +4 -4
- package/dist/resource-projection.d.ts +1 -1
- package/dist/skill-capsule.d.ts +1 -1
- package/dist/skill-capsule.js +1 -1
- package/dist/{src-DRIws6tY.js → src-6nezdi57.js} +1 -1
- package/dist/{src-DCRih45n.js → src-Bj7BZokJ.js} +237 -36
- package/dist/{src-D1Bmq7Lo.js → src-ClihwpeP.js} +1 -1
- package/dist/system-skills/resource-dsl/KindDefinitions/SkillCapsule/manifest.xnl +21 -0
- package/dist/system-skills/resource-dsl/KindDefinitions/WikiPage/manifest.xnl +10 -0
- package/dist/system-skills/resource-dsl/SkillCapsules/System/SKILL.metadata.yaml +2 -0
- package/dist/system-skills/resource-dsl/SkillCapsules/System/SKILL.template.ejs +20 -0
- package/dist/system-skills/resource-dsl/SkillCapsules/System/manifest.xnl +18 -0
- package/dist/system-skills/resource-dsl/SkillCapsules/System/resource-mappings.xnl +10 -0
- package/dist/system-skills/resource-dsl/WikiPages/documents/manifest.xnl +6 -0
- package/dist/system-skills/resource-dsl/WikiPages/files/manifest.xnl +6 -0
- package/dist/system-skills/resource-dsl/WikiPages/index/manifest.xnl +6 -0
- package/dist/system-skills/resource-dsl/WikiPages/language/manifest.xnl +6 -0
- package/dist/system-skills/resource-dsl/WikiPages/migration/manifest.xnl +6 -0
- package/dist/system-skills/resource-dsl/WikiPages/projections/manifest.xnl +6 -0
- package/dist/system-skills/resource-dsl/WikiPages/skill-capsules/manifest.xnl +6 -0
- package/dist/system-skills/resource-dsl/documents.md +119 -0
- package/dist/system-skills/resource-dsl/examples/function.xnl +12 -0
- package/dist/system-skills/resource-dsl/examples/index.md +17 -0
- package/dist/system-skills/resource-dsl/examples/kind-definition.xnl +12 -0
- package/dist/system-skills/resource-dsl/examples/resource-mappings.xnl +21 -0
- package/dist/system-skills/resource-dsl/examples/resource-package.xnl +19 -0
- package/dist/system-skills/resource-dsl/examples/skill-capsule-authoring.xnl +11 -0
- package/dist/system-skills/resource-dsl/examples/skill-capsule-devops.xnl +12 -0
- package/dist/system-skills/resource-dsl/examples/skill-capsule-kind-definition.xnl +27 -0
- package/dist/system-skills/resource-dsl/examples/skill-capsule-resource-dsl.xnl +8 -0
- package/dist/system-skills/resource-dsl/examples/skill-capsule-run.xnl +8 -0
- package/dist/system-skills/resource-dsl/files.md +47 -0
- package/dist/system-skills/resource-dsl/index.md +59 -0
- package/dist/system-skills/resource-dsl/language.md +64 -0
- package/dist/system-skills/resource-dsl/manifest.xnl +10 -0
- package/dist/system-skills/resource-dsl/migration.md +40 -0
- package/dist/system-skills/resource-dsl/projections.md +142 -0
- package/dist/system-skills/resource-dsl/skill-capsules.md +94 -0
- package/package.json +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Resource Document Families
|
|
2
|
+
|
|
3
|
+
## ResourcePackage 与 Catalogs
|
|
4
|
+
|
|
5
|
+
一个 package 有且只有一个 `ResourcePackage` authority root。它拥有唯一 `Catalogs` 子域;每个 `Catalog` 声明一种资源的逻辑根与目录入口:
|
|
6
|
+
|
|
7
|
+
```xnl
|
|
8
|
+
<ResourcePackage #demo.resource_workflow.authoring apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
9
|
+
lifecycle = "Active"
|
|
10
|
+
description = "Demo authoring resource package"
|
|
11
|
+
} (
|
|
12
|
+
<Catalogs [
|
|
13
|
+
<Catalog #kind_definitions {
|
|
14
|
+
kind = "KindDefinition"
|
|
15
|
+
shape = "directory"
|
|
16
|
+
root = "vfs://./KindDefinitions/"
|
|
17
|
+
entry = "manifest.xnl"
|
|
18
|
+
}>
|
|
19
|
+
<Catalog #functions {
|
|
20
|
+
kind = "Function"
|
|
21
|
+
shape = "directory"
|
|
22
|
+
root = "vfs://./Functions/"
|
|
23
|
+
entry = "manifest.xnl"
|
|
24
|
+
}>
|
|
25
|
+
]>
|
|
26
|
+
)>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
catalog 只描述组织,不复制每个 descriptor 的内容。`shape` 取 `single-file|directory|manifest`;后两者必须声明目录入口 `entry`。`single-file` 缺省扫描 `root` 下全部 `.xnl` 文件,也可以用可选 `entry = "<name>.xnl"` 精确选择同目录中的一个 authority 文件;该 entry 必须是无路径片段的 XNL 文件名。loader 用根 tag/`#id` 确认 kind/identity。
|
|
30
|
+
|
|
31
|
+
## KindDefinition
|
|
32
|
+
|
|
33
|
+
`KindDefinition` 声明 source shape 与 descriptor contract:
|
|
34
|
+
|
|
35
|
+
```xnl
|
|
36
|
+
<KindDefinition #halfcode.resource_kind.Function apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
37
|
+
lifecycle = "Stable"
|
|
38
|
+
sourceShapes = ["single-file" "directory"]
|
|
39
|
+
currentApiVersion = "halfcode.resources/v1"
|
|
40
|
+
supportedApiVersions = ["halfcode.resources/v1"]
|
|
41
|
+
} (
|
|
42
|
+
<DescriptorContract (
|
|
43
|
+
<Identity { required = true form = "fqn" }>
|
|
44
|
+
<CodeBinding { property = "src" scheme = "vfs" exportFragmentRequired = true }>
|
|
45
|
+
<Instruction { required = false source = "inline-or-vfs" }>
|
|
46
|
+
)>
|
|
47
|
+
)>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`currentApiVersion` 是新资源和迁移目标版本,`supportedApiVersions` 是 loader 可直接读取的兼容集合,且必须包含 current。未知版本必须先经过调用方在代码侧注册的确定性 migration,再交给 loader;可执行转换不写入 XNL。
|
|
51
|
+
|
|
52
|
+
`documentCardinality` 缺省为 `"one"`。只有 `sourceShapes = ["single-file"]` 的 Kind 可以声明 `documentCardinality = "many"`,表示一个 authority 文档允许包含多个并列的同 Kind 根;它不是对所有 XNL 文件放宽根约束。
|
|
53
|
+
|
|
54
|
+
Kind contract 可以按自身语义约束 lifecycle、description、instruction、code binding 与 includes;除 `#id` 和 `apiVersion` 外,这些字段都不是通用 loader 强加给所有 Kind 的共同要求。
|
|
55
|
+
|
|
56
|
+
加载成功后,consumer 从 `ResourceTree.registry.kindDefinitions` 按 `resourceKind` 取得规范化 contract。该 projection 包含 version、source shape、cardinality、required files 以及 KindDefinition 自身的 `resourceId`/`documentUri` provenance;KindDefinition 不混入业务资源的 `registry.byKind`。
|
|
57
|
+
|
|
58
|
+
## Resource descriptor
|
|
59
|
+
|
|
60
|
+
descriptor 根 tag 直接使用 kind,`#id` 是资源 FQN。唯一概念进入 `()`;重复成员进入 `[]`:
|
|
61
|
+
|
|
62
|
+
```xnl
|
|
63
|
+
<Function #demo.resource_workflow.prepare_data apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
64
|
+
lifecycle = "Active"
|
|
65
|
+
title = "Prepare workflow data"
|
|
66
|
+
} (
|
|
67
|
+
<Instruction ?instruction>
|
|
68
|
+
接收输入并产生下游 procedure 所需的规范数据。
|
|
69
|
+
</?instruction>
|
|
70
|
+
<CodeBinding {
|
|
71
|
+
src = "vfs://@/apps/demo-resource-workflow-authoring/src/procedures.ts#prepareProcedure"
|
|
72
|
+
}>
|
|
73
|
+
)>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
通用资源外壳只规定 identity、metadata channel、members/subdomains 和 provenance。各 Kind 的稳定领域字段及其 requiredness 由对应 `KindDefinition` 或 consumer contract 收窄;缺失的可选字段不会被填成空字符串。
|
|
77
|
+
|
|
78
|
+
允许 forest 的 Kind 仍逐根执行同样的 kind、identity 与 `apiVersion` 校验。例如 Decision Kind 可以显式声明:
|
|
79
|
+
|
|
80
|
+
```xnl
|
|
81
|
+
<KindDefinition #codument.resource_kind.Decision apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
82
|
+
lifecycle = "Stable"
|
|
83
|
+
sourceShapes = ["single-file"]
|
|
84
|
+
currentApiVersion = "codument.tech/v1alpha1"
|
|
85
|
+
supportedApiVersions = ["codument.tech/v1alpha1"]
|
|
86
|
+
documentCardinality = "many"
|
|
87
|
+
}>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
对应 authority 文件可以有多个并列 `<Decision ...>` 根。每个根归一化为独立 resource record,并共享该文件的 `documentUri` provenance;重复 `#id`、混合根 kind 或不受支持的版本仍是错误。
|
|
91
|
+
|
|
92
|
+
## ResourceMappings
|
|
93
|
+
|
|
94
|
+
mapping 根拥有多个唯一 collection subdomain;collection 的 `[]` 承载重复条目:
|
|
95
|
+
|
|
96
|
+
```xnl
|
|
97
|
+
<ResourceMappings #demo.resource_workflow.mappings apiVersion="halfcode.resources/v1" version="1.0.0" (
|
|
98
|
+
<ReferenceTargets [
|
|
99
|
+
<ReferenceTarget #function_dependency {
|
|
100
|
+
fromKind = "Function"
|
|
101
|
+
field = "dependsOn"
|
|
102
|
+
targetKind = "Function"
|
|
103
|
+
}>
|
|
104
|
+
]>
|
|
105
|
+
<CallableArtifacts [
|
|
106
|
+
<CallableArtifact #function_callable {
|
|
107
|
+
kind = "Function"
|
|
108
|
+
binding = "CodeBinding.src"
|
|
109
|
+
}>
|
|
110
|
+
]>
|
|
111
|
+
<SourceRoots [
|
|
112
|
+
<SourceRoot #authoring {
|
|
113
|
+
uri = "vfs://@/apps/demo-resource-workflow-authoring/resources/"
|
|
114
|
+
}>
|
|
115
|
+
]>
|
|
116
|
+
)>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
mapping key 是显式属性或 `#id`,不得把用户数据动态拼进 tag 名。
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<Function #demo.resource_workflow.prepare_data apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
lifecycle = "Active"
|
|
3
|
+
title = "Prepare workflow data"
|
|
4
|
+
} (
|
|
5
|
+
<Instruction ?instruction>
|
|
6
|
+
接收输入并产生下游 procedure 所需的规范数据。
|
|
7
|
+
</?instruction>
|
|
8
|
+
<CodeBinding {
|
|
9
|
+
src = "vfs://@/apps/demo-resource-workflow-authoring/src/procedures.ts#prepareProcedure"
|
|
10
|
+
}>
|
|
11
|
+
)>
|
|
12
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Parseable Examples
|
|
2
|
+
|
|
3
|
+
> 目录职责 · holds: 由当前 xnl-core parser 机械验证的规范 resource DSL 样例 · excludes: demo 业务资源与运行态 fixtures · tier: stable · ⬆from: resource DSL 文档实例 · ⬇to: parser/loader contract tests
|
|
4
|
+
|
|
5
|
+
| 文件 | 文档族 |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `resource-package.xnl` | package 与 catalogs |
|
|
8
|
+
| `kind-definition.xnl` | 通用 Function KindDefinition |
|
|
9
|
+
| `skill-capsule-kind-definition.xnl` | SkillCapsule exact dependency contract |
|
|
10
|
+
| `skill-capsule-devops.xnl` | 四 Skill 示例的 lifecycle root |
|
|
11
|
+
| `skill-capsule-authoring.xnl` | authoring -> shared resource DSL dependency |
|
|
12
|
+
| `skill-capsule-run.xnl` | 无 sibling dependency 的 run Skill |
|
|
13
|
+
| `skill-capsule-resource-dsl.xnl` | 被 authoring 复用的 shared resource DSL Skill |
|
|
14
|
+
| `function.xnl` | 带 instruction 与 code binding 的 descriptor |
|
|
15
|
+
| `resource-mappings.xnl` | reference/callable/source-root mappings |
|
|
16
|
+
|
|
17
|
+
这些文件由当前 `xnl-core` parser 做 parse/stringify/parse 验证。下游 resource-core track 会把相同检查变成持续测试。
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<KindDefinition #halfcode.resource_kind.Function apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
lifecycle = "Stable"
|
|
3
|
+
sourceShapes = ["single-file" "directory"]
|
|
4
|
+
currentApiVersion = "halfcode.resources/v1"
|
|
5
|
+
supportedApiVersions = ["halfcode.resources/v1"]
|
|
6
|
+
} (
|
|
7
|
+
<DescriptorContract (
|
|
8
|
+
<Identity { required = true form = "fqn" }>
|
|
9
|
+
<CodeBinding { property = "src" scheme = "vfs" exportFragmentRequired = true }>
|
|
10
|
+
<Instruction { required = false source = "inline-or-vfs" }>
|
|
11
|
+
)>
|
|
12
|
+
)>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<ResourceMappings #demo.resource_workflow.mappings apiVersion="halfcode.resources/v1" version="1.0.0" (
|
|
2
|
+
<ReferenceTargets [
|
|
3
|
+
<ReferenceTarget #function_dependency {
|
|
4
|
+
fromKind = "Function"
|
|
5
|
+
field = "dependsOn"
|
|
6
|
+
targetKind = "Function"
|
|
7
|
+
}>
|
|
8
|
+
]>
|
|
9
|
+
<CallableArtifacts [
|
|
10
|
+
<CallableArtifact #function_callable {
|
|
11
|
+
kind = "Function"
|
|
12
|
+
binding = "CodeBinding.src"
|
|
13
|
+
}>
|
|
14
|
+
]>
|
|
15
|
+
<SourceRoots [
|
|
16
|
+
<SourceRoot #authoring {
|
|
17
|
+
uri = "vfs://@/apps/demo-resource-workflow-authoring/resources/"
|
|
18
|
+
}>
|
|
19
|
+
]>
|
|
20
|
+
)>
|
|
21
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<ResourcePackage #demo.resource_workflow.authoring apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
lifecycle = "Active"
|
|
3
|
+
description = "Demo authoring resource package"
|
|
4
|
+
} (
|
|
5
|
+
<Catalogs [
|
|
6
|
+
<Catalog #kind_definitions {
|
|
7
|
+
kind = "KindDefinition"
|
|
8
|
+
shape = "directory"
|
|
9
|
+
root = "vfs://./KindDefinitions/"
|
|
10
|
+
entry = "manifest.xnl"
|
|
11
|
+
}>
|
|
12
|
+
<Catalog #functions {
|
|
13
|
+
kind = "Function"
|
|
14
|
+
shape = "directory"
|
|
15
|
+
root = "vfs://./Functions/"
|
|
16
|
+
entry = "manifest.xnl"
|
|
17
|
+
}>
|
|
18
|
+
]>
|
|
19
|
+
)>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<SkillCapsule #example.resource_lifecycle.skill.authoring apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
name = "example-resource-lifecycle-authoring"
|
|
3
|
+
lifecycle = "Active"
|
|
4
|
+
description = "Generic operations for resource creation and revision."
|
|
5
|
+
} (
|
|
6
|
+
<SkillMetadata { href = "vfs://./SKILL.metadata.yaml" format = "yaml" }>
|
|
7
|
+
<Template { href = "vfs://./SKILL.template.ejs" format = "ejs" }>
|
|
8
|
+
<SkillDependencies [
|
|
9
|
+
<SkillDependency { ref = "resource://example.resource_lifecycle.skill.resource_dsl" version = "1.0.0" }>
|
|
10
|
+
]>
|
|
11
|
+
)>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<SkillCapsule #example.resource_lifecycle.skill.devops apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
name = "example-resource-lifecycle-devops"
|
|
3
|
+
lifecycle = "Active"
|
|
4
|
+
description = "Generic lifecycle root that routes authoring and run operations."
|
|
5
|
+
} (
|
|
6
|
+
<SkillMetadata { href = "vfs://./SKILL.metadata.yaml" format = "yaml" }>
|
|
7
|
+
<Template { href = "vfs://./SKILL.template.ejs" format = "ejs" }>
|
|
8
|
+
<SkillDependencies [
|
|
9
|
+
<SkillDependency { ref = "resource://example.resource_lifecycle.skill.authoring" version = "1.0.0" }>
|
|
10
|
+
<SkillDependency { ref = "resource://example.resource_lifecycle.skill.run" version = "1.0.0" }>
|
|
11
|
+
]>
|
|
12
|
+
)>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<KindDefinition #halfcode.resource_kind.SkillCapsule apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
lifecycle = "Stable"
|
|
3
|
+
description = "Versioned Skill capsule with exact sibling dependencies."
|
|
4
|
+
resourceKind = "SkillCapsule"
|
|
5
|
+
sourceShapes = ["directory"]
|
|
6
|
+
currentApiVersion = "halfcode.resources/v1"
|
|
7
|
+
supportedApiVersions = ["halfcode.resources/v1"]
|
|
8
|
+
} (
|
|
9
|
+
<DescriptorContract (
|
|
10
|
+
<RequiredFiles [
|
|
11
|
+
<File { name = "SKILL.metadata.yaml" }>
|
|
12
|
+
<File { name = "SKILL.template.ejs" }>
|
|
13
|
+
]>
|
|
14
|
+
<SkillDependencyContract {
|
|
15
|
+
collection = "SkillDependencies"
|
|
16
|
+
member = "SkillDependency"
|
|
17
|
+
refScheme = "resource"
|
|
18
|
+
targetKind = "SkillCapsule"
|
|
19
|
+
versionBinding = "exact"
|
|
20
|
+
}>
|
|
21
|
+
<IncludeContract {
|
|
22
|
+
collection = "Includes"
|
|
23
|
+
relation = "compiled-resource-selection"
|
|
24
|
+
dependencySemantics = false
|
|
25
|
+
}>
|
|
26
|
+
)>
|
|
27
|
+
)>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<SkillCapsule #example.resource_lifecycle.skill.resource_dsl apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
name = "example-resource-lifecycle-dsl"
|
|
3
|
+
lifecycle = "Stable"
|
|
4
|
+
description = "Shared resource DSL reference used by authoring operations."
|
|
5
|
+
} (
|
|
6
|
+
<SkillMetadata { href = "vfs://./SKILL.metadata.yaml" format = "yaml" }>
|
|
7
|
+
<Template { href = "vfs://./SKILL.template.ejs" format = "ejs" }>
|
|
8
|
+
)>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<SkillCapsule #example.resource_lifecycle.skill.run apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
name = "example-resource-lifecycle-run"
|
|
3
|
+
lifecycle = "Active"
|
|
4
|
+
description = "Generic operations for running an authored resource."
|
|
5
|
+
} (
|
|
6
|
+
<SkillMetadata { href = "vfs://./SKILL.metadata.yaml" format = "yaml" }>
|
|
7
|
+
<Template { href = "vfs://./SKILL.template.ejs" format = "ejs" }>
|
|
8
|
+
)>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Files And Bundles
|
|
2
|
+
|
|
3
|
+
## 内容为真源
|
|
4
|
+
|
|
5
|
+
kind 与 identity 来自文件根 tag 和 `#id`。目录名、文件名和 catalog 路径只是布局;扫描器不得通过后缀或目录名补写资源语义。
|
|
6
|
+
|
|
7
|
+
## 两种定义形态
|
|
8
|
+
|
|
9
|
+
- 单文件 definition:任意描述性 `.xnl` 文件名,文件内有一个语义根。
|
|
10
|
+
- 目录 bundle:入口固定为 `manifest.xnl`,域文件使用描述性 `.xnl` 文件名。
|
|
11
|
+
|
|
12
|
+
目录 bundle 示例:
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
Functions/
|
|
16
|
+
PrepareData/
|
|
17
|
+
manifest.xnl # <Function #demo.resource_workflow.prepare_data ...>
|
|
18
|
+
instruction.md # CodeBinding/Instruction 引用的 material
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`manifest.xnl` 的根决定 bundle kind 与 identity。独立子域可以从 manifest 的 `()` 原样外提为同型域文件;外提不改变 logical refs。
|
|
22
|
+
|
|
23
|
+
## 单文件 forest
|
|
24
|
+
|
|
25
|
+
单文件默认只有一个语义根。仅当对应 `KindDefinition` 同时声明 `sourceShapes = ["single-file"]` 与 `documentCardinality = "many"` 时,同一个 `.xnl` authority 文件才可以包含多个并列根。
|
|
26
|
+
|
|
27
|
+
forest 的每个根是独立资源,必须使用同一 Kind,具有独立 `#id`,并通过该 Kind 的版本契约。`ResourcePackage`、catalog、KindDefinition 与目录 bundle 入口始终保持单根。
|
|
28
|
+
|
|
29
|
+
## Provenance 与 logical path
|
|
30
|
+
|
|
31
|
+
loader 为每个 normalized descriptor 附加只读 provenance:
|
|
32
|
+
|
|
33
|
+
- `documentUri`:加载 authority 文档的 canonical VFS URI;
|
|
34
|
+
- `logicalPath`:相对 package catalog root 的逻辑路径;
|
|
35
|
+
- `packageId`:从 `ResourcePackage #id` 派生;
|
|
36
|
+
- `resourceId`:来自 descriptor 根 `#id`。
|
|
37
|
+
|
|
38
|
+
这些字段由 loader 拥有,author 不在 descriptor 中重复配置。consumer 可以记录 provenance 用于诊断,但不得修改后反写 XNL。
|
|
39
|
+
|
|
40
|
+
## 扫描边界
|
|
41
|
+
|
|
42
|
+
- 默认目录入口仅为 `manifest.xnl`。
|
|
43
|
+
- `single-file` catalog 缺省扫描 root 下全部 `.xnl`;声明 `entry = "name.xnl"` 时只加载该文件,便于多个不同 Kind 共用一个物理目录。
|
|
44
|
+
- 非入口 `.xnl` 文件只能作为显式域/物料被入口引用,不能被重复注册为第二资源。
|
|
45
|
+
- 多根文档必须由 KindDefinition 显式授权;loader 不根据文件名或根数量猜测 forest 语义。
|
|
46
|
+
- catalog root 必须是 `vfs://` URI。
|
|
47
|
+
- resource-core 负责 URI 解析、边界检查和重复 identity 诊断;consumer 不自行扫描磁盘。
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Halfcode XNL Resource DSL
|
|
2
|
+
|
|
3
|
+
## 目录职责
|
|
4
|
+
|
|
5
|
+
- **holds**:halfcode resource package、catalog、KindDefinition、descriptor、mapping、URI 与文件组织的 XNL authoring 真源。
|
|
6
|
+
- **excludes**:parser/registry 实现(→`packages/resource-core/`)、consumer 归一化逻辑(→各 consumer package)、运行态数据与 BusinessObject/PageObject 尚未稳定的专用 API。
|
|
7
|
+
- **tier**:`stable`
|
|
8
|
+
- **promotes_from**:Codument track `define-xnl-resource-dsl` 的 proposal、design、behavior 与 modeling delta。
|
|
9
|
+
- **promotes_to**:资源 authoring 文件、loader/validator、consumer contract tests 与公开文档。
|
|
10
|
+
|
|
11
|
+
本目录定义 halfcode 资源的 XNL-native 语言。XNL 文档是可持久化语义真源;normalized descriptors、application assembly、发布制品和运行快照都是可重建投影,不得反向成为第二份 authoring 定义。
|
|
12
|
+
|
|
13
|
+
## 核心公理
|
|
14
|
+
|
|
15
|
+
一个节点的完整形态是:
|
|
16
|
+
|
|
17
|
+
```xnl
|
|
18
|
+
<Tag #id apiVersion="halfcode.resources/v1" version="1.0.0" { properties } ( unique-subdomains ) [ repeated-or-ordered-members ]>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
| 通道 | 唯一职责 | 资源 DSL 用法 |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `Tag` | 节点类别 | `ResourcePackage`、`KindDefinition`、`Function`、`ResourceMappings` 等资源 kind |
|
|
24
|
+
| `#id` | 节点身份 | 可跨容器引用的 FQN;不从文件名推断 |
|
|
25
|
+
| metadata 位 | 系统级版本 | `apiVersion`、`version` |
|
|
26
|
+
| `{}` | 无序业务属性 | lifecycle、description、kind、src、root 等标量或内联结构 |
|
|
27
|
+
| `()` | 每父节点唯一的命名子域 | `Catalogs`、`DescriptorContract`、`Instruction`、`CodeBinding` 等 |
|
|
28
|
+
| `[]` | 直接、有序或可重复事实 | catalog 条目、mapping 条目、includes 等 |
|
|
29
|
+
|
|
30
|
+
规则的重点是语义分配,不是把 XML tag/attribute 机械换一种括号。consumer 不得读取 parser-private 字段,也不得重建 `@_attribute` 一类 XML 对象形状。
|
|
31
|
+
|
|
32
|
+
## 权威文档
|
|
33
|
+
|
|
34
|
+
| 文档 | 回答的问题 |
|
|
35
|
+
|---|---|
|
|
36
|
+
| [language.md](language.md) | XNL 通道、身份、引用、声明式边界与 normalized projection。 |
|
|
37
|
+
| [documents.md](documents.md) | package、catalog、KindDefinition、descriptor、mapping 各自长什么样。 |
|
|
38
|
+
| [files.md](files.md) | 单文件/目录 bundle、`manifest.xnl`、logical path 与 provenance。 |
|
|
39
|
+
| [projections.md](projections.md) | 单包 tree、ordered layers、tombstone、typed dependency 与 revision 的 authority 边界。 |
|
|
40
|
+
| [skill-capsules.md](skill-capsules.md) | SkillCapsule version authority、sibling dependency、closure plan/apply 与 host 边界。 |
|
|
41
|
+
| [migration.md](migration.md) | XML authority 如何迁移,哪些做法被明确拒绝。 |
|
|
42
|
+
| [examples/](examples/) | 由当前 `xnl-core` parser 验证的规范实例。 |
|
|
43
|
+
|
|
44
|
+
KindDefinition 同时拥有资源版本契约:`currentApiVersion` 指向当前 authoring 版本,`supportedApiVersions` 列出可直接加载的兼容版本。版本转换由 `halfcode-compiler.xnl/kind-definition` 的代码侧 migration registry 执行,XNL 不承载可执行转换。成功加载的规范化 contract 可从 `ResourceTree.registry.kindDefinitions` 读取,consumer 无需再次解析 Kind XNL。
|
|
45
|
+
|
|
46
|
+
多个 package 的组合不产生新的 authoring authority。canonical loader 在同一次 raw-byte read 中产生 `LoadedResourceTree.contentIdentities`;`resolveEffectiveResourceContentIdentities()` 再从 exact effective layer 选择 authority identity 并合并 Kind owner 的显式 digest contributions。`EffectiveResourceRegistry` 和 `ResourceDependencySnapshot` 都是由已验证 XNL、显式 tombstone、typed edge 与 digest contribution 重建的只读投影;它们不得被序列化回 XNL 作为第二份事实源。完整规则见 [projections.md](projections.md)。
|
|
47
|
+
|
|
48
|
+
本目录自身也是 `Halfcode.ResourceDsl.Package@1.0.0`:XNL descriptors 只登记 canonical Markdown/XNL materials,不复制正文。`Halfcode.ResourceDsl.Skill.System` 编译为 `sys-halfcode-resource-dsl@1.0.0`,供离线消费者按需加载这些文档;每个 capsule 的 `references/.halfcode/provenance.json` 绑定 source FQN/apiVersion/version、生成协议和 payload digests。
|
|
49
|
+
|
|
50
|
+
## 暂缓边界
|
|
51
|
+
|
|
52
|
+
BusinessObject 与 PageObject 的通用外壳仍服从本目录的 `Tag/#id/metadata/{}/()/[]` 公理,但以下内容在当前版本中**刻意不定义**:
|
|
53
|
+
|
|
54
|
+
- 专用字段与 operation/mutation/action 模型;
|
|
55
|
+
- application assembly 的二者专用 public types;
|
|
56
|
+
- 参考实现正在重构的 PageObject API 映射;
|
|
57
|
+
- 二者最终 KindDefinition descriptor contract。
|
|
58
|
+
|
|
59
|
+
这些内容由 mission `halfcode-compiler-xnl-migration` 的 `LATE-BO-PO` group 在重新观察参考实现后补充。
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Language Axioms
|
|
2
|
+
|
|
3
|
+
## 身份与分类
|
|
4
|
+
|
|
5
|
+
- 根 tag 是资源 kind;PascalCase 保留给 DSL 结构节点。
|
|
6
|
+
- 可跨容器复用的资源在 `#id` 使用点分 FQN,例如 `#demo.resource_workflow.prepare_data`。
|
|
7
|
+
- 文件路径只负责物理布局,不决定 kind 或 identity。移动文件不改变 `#id`。
|
|
8
|
+
- `apiVersion` 与 `version` 写在 metadata 位;title、lifecycle、description 等业务数据若属于该 Kind,则写入 `{}`。
|
|
9
|
+
- 通用资源边界只要求根 `#id` 与 `apiVersion`。`lifecycle`、`description` 的存在性和语义由具体 Kind 或 consumer contract 决定,resource-core 不提供虚假默认值。
|
|
10
|
+
- 每个 KindDefinition 显式声明 `currentApiVersion` 与 `supportedApiVersions`;loader 不猜测未知版本,也不自动执行迁移。具体系统通过公开 `ResourceMigrationRegistry` 注册纯转换函数,得到唯一版本链后再加载目标文档。
|
|
11
|
+
- XNL authority 默认单根。只有 source shape 严格为 `single-file` 的 Kind 可以通过 `documentCardinality = "many"` 授权同 Kind forest;每个顶层根仍是独立资源,`[]` 继续只表达节点内部的重复子项。
|
|
12
|
+
- 静态描述数据由所属节点自持,不寄存在另一域再引用回来。
|
|
13
|
+
|
|
14
|
+
## 子域与重复事实
|
|
15
|
+
|
|
16
|
+
`()` 表示父节点拥有的唯一子域概念。同一父节点的 `()` 中,同名 tag 只能出现一次。重复条目由复数子域的 `[]` 承载:
|
|
17
|
+
|
|
18
|
+
```xnl
|
|
19
|
+
<ResourcePackage #demo.package (
|
|
20
|
+
<Catalogs [
|
|
21
|
+
<Catalog #functions { kind = "Function" root = "vfs://./Functions/" entry = "manifest.xnl" }>
|
|
22
|
+
<Catalog #skills { kind = "SkillCapsule" root = "vfs://./Skills/" entry = "manifest.xnl" }>
|
|
23
|
+
]>
|
|
24
|
+
)>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
直接、有序或可重复的事实进入 `[]`。禁止为了凑层级增加没有领域语义的 `Nodes`、`Items` 或 `Block` 包装;复数容器必须确实代表一个唯一子域概念。
|
|
28
|
+
|
|
29
|
+
## URI 与代码引用
|
|
30
|
+
|
|
31
|
+
所有跨节点/文件引用都是引号字符串 URI:
|
|
32
|
+
|
|
33
|
+
| 目标 | canonical 形态 | 示例 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| 当前 bundle 相对文件 | `vfs://./<path>` | `vfs://./instruction.md` |
|
|
36
|
+
| workspace 文件 | `vfs://@/<path>` | `vfs://@/apps/demo/src/procedures.ts` |
|
|
37
|
+
| TypeScript 导出 | `vfs://...#<ExportName>` | `vfs://@/apps/demo/src/procedures.ts#prepareProcedure` |
|
|
38
|
+
| 规范资源 identity | `resource://<FQN>` | `resource://demo.resource_workflow.prepare_data` |
|
|
39
|
+
| 当前容器 id | `<domain>://#<id>` | `catalog://#functions` |
|
|
40
|
+
|
|
41
|
+
代码引用必须包含 export fragment。XNL 只保存声明式 binding;函数、闭包、表达式字符串和 handler object 不得内嵌到 XNL。执行代码的协议和副作用由 runtime/component contract 定义,不属于 parser。
|
|
42
|
+
|
|
43
|
+
## Authoring 与 projection
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
XNL authority document
|
|
47
|
+
-> xnl-core node tree
|
|
48
|
+
-> validated normalized resource descriptor + provenance
|
|
49
|
+
-> registry / mapping / application assembly projections
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- authority:磁盘上的 `.xnl` 文档;唯一可编辑事实。
|
|
53
|
+
- parser tree:语法投影,只由 resource-core loader 消费。
|
|
54
|
+
- normalized descriptor:稳定领域边界,携带 `resourceId`、`kind`、metadata、members、subdomains、`documentUri`、`logicalPath`;Kind-owned 可选属性保持存在或缺失的原始事实。
|
|
55
|
+
- consumer projection:可重建;不得暴露 parser node 内部字段,也不得反写 authority。
|
|
56
|
+
|
|
57
|
+
package provenance 从 package manifest、document URI 与 logical path 派生。descriptor 不重复保存一份可由路径计算的 package identity。
|
|
58
|
+
|
|
59
|
+
## 声明式限制
|
|
60
|
+
|
|
61
|
+
- 一个 bundle 内的配置只使用 XNL,不引入 JSON/XML/YAML 第二配置入口。
|
|
62
|
+
- 动态代码保存在 `.ts` 等外部文件,通过 `vfs://...#Export` 挂接。
|
|
63
|
+
- 不允许将 XML attributes 转换成 `@_name` 或其他前缀键后暴露给 consumer。
|
|
64
|
+
- 不允许根据文件名猜测 kind;文件内容的 tag 才是 authority。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<ResourcePackage #Halfcode.ResourceDsl.Package apiVersion="halfcode.resources/v1" version="1.0.0" {
|
|
2
|
+
lifecycle = "Stable"
|
|
3
|
+
description = "Canonical Halfcode Resource DSL documentation and consumer Skill resources."
|
|
4
|
+
} (
|
|
5
|
+
<Catalogs [
|
|
6
|
+
<Catalog #KindDefinitions { kind = "KindDefinition" shape = "directory" root = "vfs://./KindDefinitions/" entry = "manifest.xnl" }>
|
|
7
|
+
<Catalog #WikiPages { kind = "WikiPage" shape = "directory" root = "vfs://./WikiPages/" entry = "manifest.xnl" }>
|
|
8
|
+
<Catalog #SkillCapsules { kind = "SkillCapsule" shape = "directory" root = "vfs://./SkillCapsules/" entry = "manifest.xnl" }>
|
|
9
|
+
]>
|
|
10
|
+
)>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# XML To XNL Migration
|
|
2
|
+
|
|
3
|
+
## 迁移原则
|
|
4
|
+
|
|
5
|
+
迁移单位是“资源语义”,不是 tag/attribute 的逐字符替换:
|
|
6
|
+
|
|
7
|
+
| XML-era 表达 | XNL authority |
|
|
8
|
+
|---|---|
|
|
9
|
+
| 根 element 名 | 根 tag(resource kind) |
|
|
10
|
+
| `Id`/`Name` 等身份 attribute | 根 `#id` FQN;display name 若存在则留在 `{}` |
|
|
11
|
+
| `Version`/schema version | metadata 位的 `version`/`apiVersion` |
|
|
12
|
+
| 普通 attributes | `{}` 中归节点所有的属性 |
|
|
13
|
+
| 唯一 child section | `()` 中的唯一子域 |
|
|
14
|
+
| 重复 child elements | 父 `[]` 或复数子域的 `[]` |
|
|
15
|
+
| 文件路径/code export | 引号字符串 `vfs://...#Export` |
|
|
16
|
+
| parser `@_foo`/XmlObject | 不迁移;在 normalized descriptor 边界消失 |
|
|
17
|
+
|
|
18
|
+
## 顺序
|
|
19
|
+
|
|
20
|
+
1. 用 `KindDefinition` 明确 kind contract。
|
|
21
|
+
- 声明 `currentApiVersion` 与 `supportedApiVersions`。
|
|
22
|
+
- 对不可直接兼容的历史版本,在代码侧 `ResourceMigrationRegistry` 注册唯一纯转换链;XNL 不内嵌 transformer。
|
|
23
|
+
2. 将 package/catalog authority 改为 XNL。
|
|
24
|
+
3. 逐个资源按领域语义分配 `{}`、`()`、`[]`,保留稳定 `#id`。
|
|
25
|
+
4. 将路径与代码引用规范为 VFS URI。
|
|
26
|
+
5. 通过 resource-core 得到 normalized descriptor,再迁移 consumer。
|
|
27
|
+
6. 删除兼容 XML 与 `fast-xml-parser`,以产品 XML inventory 清零作为关闭条件。
|
|
28
|
+
|
|
29
|
+
## 明确拒绝
|
|
30
|
+
|
|
31
|
+
- 在 TypeScript 中保留 `XmlObject`、`@_` 属性前缀或 XML child-array 作为公开类型。
|
|
32
|
+
- 同一资源同时维护 XML 与 XNL 两份长期 authority。
|
|
33
|
+
- 根据目录名/文件名猜 kind 或 identity。
|
|
34
|
+
- 在 XNL 内嵌函数、闭包或可执行表达式字符串。
|
|
35
|
+
- 用无语义的 wrapper 模拟 XML 层级。
|
|
36
|
+
- 在 BusinessObject/PageObject API 尚未稳定时提前设计二者的专用 XNL schema。
|
|
37
|
+
|
|
38
|
+
## 暂时兼容
|
|
39
|
+
|
|
40
|
+
后续实现 track 可以在内部短期 dual-read,用于小步迁移和 characterization test;兼容层不得进入 public API,并必须在 `close-xnl-only-product-surface` track 删除。
|