superbee 0.4.4-pre.14 → 0.4.4-pre.15

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 CHANGED
@@ -127,6 +127,51 @@ In a hosted checkout, `superbee view read <id>` prints a View page's version on
127
127
  `superbee view update <id> --expected-version <version>` replaces the page there (sync never sends
128
128
  `views/`). Uploading a page never approves its execution.
129
129
 
130
+ ## Copying documents between bundles
131
+
132
+ `superbee doc import` copies chosen documents from another bundle with new ids and rewritten links.
133
+ Declare the source first, then review the plan before applying it:
134
+
135
+ ```sh
136
+ superbee deps add wave --bundle-id <source-bundle-id> --path ../wave
137
+ superbee doc import --from wave --with wave=../wave --select type=Theme --prefix wave
138
+ superbee doc import --from wave --with wave=../wave --select type=Theme --prefix wave --apply <plan-token>
139
+ superbee doc import --from wave --with wave=../wave --refresh <record-id>
140
+ ```
141
+
142
+ The first import command only prints the plan and its token. Applying writes new documents and one
143
+ Promotion record, and never overwrites a document. `--resume <record-id>` finishes an interrupted
144
+ run. `--refresh <record-id>` updates the copies from their sources with the same plan and apply
145
+ steps; a copy edited since the import is a conflict until you name it with `--overwrite <id>` or
146
+ `--skip <id>`. The target must be a local bundle or Git board. `superbee doc import --help` has the
147
+ full reference.
148
+
149
+ ## When a document cannot be read
150
+
151
+ Superbee bounds how much frontmatter it parses: 262,144 characters of YAML, 32 levels of nesting, and limits on
152
+ YAML alias use. Ordinary documents are far below these limits. A write over a limit is refused with
153
+ `USAGE` and nothing is stored. A document already in the bundle that is over a limit, or whose YAML
154
+ is invalid, cannot be read:
155
+
156
+ - `doc read` on it fails with `RUNTIME`. `details.frontmatter.code` is `FRONTMATTER_TOO_LARGE`,
157
+ `FRONTMATTER_TOO_DEEP`, `FRONTMATTER_ALIAS_LIMIT`, `FRONTMATTER_CYCLE` or
158
+ `FRONTMATTER_MALFORMED`, and `details.frontmatter.document` names the file.
159
+ - To find every affected document, run `superbee status` (the `malformed` count and rows) or
160
+ `superbee list` (the `skipped` rows). `search`, `query`, `index generate`, `link list`,
161
+ `link show`, `view list` and `kinds --coverage` also skip it, say so, and keep working.
162
+ - To fix it, edit the lines between the `---` markers in a text editor, or remove the document with
163
+ `superbee doc delete <id>`. `doc update` and `doc field` cannot change a document they cannot read.
164
+
165
+ On a Git board, `sync` holds a changed file it cannot read: it exits 5, names the file, and commits
166
+ and pushes nothing until you fix it. If a conflict kept a version that cannot be read, the receipt
167
+ tells you to copy your saved export over the document.
168
+
169
+ In a hosted checkout, a host document this client cannot store comes back as a `held` row named with
170
+ its `FRONTMATTER_*` code, exit 5, and everything else proceeds. The next sync places it once it is
171
+ repaired on the host. If the checkout's own local store holds a copy it cannot read, sync stops with
172
+ `store_damaged` and sends and places nothing. Reads continue and `status` reports it. Copy out any
173
+ unsent edits and make a fresh checkout, as the error's help describes.
174
+
130
175
  ## Upgrading from aslite
131
176
 
132
177
  If you installed the earlier `@holaxis/aslite` package or its marketplace plugin: install
