@voxgig/sdkgen 1.3.7 → 1.3.8

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.
@@ -0,0 +1,286 @@
1
+ // Shared prose for the generated agent guides (AGENTS.md files emitted at the
2
+ // project top level, per target language, and per feature). The workflow, the
3
+ // two-layer template/component model, and the aontu primer are identical for
4
+ // every generated SDK, so they live here once and the three AgentGuide
5
+ // components (AgentGuideTop / AgentGuide / AgentGuideFeature) render them.
6
+ //
7
+ // IMPORTANT: these guides ship INSIDE a generated SDK project, so every path is
8
+ // consumer-relative (`.sdk/tm/<lang>/`, `.sdk/src/cmp/<lang>/`,
9
+ // `.sdk/model/...`) — NOT the `project/.sdk/...` form used by the sdkgen repo's
10
+ // own developer docs.
11
+
12
+ import { each } from 'jostraca'
13
+
14
+ import {
15
+ KIT,
16
+ getModelPath,
17
+ } from '../types'
18
+
19
+
20
+ // Build/test commands for a generated target directory. Every SDK target ships
21
+ // a Makefile (`make build` / `make test` are the source of truth), so
22
+ // `viaMake` targets render those; only the dependency-install step is
23
+ // ecosystem-specific. go-cli / go-mcp are non-SDK surfaces (build only).
24
+ type LangCmd = { install?: string, build?: string, test?: string, viaMake?: boolean, note?: string }
25
+
26
+ const LANG_CMD: Record<string, LangCmd> = {
27
+ ts: { install: 'npm install', viaMake: true },
28
+ js: { install: 'npm install', viaMake: true },
29
+ go: { viaMake: true },
30
+ py: { install: 'pip install -e .', viaMake: true },
31
+ php: { install: 'composer install', viaMake: true },
32
+ rb: { install: 'bundle install', viaMake: true },
33
+ lua: { install: 'luarocks make', viaMake: true },
34
+ 'go-cli': { build: 'go build ./...', note: 'A CLI surface, not an SDK client library.' },
35
+ 'go-mcp': { build: 'go build ./...', note: 'An MCP server surface for AI agents, not an SDK client library.' },
36
+ }
37
+
38
+
39
+ function langCmd(name: string): LangCmd {
40
+ return LANG_CMD[name] || { viaMake: true }
41
+ }
42
+
43
+
44
+ // A fenced shell block of the per-target build/test commands, run **in the
45
+ // target directory** (the per-language guide already lives there). Prefers the
46
+ // target's Makefile recipes (`make build` / `make test`).
47
+ function langCommandsBlock(name: string): string {
48
+ const c = langCmd(name)
49
+ const lines: string[] = []
50
+ if (c.install) lines.push(c.install)
51
+ if (c.viaMake) {
52
+ lines.push('make build')
53
+ lines.push('make test')
54
+ }
55
+ else {
56
+ if (c.build) lines.push(c.build)
57
+ if (c.test) lines.push(c.test)
58
+ }
59
+ if (0 === lines.length) {
60
+ return `Build and test with \`${name}\`'s standard toolchain.\n`
61
+ }
62
+ return '```bash\n# in this target directory (' + name + '/):\n' + lines.join('\n') + '\n```\n'
63
+ }
64
+
65
+
66
+ // --- feature layout helpers (targets differ) --------------------------------
67
+
68
+ // Whether a target generates per-feature output at all. go-cli / go-mcp
69
+ // disable the feature phase (`phase.feature.active: false`).
70
+ function featuresEnabled(target: any): boolean {
71
+ return target?.phase?.feature?.active !== false
72
+ }
73
+
74
+ // ts/js lay each feature out as a directory `src/feature/<name>/`; the other
75
+ // SDK targets (`srcfeature: false`) use flat files in a shared `feature/`
76
+ // package. Drives where feature guides live / are referenced.
77
+ function isDirLayout(target: any): boolean {
78
+ return target?.srcfeature !== false
79
+ }
80
+
81
+ function featureBase(target: any): string {
82
+ return isDirLayout(target) ? 'src/feature' : 'feature'
83
+ }
84
+
85
+ // The generated runtime file for a feature in a flat-layout target:
86
+ // `<name>_feature.<ext>` (go/py/rb/lua) or `<Name>Feature.php` (php).
87
+ function featureRuntimeFile(target: any, feature: any): string {
88
+ const ext = target?.ext || target?.name || ''
89
+ if ('php' === target?.name) {
90
+ return (feature.Name || feature.name) + 'Feature.php'
91
+ }
92
+ return feature.name + '_feature.' + ext
93
+ }
94
+
95
+ // A feature's active hook-stage names (feature.hook.<Stage>.active === true),
96
+ // sorted (each() marks map keys as key$).
97
+ function featureHooks(feature: any): string[] {
98
+ return each(feature.hook || {})
99
+ .filter((h: any) => h && h.active)
100
+ .map((h: any) => h.name || h.key$)
101
+ .filter(Boolean)
102
+ }
103
+
104
+
105
+ // --- model readers (mirror the active-item pattern in ReadmeTop.ts) ---
106
+
107
+ function activeTargets(model: any): any[] {
108
+ const target = getModelPath(model, `main.${KIT}.target`) || {}
109
+ return each(target).filter((t: any) => t && t.active !== false)
110
+ }
111
+
112
+ function activeFeatures(model: any): any[] {
113
+ const feature = getModelPath(model, `main.${KIT}.feature`) || {}
114
+ return each(feature).filter((f: any) => f && f.active !== false)
115
+ }
116
+
117
+ function activeEntities(model: any): any[] {
118
+ const entity = getModelPath(model, `main.${KIT}.entity`) || {}
119
+ return each(entity).filter((e: any) => e && e.active !== false)
120
+ }
121
+
122
+ function projectName(model: any): string {
123
+ return model.Name || model.const?.Name || model.name || 'SDK'
124
+ }
125
+
126
+
127
+ // --- shared markdown sections -----------------------------------------------
128
+
129
+ // (a) basic generation & updating.
130
+ function workflowSection(): string {
131
+ return `## Generating and updating the SDK
132
+
133
+ All generation is driven from the \`.sdk/\` directory. The generated language
134
+ directories (\`ts/\`, \`go/\`, …) are **build output** — never edit them by
135
+ hand; fix the model, a template, or a component and regenerate.
136
+
137
+ \`\`\`bash
138
+ cd .sdk
139
+ npm run add-target <lang> # scaffold a language target (ts js go py php rb lua ...)
140
+ npm run add-feature <name> # scaffold a feature (e.g. log, test)
141
+ npm run build # compile .sdk/src/cmp -> .sdk/dist
142
+ npm run generate # emit/refresh the SDK into ../<lang>
143
+ \`\`\`
144
+
145
+ \`generate\` **merges** into existing files and does **not** re-apply
146
+ placeholder substitution to merged content. If you ever see a literal
147
+ \`ProjectName\` or \`GOMODULE\` in generated output, delete that one file and
148
+ regenerate it fresh:
149
+
150
+ \`\`\`bash
151
+ rm <lang>/<the-file-with-the-placeholder>
152
+ npm run generate
153
+ \`\`\`
154
+
155
+ Note: the \`voxgig-sdkgen\` CLI only *scaffolds* (\`target add\` /
156
+ \`feature add\`). Generation itself runs via \`npm run generate\` (backed by
157
+ \`@voxgig/model\`) — there is no \`generate\` CLI subcommand.
158
+ `
159
+ }
160
+
161
+
162
+ // (b) adding a new generated feature.
163
+ function featureSection(): string {
164
+ return `## Adding a feature
165
+
166
+ A **feature** is a pipeline extension: an object of hooks that fire at named
167
+ stages of every entity operation (each target's guide documents its
168
+ features). Built-in features are \`log\` and \`test\`.
169
+
170
+ \`\`\`bash
171
+ cd .sdk
172
+ npm run add-feature <name> # e.g. log (comma-separated for several)
173
+ npm run build && npm run generate
174
+ \`\`\`
175
+
176
+ To author a **new** feature:
177
+
178
+ 1. Define its model at \`.sdk/model/feature/<name>.aontu\` — \`name: key()\`,
179
+ \`title\`, \`version\`, \`active\`, \`config.options.active\`, a \`hook\`
180
+ map (\`<Stage>: active: true\`), and per-language \`deps\`.
181
+ 2. Register it in \`.sdk/model/feature/feature-index.aontu\` with
182
+ \`@"<name>.aontu"\`.
183
+ 3. Provide the per-language runtime under that target's feature template dir
184
+ (\`.sdk/tm/<lang>/src/feature/<name>/\` for ts/js, \`.sdk/tm/<lang>/feature/\`
185
+ otherwise) — the \`FEATURE_Name\` / \`FEATURE_VERSION\` placeholders are
186
+ substituted on \`add-feature\`.
187
+ 4. \`npm run add-feature <name> && npm run build && npm run generate\`.
188
+ `
189
+ }
190
+
191
+
192
+ // (c) customising the model and templates (the two-layer mental model).
193
+ function customiseSection(): string {
194
+ return `## Customising: model, templates, components
195
+
196
+ Each language target is generated from **two layers**:
197
+
198
+ | Layer | Path | Nature |
199
+ | --- | --- | --- |
200
+ | **Templates** | \`.sdk/tm/<lang>/\` | Plain target-language source, copied verbatim with placeholder substitution. Edit when the file is the **same for every API** (transport, base classes, runtime, utilities). |
201
+ | **Components** | \`.sdk/src/cmp/<lang>/\` | TypeScript that **generates** source by walking the model. Edit when the file's shape **depends on the API** (entity classes, the constructor, README, tests). |
202
+
203
+ > Decision rule: *same for every API → template; depends on the API →
204
+ > component.*
205
+
206
+ Placeholders substituted on copy: \`ProjectName\` (Pascal-case SDK name),
207
+ \`GOMODULE\` (Go module path), \`FEATURE_Name\` / \`FEATURE_VERSION\`, and the
208
+ \`$$path$$\` interpolation of a model value (such as the name) in \`.aontu\`.
209
+
210
+ Propagate a change: edit the template/component → \`npm run build\` (only
211
+ needed if you touched a component) → \`npm run generate\`. Target shape and
212
+ deps live in \`.sdk/model/target/<lang>.aontu\`; features in
213
+ \`.sdk/model/feature/<name>.aontu\`.
214
+ `
215
+ }
216
+
217
+
218
+ // (d) how the aontu model language works.
219
+ function aontuSection(): string {
220
+ return `## The model language (aontu, \`.aontu\` files)
221
+
222
+ The model is one structured object assembled by **aontu** (a unification
223
+ engine) from three sources: the API model (entities/operations, from the
224
+ OpenAPI spec via \`@voxgig/apidef\`), the base schema, and the target/feature
225
+ definitions in \`.sdk/model/\`. An \`.aontu\` file is a relaxed JSON (jsonic
226
+ syntax) with unification semantics:
227
+
228
+ | Syntax | Meaning |
229
+ | --- | --- |
230
+ | \`a: b: c: 1\` | Nested-object shorthand for \`a:{b:{c:1}}\`. |
231
+ | \`&: { ... }\` | Schema applied to **every** child of a map (one rule, many entries). |
232
+ | \`*default \\| type\` | A default value unified against a type (e.g. \`*true \\| boolean\`). |
233
+ | \`name: key()\` | Bind a field to its map key (so \`feature: log: {}\` gets \`name: 'log'\`). |
234
+ | \`$$path$$\` | Interpolate a model value into a string — e.g. the SDK \`name\`. |
235
+ | \`@"file.aontu"\` | Include another fragment (how the index files work). |
236
+ | \`x: .y\` | Reference another path's value (e.g. \`deps: ts: .js\`). |
237
+
238
+ For example, the schema for every feature entry:
239
+
240
+ \`\`\`aontu
241
+ main: kit: feature: &: {
242
+ name: key()
243
+ active: *false | boolean
244
+ title: string
245
+ version: *'0.0.1' | string
246
+ hook: &: { active: *false | boolean, await: *false | boolean }
247
+ }
248
+ \`\`\`
249
+
250
+ Caveat: literal disjunctions (\`'prod' | 'peer' | 'dev'\`) are fragile in
251
+ aontu, so the model uses \`*'prod' | string\` and enforces the enum in code —
252
+ do not "fix" these into literal disjunctions.
253
+ `
254
+ }
255
+
256
+
257
+ // A thin CLAUDE.md that points at the sibling AGENTS.md (same directory).
258
+ function claudePointer(title: string): string {
259
+ return `# ${title}
260
+
261
+ This project uses **AGENTS.md** as the operating guide for coding agents.
262
+
263
+ See [AGENTS.md](./AGENTS.md).
264
+ `
265
+ }
266
+
267
+
268
+ export {
269
+ LANG_CMD,
270
+ langCmd,
271
+ langCommandsBlock,
272
+ featuresEnabled,
273
+ isDirLayout,
274
+ featureBase,
275
+ featureRuntimeFile,
276
+ featureHooks,
277
+ activeTargets,
278
+ activeFeatures,
279
+ activeEntities,
280
+ projectName,
281
+ workflowSection,
282
+ featureSection,
283
+ customiseSection,
284
+ aontuSection,
285
+ claudePointer,
286
+ }
@@ -0,0 +1,107 @@
1
+
2
+ import { cmp, each, Content, File, Folder } from 'jostraca'
3
+
4
+ import { claudePointer } from './AgentGuideContent'
5
+
6
+
7
+ function cap(s: string): string {
8
+ return s ? s.charAt(0).toUpperCase() + s.slice(1) : s
9
+ }
10
+
11
+
12
+ // Per-feature agent guide, co-located with the feature's generated runtime.
13
+ // Invoked from AgentGuide inside the ambient target folder, so it lands at
14
+ // `<lang>/src/feature/<name>/AGENTS.md`.
15
+ const AgentGuideFeature = cmp(function AgentGuideFeature(props: any) {
16
+ const { target, feature, ctx$ } = props
17
+
18
+ const name = feature.name
19
+ const Name = feature.Name || cap(name)
20
+ const title = feature.title || `${Name} feature`
21
+ const version = feature.version || '0.0.1'
22
+ const lang = target.name
23
+
24
+ // Active hook stages (feature.hook.<Stage>.active === true).
25
+ const hooks = each(feature.hook || {})
26
+ .filter((h: any) => h && h.active)
27
+ .map((h: any) => h.name || h.key$)
28
+ .filter(Boolean)
29
+
30
+ const defaultOn = true === feature?.config?.options?.active
31
+
32
+ Folder({ name: 'src/feature/' + name }, () => {
33
+
34
+ File({ name: 'AGENTS.md' }, () => {
35
+ Content(`# ${Name}Feature — Agent Guide
36
+
37
+ ${title} (v${version}).
38
+
39
+ A **feature** is a pipeline extension: an object of hooks that fire at named
40
+ stages of every entity operation (load, list, create, update, remove) and of
41
+ the SDK/entity lifecycle. Features are how you inspect or modify the request
42
+ pipeline without forking the SDK. This directory holds the **generated**
43
+ runtime for the \`${name}\` feature in the ${target.title || lang} target — do
44
+ not edit it by hand; change its template/model in \`.sdk/\` and regenerate.
45
+
46
+ Active by default: **${defaultOn ? 'yes' : 'no'}** (\`config.options.active\`
47
+ in the model). ${defaultOn
48
+ ? 'It runs unless disabled.'
49
+ : 'It only runs when explicitly enabled (e.g. the `test` feature is switched on for test mode).'}
50
+
51
+ `)
52
+
53
+ if (0 < hooks.length) {
54
+ Content(`## Hooks it fires
55
+
56
+ ${hooks.map((h: string) => `- \`${h}\``).join('\n')}
57
+
58
+ Each active hook runs at its pipeline stage in feature-registration order, so a
59
+ later feature can override an earlier one.
60
+
61
+ `)
62
+ }
63
+
64
+ Content(`## Where it is defined
65
+
66
+ | Part | Path |
67
+ | --- | --- |
68
+ | Model definition | \`.sdk/model/feature/${name}.aontu\` (name, title, version, \`config.options.active\`, the \`hook\` map, per-language \`deps\`) |
69
+ | Registered in | \`.sdk/model/feature/feature-index.aontu\` (\`@"${name}.aontu"\`) |
70
+ | Runtime template | \`.sdk/tm/${lang}/src/feature/${name}/\` (copied here on \`generate\`; \`FEATURE_Name\`/\`FEATURE_VERSION\` substituted) |
71
+
72
+ (Paths are relative to the **project root** — four levels up from here.)
73
+
74
+ ## Customising this feature
75
+
76
+ - **Turn hooks on/off**: edit the \`hook\` map in
77
+ \`.sdk/model/feature/${name}.aontu\` (\`<Stage>: active: true|false\`).
78
+ - **Change default activation**: set \`config.options.active\` in the same file.
79
+ - **Dependencies**: edit \`deps.<lang>\` in the same file.
80
+ - **Behaviour**: edit the runtime template under
81
+ \`.sdk/tm/${lang}/src/feature/${name}/\`, then regenerate.
82
+
83
+ After any change: \`cd ../../../../.sdk && npm run generate\` (add
84
+ \`npm run build\` first if you changed a component). If a regenerated file
85
+ shows a literal \`FEATURE_Name\`/\`ProjectName\`, delete it and regenerate.
86
+
87
+ To author a **new** feature, copy this one's model + template shape — see the
88
+ [project guide](../../../../AGENTS.md) and the
89
+ [${target.title || lang} guide](../../../AGENTS.md).
90
+ `)
91
+ })
92
+
93
+ File({ name: 'CLAUDE.md' }, () => {
94
+ Content(claudePointer(`${Name}Feature (${lang})`))
95
+ })
96
+ })
97
+
98
+ ctx$.log?.info?.({
99
+ point: 'generate-agentguide-feature', target, feature,
100
+ note: 'target:' + lang + ', feature:' + name,
101
+ })
102
+ })
103
+
104
+
105
+ export {
106
+ AgentGuideFeature
107
+ }
@@ -0,0 +1,121 @@
1
+
2
+ import { cmp, names, Content, File } from 'jostraca'
3
+
4
+ import {
5
+ activeTargets,
6
+ activeFeatures,
7
+ activeEntities,
8
+ projectName,
9
+ workflowSection,
10
+ featureSection,
11
+ customiseSection,
12
+ aontuSection,
13
+ claudePointer,
14
+ langCmd,
15
+ } from './AgentGuideContent'
16
+
17
+
18
+ // Top-level agent guide for a generated SDK project. Emitted once at the
19
+ // project root (no enclosing Folder), alongside README.md/Makefile. Teaches a
20
+ // coding agent how to operate the whole project: regenerate, add features,
21
+ // customise the model/templates, and read the aontu model language.
22
+ const AgentGuideTop = cmp(function AgentGuideTop(props: any) {
23
+ const { ctx$ } = props
24
+ const { model } = ctx$
25
+
26
+ if (model.name && !model.Name) names(model, model.name)
27
+
28
+ const Name = projectName(model)
29
+ const targets = activeTargets(model)
30
+ const features = activeFeatures(model)
31
+ const entities = activeEntities(model)
32
+
33
+ File({ name: 'AGENTS.md' }, () => {
34
+ Content(`# ${Name} SDK — Agent Guide
35
+
36
+ This is a **generated** multi-language SDK project. The client libraries in
37
+ each language directory are produced by [@voxgig/sdkgen](https://github.com/voxgig/sdkgen)
38
+ from an API model; the generator, model, templates, and components all live in
39
+ \`.sdk/\`. Treat the language directories as build output — change the model,
40
+ a template, or a component and regenerate.
41
+
42
+ There are companion guides deeper in the tree: one per language
43
+ (\`<lang>/AGENTS.md\`) and one per feature
44
+ (\`<lang>/src/feature/<name>/AGENTS.md\`).
45
+
46
+ ## Project map
47
+
48
+ `)
49
+
50
+ // Targets
51
+ if (0 < targets.length) {
52
+ Content(`**Targets** (${targets.length}):
53
+
54
+ | Target | Directory | Build guide |
55
+ | --- | --- | --- |
56
+ `)
57
+ targets.forEach((t: any) => {
58
+ const note = langCmd(t.name).note ? ' — ' + langCmd(t.name).note : ''
59
+ Content(`| \`${t.name}\` | \`${t.name}/\`${note} | [\`${t.name}/AGENTS.md\`](./${t.name}/AGENTS.md) |
60
+ `)
61
+ })
62
+ Content(`
63
+ `)
64
+ }
65
+
66
+ // Features
67
+ if (0 < features.length) {
68
+ Content(`**Features** (${features.length}): `)
69
+ Content(features.map((f: any) => `\`${f.name}\``).join(', ') + `.
70
+
71
+ Each feature is generated into every SDK target — as a directory
72
+ \`<lang>/src/feature/<name>/\` (ts/js) or a flat file in the \`<lang>/feature/\`
73
+ package (other languages). Each target's guide documents its features.
74
+
75
+ `)
76
+ }
77
+
78
+ // Entities
79
+ if (0 < entities.length) {
80
+ Content(`**Entities** (${entities.length}): `)
81
+ Content(entities.map((e: any) => `\`${e.Name || e.name}\``).join(', ') + `.
82
+
83
+ `)
84
+ }
85
+
86
+ Content(workflowSection())
87
+ Content(featureSection())
88
+ Content(customiseSection())
89
+ Content(aontuSection())
90
+
91
+ Content(`## Where things live
92
+
93
+ \`\`\`
94
+ .sdk/
95
+ model/ the model: target/, feature/, and index .aontu files
96
+ src/cmp/<lang>/ components — TypeScript that generates API-specific source
97
+ tm/<lang>/ templates — verbatim source copied with placeholders
98
+ dist/ compiled components (npm run build)
99
+ <lang>/ generated SDK for each target (build output)
100
+ README.md human-facing overview
101
+ Makefile per-target deploy recipes
102
+ \`\`\`
103
+
104
+ ---
105
+
106
+ Generated by [@voxgig/sdkgen](https://github.com/voxgig/sdkgen). Regenerate
107
+ with \`cd .sdk && npm run generate\`.
108
+ `)
109
+ })
110
+
111
+ File({ name: 'CLAUDE.md' }, () => {
112
+ Content(claudePointer(`${Name} SDK`))
113
+ })
114
+
115
+ ctx$.log?.info?.({ point: 'generate-agentguide-top', note: 'name:' + Name })
116
+ })
117
+
118
+
119
+ export {
120
+ AgentGuideTop
121
+ }
@@ -215,9 +215,22 @@ ${aboutMd.trim()}
215
215
  // mental model the SDK is built around (model-driven; lists real entities).
216
216
  if (activeEntities.length > 0) {
217
217
  const entNames = activeEntities.map((e: any) => e.Name)
218
- const entList = entNames.length > 1
218
+ const entCount = entNames.length
219
+ const entList = entCount > 1
219
220
  ? entNames.slice(0, -1).join(', ') + ' and ' + entNames[entNames.length - 1]
220
221
  : entNames[0]
222
+ // Only enumerate the entity names inline when the set is small enough that
223
+ // the list clarifies the mental model rather than becoming a wall of names
224
+ // at the top of the README. Larger APIs get a count and a pointer to the
225
+ // Entities table below — and we never assert a "small set" when it isn't.
226
+ const NAME_INLINE_MAX = 6
227
+ const inlineNames = entCount <= NAME_INLINE_MAX
228
+ const surface = inlineNames
229
+ ? `a small set of **semantic entities** — ${entList} —`
230
+ : `**${entCount} semantic entities**`
231
+ const seeEntities = inlineNames
232
+ ? ''
233
+ : ' See the [Entities](#entities) table below for the full list.'
221
234
  const exEnt = activeEntities[0]
222
235
  const ex = exEnt.Name
223
236
  const exLower = safeVarName(ex.toLowerCase(), 'ts')
@@ -254,8 +267,8 @@ ${aboutMd.trim()}
254
267
  const opList = (opNames.length ? opNames : ['list', 'load']).map((o) => '`' + o + '`').join(', ')
255
268
  Content(`## Entities, not endpoints
256
269
 
257
- This SDK exposes the API as a small set of **semantic entities** — ${entList} that you
258
- call directly, instead of assembling URL paths and query strings. Entities are
270
+ This SDK exposes the API as ${surface} that you
271
+ call directly, instead of assembling URL paths and query strings.${seeEntities} Entities are
259
272
  **Capitalised** to mark them as the primary surface, each with the operations they
260
273
  support (${opList}):
261
274
 
package/src/sdkgen.ts CHANGED
@@ -27,6 +27,9 @@ import { Entity } from './cmp/Entity'
27
27
  import { Feature } from './cmp/Feature'
28
28
  import { Readme } from './cmp/Readme'
29
29
  import { ReadmeTop } from './cmp/ReadmeTop'
30
+ import { AgentGuideTop } from './cmp/AgentGuideTop'
31
+ import { AgentGuide } from './cmp/AgentGuide'
32
+ import { AgentGuideFeature } from './cmp/AgentGuideFeature'
30
33
  import { License } from './cmp/License'
31
34
  import { Security } from './cmp/Security'
32
35
  import { Changelog } from './cmp/Changelog'
@@ -415,6 +418,9 @@ export {
415
418
  Test,
416
419
  Readme,
417
420
  ReadmeTop,
421
+ AgentGuideTop,
422
+ AgentGuide,
423
+ AgentGuideFeature,
418
424
  ReadmeInstall,
419
425
  ReadmeQuick,
420
426
  ReadmeErrors,