@@ -139,6 +184,8 @@ run `npm uninstall -g @holaxis/aslite`. Existing `.agentstate-lite/` bundles and
139
184
  The [repository](https://github.com/Holaxis-ai/superbee) holds the source, the
140
185
  [CLI contract](https://github.com/Holaxis-ai/superbee/blob/main/packages/superbee/AXI-CONTRACT.md),
141
186
  and the [wire protocol](https://github.com/Holaxis-ai/superbee/blob/main/docs/WIRE-PROTOCOL.md).
187
+ Site builders can read a publication's Site declaration through `superbee/publication/site-manifest`;
188
+ see [Site declarations](https://github.com/Holaxis-ai/superbee/blob/main/packages/publication/SITE-MANIFEST.md).
142
189
 
143
190
  ## License
144
191
 
package/SKILL.md CHANGED
@@ -74,7 +74,7 @@ files, and stop. Use `superbee <command> --help` for exact current syntax rather
74
74
  copied command manual. Use `--body-file` for multiline Markdown. `list` / `query` filter metadata, not body text; `doc update` / `doc field` patch metadata while preserving omitted fields and body. For body edits, read the complete body with `doc read <id> --body-out <temp-file>` outside the bundle, edit that temporary file, then `doc update <id> --body-file <temp-file> --expected-version <head_version> --actor <actor>` using the version from the read. Re-read and reconcile on a version conflict. Never feed a truncated preview or a full-document `--out` export to `--body-file`: body input is Markdown only; tooling owns YAML frontmatter. With MCP, use available tools and version preconditions; check tool schemas rather than inventing search or patch verbs.
75
75
 
76
76
  Focused shipped material is available under `$REFS/recipes/` for portable examples,
77
- `$REFS/views/` for View authoring and examples, and `$REFS/sample-bundle/` for OKF interop. Integration authoring and explicit local source bind/run use `$REFS/author-an-integration.md`; recorded `$REFS/integrations/` examples need no credentials.
77
+ `$REFS/views/` for View authoring and examples, and `$REFS/sample-bundle/` for OKF interop. Integration authoring and explicit local source bind/run use `$REFS/author-an-integration.md`; recorded `$REFS/integrations/` examples need no credentials. `RUNTIME` with `details.frontmatter.code` means a document cannot be read: see "When a document cannot be read" in `$REFS/modeling-and-delivery.md`, which also covers `superbee doc import`.
78
78
  Read only what the accepted work requires.
79
79
 
80
80
  ## Make the value visible
@@ -3175,8 +3175,18 @@ function parseFrontmatter(source, context, options = {}) {
3175
3175
  }
3176
3176
  return normalizeFrontmatter(parsed, options);
3177
3177
  }
3178
+ function isStackExhaustion(error) {
3179
+ if (error instanceof RangeError) return /call stack/i.test(error.message);
3180
+ return error?.name === "InternalError" && /recursion/i.test(error.message);
3181
+ }
3178
3182
  function stringifyFrontmatter(data) {
3179
- const dumped = import_js_yaml2.default.safeDump(data).trim();
3183
+ let dumped;
3184
+ try {
3185
+ dumped = import_js_yaml2.default.safeDump(data).trim();
3186
+ } catch (error) {
3187
+ if (isStackExhaustion(error)) throw new FrontmatterRefusedError("FRONTMATTER_TOO_DEEP", `YAML nesting is deeper than ${FRONTMATTER_LIMITS.depth} levels`);
3188
+ throw error;
3189
+ }
3180
3190
  try {
3181
3191
  yamlEngine.parse(`${dumped}
3182
3192
  `);
@@ -3998,24 +4008,7 @@ function hasSourceIdentity(sources, identity) {
3998
4008
  return Array.isArray(sources) && sources.some((entry) => matchesSourceIdentity(entry, identity));
3999
4009
  }
4000
4010
 
4001
- // ../core/src/engine.ts
4002
- async function readBundleOkfVersion(backend) {
4003
- const index = await backend.readReserved("", "index.md");
4004
- if (!index) return void 0;
4005
- const value = parseLeadingFrontmatter(index.content, "index.md").okf_version;
4006
- return typeof value === "string" && value.trim() !== "" ? value : void 0;
4007
- }
4008
- function assertReadableConceptId(id) {
4009
- assertSafeConceptId(id);
4010
- const rel = pathFromConceptId(id);
4011
- if (isReservedFile(rel)) {
4012
- throw new InvalidInputError(`'${id}' is a reserved file (index.md / log.md), not a concept document.`);
4013
- }
4014
- }
4015
- async function readDocVersioned(backend, id) {
4016
- assertReadableConceptId(id);
4017
- return backend.read(id);
4018
- }
4011
+ // ../core/src/document-scan.ts
4019
4012
  function isEnoent(err) {
4020
4013
  return typeof err === "object" && err !== null && err.code === "ENOENT";
4021
4014
  }
@@ -4046,6 +4039,25 @@ async function readManyExisting(backend, ids, onMalformed, onAliased) {
4046
4039
  return out;
4047
4040
  }
4048
4041
  }
4042
+
4043
+ // ../core/src/engine.ts
4044
+ async function readBundleOkfVersion(backend) {
4045
+ const index = await backend.readReserved("", "index.md");
4046
+ if (!index) return void 0;
4047
+ const value = parseLeadingFrontmatter(index.content, "index.md").okf_version;
4048
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
4049
+ }
4050
+ function assertReadableConceptId(id) {
4051
+ assertSafeConceptId(id);
4052
+ const rel = pathFromConceptId(id);
4053
+ if (isReservedFile(rel)) {
4054
+ throw new InvalidInputError(`'${id}' is a reserved file (index.md / log.md), not a concept document.`);
4055
+ }
4056
+ }
4057
+ async function readDocVersioned(backend, id) {
4058
+ assertReadableConceptId(id);
4059
+ return backend.read(id);
4060
+ }
4049
4061
  async function scanMatching(backend, filter, onSkip) {
4050
4062
  const ids = await backend.list(filter.prefix);
4051
4063
  const results = [];
@@ -31129,8 +31129,18 @@ function parseFrontmatter(source, context, options = {}) {
31129
31129
  }
31130
31130
  return normalizeFrontmatter(parsed, options);
31131
31131
  }
31132
+ function isStackExhaustion(error) {
31133
+ if (error instanceof RangeError) return /call stack/i.test(error.message);
31134
+ return error?.name === "InternalError" && /recursion/i.test(error.message);
31135
+ }
31132
31136
  function stringifyFrontmatter(data) {
31133
- const dumped = import_js_yaml2.default.safeDump(data).trim();
31137
+ let dumped;
31138
+ try {
31139
+ dumped = import_js_yaml2.default.safeDump(data).trim();
31140
+ } catch (error) {
31141
+ if (isStackExhaustion(error)) throw new FrontmatterRefusedError("FRONTMATTER_TOO_DEEP", `YAML nesting is deeper than ${FRONTMATTER_LIMITS.depth} levels`);
31142
+ throw error;
31143
+ }
31134
31144
  try {
31135
31145
  yamlEngine.parse(`${dumped}
31136
31146
  `);
@@ -31959,24 +31969,7 @@ function hasSourceIdentity(sources, identity) {
31959
31969
  return Array.isArray(sources) && sources.some((entry) => matchesSourceIdentity(entry, identity));
31960
31970
  }
31961
31971
 
31962
- // ../core/src/engine.ts
31963
- async function readBundleOkfVersion(backend) {
31964
- const index2 = await backend.readReserved("", "index.md");
31965
- if (!index2) return void 0;
31966
- const value = parseLeadingFrontmatter(index2.content, "index.md").okf_version;
31967
- return typeof value === "string" && value.trim() !== "" ? value : void 0;
31968
- }
31969
- function assertReadableConceptId(id) {
31970
- assertSafeConceptId(id);
31971
- const rel = pathFromConceptId(id);
31972
- if (isReservedFile(rel)) {
31973
- throw new InvalidInputError(`'${id}' is a reserved file (index.md / log.md), not a concept document.`);
31974
- }
31975
- }
31976
- async function readDocVersioned(backend, id) {
31977
- assertReadableConceptId(id);
31978
- return backend.read(id);
31979
- }
31972
+ // ../core/src/document-scan.ts
31980
31973
  function isEnoent(err) {
31981
31974
  return typeof err === "object" && err !== null && err.code === "ENOENT";
31982
31975
  }
@@ -32007,6 +32000,25 @@ async function readManyExisting(backend, ids, onMalformed, onAliased) {
32007
32000
  return out;
32008
32001
  }
32009
32002
  }
32003
+
32004
+ // ../core/src/engine.ts
32005
+ async function readBundleOkfVersion(backend) {
32006
+ const index2 = await backend.readReserved("", "index.md");
32007
+ if (!index2) return void 0;
32008
+ const value = parseLeadingFrontmatter(index2.content, "index.md").okf_version;
32009
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
32010
+ }
32011
+ function assertReadableConceptId(id) {
32012
+ assertSafeConceptId(id);
32013
+ const rel = pathFromConceptId(id);
32014
+ if (isReservedFile(rel)) {
32015
+ throw new InvalidInputError(`'${id}' is a reserved file (index.md / log.md), not a concept document.`);
32016
+ }
32017
+ }
32018
+ async function readDocVersioned(backend, id) {
32019
+ assertReadableConceptId(id);
32020
+ return backend.read(id);
32021
+ }
32010
32022
  async function scanMatching(backend, filter, onSkip) {
32011
32023
  const ids = await backend.list(filter.prefix);
32012
32024
  const results = [];