@ryanyahya/opendoc-headless 0.4.0
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/.agents/skills/opendoc-apply-comments/SKILL.md +30 -0
- package/.agents/skills/opendoc-apply-comments/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-create/SKILL.md +63 -0
- package/.agents/skills/opendoc-create/agents/openai.yaml +6 -0
- package/.agents/skills/opendoc-create-template/SKILL.md +50 -0
- package/.agents/skills/opendoc-create-template/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-create-template/references/structured-reports.md +11 -0
- package/.agents/skills/opendoc-create-theme/SKILL.md +40 -0
- package/.agents/skills/opendoc-create-theme/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-current-document/SKILL.md +32 -0
- package/.agents/skills/opendoc-current-document/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-current-document/references/context-fields.md +20 -0
- package/.agents/skills/opendoc-review-document/SKILL.md +60 -0
- package/.agents/skills/opendoc-review-document/agents/openai.yaml +4 -0
- package/AGENTS.md +69 -0
- package/CONTRIBUTING.md +38 -0
- package/LICENSE +21 -0
- package/README.md +179 -0
- package/SECURITY.md +9 -0
- package/THIRD_PARTY.md +49 -0
- package/VALIDATION.md +99 -0
- package/bin/opendoc.mjs +6 -0
- package/docs/APPEARANCE.md +21 -0
- package/docs/ASSETS.md +176 -0
- package/docs/AUTHORING.md +178 -0
- package/docs/HEADLESS.md +120 -0
- package/docs/MEDIA.md +112 -0
- package/docs/PROJECTS.md +55 -0
- package/docs/PROSE.md +15 -0
- package/docs/SELECTION.md +59 -0
- package/docs/TEMPLATES.md +55 -0
- package/docs/THEMES.md +106 -0
- package/node_modules/@formepdf/core/LICENSE +21 -0
- package/node_modules/@formepdf/core/README.md +53 -0
- package/node_modules/@formepdf/core/dist/attachments.d.ts +55 -0
- package/node_modules/@formepdf/core/dist/attachments.js +59 -0
- package/node_modules/@formepdf/core/dist/extract.d.ts +8 -0
- package/node_modules/@formepdf/core/dist/extract.js +56 -0
- package/node_modules/@formepdf/core/dist/index.d.ts +311 -0
- package/node_modules/@formepdf/core/dist/index.js +167 -0
- package/node_modules/@formepdf/core/dist/layout.d.ts +132 -0
- package/node_modules/@formepdf/core/dist/layout.js +240 -0
- package/node_modules/@formepdf/core/dist/shared/browserHelpers.d.ts +19 -0
- package/node_modules/@formepdf/core/dist/shared/browserHelpers.js +128 -0
- package/node_modules/@formepdf/core/package.json +35 -0
- package/node_modules/@formepdf/core/pkg-node/LICENSE +21 -0
- package/node_modules/@formepdf/core/pkg-node/README.md +84 -0
- package/node_modules/@formepdf/core/pkg-node/forme.d.ts +39 -0
- package/node_modules/@formepdf/core/pkg-node/forme.js +394 -0
- package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm +0 -0
- package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm.d.ts +21 -0
- package/node_modules/@formepdf/core/pkg-node/package.json +25 -0
- package/node_modules/@formepdf/react/README.md +70 -0
- package/node_modules/@formepdf/react/dist/charts.d.ts +72 -0
- package/node_modules/@formepdf/react/dist/charts.js +338 -0
- package/node_modules/@formepdf/react/dist/components.d.ts +533 -0
- package/node_modules/@formepdf/react/dist/components.js +608 -0
- package/node_modules/@formepdf/react/dist/expr.d.ts +20 -0
- package/node_modules/@formepdf/react/dist/expr.js +39 -0
- package/node_modules/@formepdf/react/dist/font.d.ts +2 -0
- package/node_modules/@formepdf/react/dist/font.js +1 -0
- package/node_modules/@formepdf/react/dist/index.d.ts +11 -0
- package/node_modules/@formepdf/react/dist/index.js +15 -0
- package/node_modules/@formepdf/react/dist/render.d.ts +12 -0
- package/node_modules/@formepdf/react/dist/render.js +15 -0
- package/node_modules/@formepdf/react/dist/serialize.d.ts +12 -0
- package/node_modules/@formepdf/react/dist/serialize.js +1470 -0
- package/node_modules/@formepdf/react/dist/stylesheet.d.ts +4 -0
- package/node_modules/@formepdf/react/dist/stylesheet.js +5 -0
- package/node_modules/@formepdf/react/dist/template-proxy.d.ts +38 -0
- package/node_modules/@formepdf/react/dist/template-proxy.js +100 -0
- package/node_modules/@formepdf/react/dist/types.d.ts +287 -0
- package/node_modules/@formepdf/react/dist/types.js +1 -0
- package/node_modules/@formepdf/react/package.json +41 -0
- package/node_modules/@formepdf/shared/README.md +7 -0
- package/node_modules/@formepdf/shared/dist/canvas.d.ts +6 -0
- package/node_modules/@formepdf/shared/dist/canvas.js +43 -0
- package/node_modules/@formepdf/shared/dist/charts.d.ts +100 -0
- package/node_modules/@formepdf/shared/dist/charts.js +98 -0
- package/node_modules/@formepdf/shared/dist/encode.d.ts +27 -0
- package/node_modules/@formepdf/shared/dist/encode.js +93 -0
- package/node_modules/@formepdf/shared/dist/font.d.ts +13 -0
- package/node_modules/@formepdf/shared/dist/font.js +52 -0
- package/node_modules/@formepdf/shared/dist/index.d.ts +10 -0
- package/node_modules/@formepdf/shared/dist/index.js +15 -0
- package/node_modules/@formepdf/shared/dist/parser.d.ts +30 -0
- package/node_modules/@formepdf/shared/dist/parser.js +756 -0
- package/node_modules/@formepdf/shared/dist/semantics.d.ts +15 -0
- package/node_modules/@formepdf/shared/dist/semantics.js +44 -0
- package/node_modules/@formepdf/shared/dist/style.d.ts +7 -0
- package/node_modules/@formepdf/shared/dist/style.js +1024 -0
- package/node_modules/@formepdf/shared/dist/types.d.ts +743 -0
- package/node_modules/@formepdf/shared/dist/types.js +2 -0
- package/node_modules/@formepdf/shared/package.json +35 -0
- package/node_modules/@types/node/LICENSE +21 -0
- package/node_modules/@types/node/README.md +15 -0
- package/node_modules/@types/node/assert/strict.d.ts +111 -0
- package/node_modules/@types/node/assert.d.ts +1078 -0
- package/node_modules/@types/node/async_hooks.d.ts +603 -0
- package/node_modules/@types/node/buffer.buffer.d.ts +472 -0
- package/node_modules/@types/node/buffer.d.ts +1934 -0
- package/node_modules/@types/node/child_process.d.ts +1476 -0
- package/node_modules/@types/node/cluster.d.ts +578 -0
- package/node_modules/@types/node/compatibility/disposable.d.ts +14 -0
- package/node_modules/@types/node/compatibility/index.d.ts +9 -0
- package/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
- package/node_modules/@types/node/compatibility/iterators.d.ts +20 -0
- package/node_modules/@types/node/console.d.ts +452 -0
- package/node_modules/@types/node/constants.d.ts +21 -0
- package/node_modules/@types/node/crypto.d.ts +4545 -0
- package/node_modules/@types/node/dgram.d.ts +600 -0
- package/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
- package/node_modules/@types/node/dns/promises.d.ts +503 -0
- package/node_modules/@types/node/dns.d.ts +923 -0
- package/node_modules/@types/node/domain.d.ts +170 -0
- package/node_modules/@types/node/events.d.ts +976 -0
- package/node_modules/@types/node/fs/promises.d.ts +1306 -0
- package/node_modules/@types/node/fs.d.ts +4463 -0
- package/node_modules/@types/node/globals.d.ts +172 -0
- package/node_modules/@types/node/globals.typedarray.d.ts +38 -0
- package/node_modules/@types/node/http.d.ts +2097 -0
- package/node_modules/@types/node/http2.d.ts +2843 -0
- package/node_modules/@types/node/https.d.ts +579 -0
- package/node_modules/@types/node/index.d.ts +98 -0
- package/node_modules/@types/node/inspector.d.ts +253 -0
- package/node_modules/@types/node/inspector.generated.d.ts +4052 -0
- package/node_modules/@types/node/module.d.ts +891 -0
- package/node_modules/@types/node/net.d.ts +1076 -0
- package/node_modules/@types/node/os.d.ts +506 -0
- package/node_modules/@types/node/package.json +145 -0
- package/node_modules/@types/node/path.d.ts +200 -0
- package/node_modules/@types/node/perf_hooks.d.ts +968 -0
- package/node_modules/@types/node/process.d.ts +2084 -0
- package/node_modules/@types/node/punycode.d.ts +117 -0
- package/node_modules/@types/node/querystring.d.ts +152 -0
- package/node_modules/@types/node/readline/promises.d.ts +161 -0
- package/node_modules/@types/node/readline.d.ts +594 -0
- package/node_modules/@types/node/repl.d.ts +428 -0
- package/node_modules/@types/node/sea.d.ts +162 -0
- package/node_modules/@types/node/sqlite.d.ts +722 -0
- package/node_modules/@types/node/stream/consumers.d.ts +38 -0
- package/node_modules/@types/node/stream/promises.d.ts +90 -0
- package/node_modules/@types/node/stream/web.d.ts +573 -0
- package/node_modules/@types/node/stream.d.ts +1694 -0
- package/node_modules/@types/node/string_decoder.d.ts +67 -0
- package/node_modules/@types/node/test.d.ts +2265 -0
- package/node_modules/@types/node/timers/promises.d.ts +108 -0
- package/node_modules/@types/node/timers.d.ts +287 -0
- package/node_modules/@types/node/tls.d.ts +1319 -0
- package/node_modules/@types/node/trace_events.d.ts +197 -0
- package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
- package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
- package/node_modules/@types/node/ts5.6/index.d.ts +98 -0
- package/node_modules/@types/node/tty.d.ts +208 -0
- package/node_modules/@types/node/url.d.ts +984 -0
- package/node_modules/@types/node/util.d.ts +2606 -0
- package/node_modules/@types/node/v8.d.ts +920 -0
- package/node_modules/@types/node/vm.d.ts +1053 -0
- package/node_modules/@types/node/wasi.d.ts +181 -0
- package/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
- package/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
- package/node_modules/@types/node/web-globals/events.d.ts +97 -0
- package/node_modules/@types/node/web-globals/fetch.d.ts +55 -0
- package/node_modules/@types/node/web-globals/navigator.d.ts +22 -0
- package/node_modules/@types/node/web-globals/storage.d.ts +24 -0
- package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
- package/node_modules/@types/node/worker_threads.d.ts +819 -0
- package/node_modules/@types/node/zlib.d.ts +747 -0
- package/node_modules/@types/react/LICENSE +21 -0
- package/node_modules/@types/react/README.md +15 -0
- package/node_modules/@types/react/canary.d.ts +129 -0
- package/node_modules/@types/react/compiler-runtime.d.ts +4 -0
- package/node_modules/@types/react/experimental.d.ts +184 -0
- package/node_modules/@types/react/global.d.ts +166 -0
- package/node_modules/@types/react/index.d.ts +4378 -0
- package/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
- package/node_modules/@types/react/jsx-runtime.d.ts +24 -0
- package/node_modules/@types/react/package.json +210 -0
- package/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
- package/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
- package/node_modules/@types/react/ts5.0/global.d.ts +166 -0
- package/node_modules/@types/react/ts5.0/index.d.ts +4365 -0
- package/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
- package/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
- package/node_modules/csstype/LICENSE +19 -0
- package/node_modules/csstype/README.md +291 -0
- package/node_modules/csstype/index.d.ts +22569 -0
- package/node_modules/csstype/index.js.flow +6863 -0
- package/node_modules/csstype/package.json +70 -0
- package/node_modules/entities/LICENSE +11 -0
- package/node_modules/entities/decode.d.ts +1 -0
- package/node_modules/entities/decode.js +3 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts +209 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.js +511 -0
- package/node_modules/entities/dist/commonjs/decode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts +22 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.js +73 -0
- package/node_modules/entities/dist/commonjs/encode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts +43 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.js +121 -0
- package/node_modules/entities/dist/commonjs/escape.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js +13 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/index.d.ts +96 -0
- package/node_modules/entities/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/index.js +131 -0
- package/node_modules/entities/dist/commonjs/index.js.map +1 -0
- package/node_modules/entities/dist/commonjs/package.json +3 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js +72 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/esm/decode.d.ts +209 -0
- package/node_modules/entities/dist/esm/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode.js +497 -0
- package/node_modules/entities/dist/esm/decode.js.map +1 -0
- package/node_modules/entities/dist/esm/encode.d.ts +22 -0
- package/node_modules/entities/dist/esm/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/encode.js +69 -0
- package/node_modules/entities/dist/esm/encode.js.map +1 -0
- package/node_modules/entities/dist/esm/escape.d.ts +43 -0
- package/node_modules/entities/dist/esm/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/escape.js +117 -0
- package/node_modules/entities/dist/esm/escape.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js +10 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/esm/index.d.ts +96 -0
- package/node_modules/entities/dist/esm/index.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/index.js +107 -0
- package/node_modules/entities/dist/esm/index.js.map +1 -0
- package/node_modules/entities/dist/esm/package.json +3 -0
- package/node_modules/entities/escape.d.ts +1 -0
- package/node_modules/entities/escape.js +3 -0
- package/node_modules/entities/package.json +118 -0
- package/node_modules/entities/readme.md +122 -0
- package/node_modules/entities/src/decode-codepoint.ts +81 -0
- package/node_modules/entities/src/decode.spec.ts +320 -0
- package/node_modules/entities/src/decode.ts +620 -0
- package/node_modules/entities/src/encode.spec.ts +78 -0
- package/node_modules/entities/src/encode.ts +77 -0
- package/node_modules/entities/src/escape.spec.ts +14 -0
- package/node_modules/entities/src/escape.ts +148 -0
- package/node_modules/entities/src/generated/.eslintrc.json +10 -0
- package/node_modules/entities/src/generated/decode-data-html.ts +8 -0
- package/node_modules/entities/src/generated/decode-data-xml.ts +8 -0
- package/node_modules/entities/src/generated/encode-html.ts +17 -0
- package/node_modules/entities/src/index.spec.ts +125 -0
- package/node_modules/entities/src/index.ts +188 -0
- package/node_modules/parse5/LICENSE +19 -0
- package/node_modules/parse5/README.md +38 -0
- package/node_modules/parse5/dist/cjs/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/cjs/common/doctype.js +118 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.js +66 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.js +237 -0
- package/node_modules/parse5/dist/cjs/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/cjs/common/html.js +528 -0
- package/node_modules/parse5/dist/cjs/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/common/token.js +24 -0
- package/node_modules/parse5/dist/cjs/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/cjs/common/unicode.js +70 -0
- package/node_modules/parse5/dist/cjs/index.d.ts +71 -0
- package/node_modules/parse5/dist/cjs/index.js +54 -0
- package/node_modules/parse5/dist/cjs/package.json +1 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.js +114 -0
- package/node_modules/parse5/dist/cjs/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/cjs/parser/index.js +3240 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.js +328 -0
- package/node_modules/parse5/dist/cjs/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/cjs/serializer/index.js +172 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.js +2714 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.js +200 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.js +176 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.js +2 -0
- package/node_modules/parse5/dist/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/common/doctype.js +114 -0
- package/node_modules/parse5/dist/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/common/error-codes.js +63 -0
- package/node_modules/parse5/dist/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/common/foreign-content.js +228 -0
- package/node_modules/parse5/dist/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/common/html.js +523 -0
- package/node_modules/parse5/dist/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/common/token.js +20 -0
- package/node_modules/parse5/dist/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/common/unicode.js +62 -0
- package/node_modules/parse5/dist/index.d.ts +71 -0
- package/node_modules/parse5/dist/index.js +42 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.js +110 -0
- package/node_modules/parse5/dist/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/parser/index.js +3245 -0
- package/node_modules/parse5/dist/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/parser/open-element-stack.js +324 -0
- package/node_modules/parse5/dist/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/serializer/index.js +168 -0
- package/node_modules/parse5/dist/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/tokenizer/index.js +2710 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.js +196 -0
- package/node_modules/parse5/dist/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/tree-adapters/default.js +173 -0
- package/node_modules/parse5/dist/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/tree-adapters/interface.js +1 -0
- package/node_modules/parse5/package.json +50 -0
- package/node_modules/undici-types/LICENSE +21 -0
- package/node_modules/undici-types/README.md +6 -0
- package/node_modules/undici-types/agent.d.ts +31 -0
- package/node_modules/undici-types/api.d.ts +43 -0
- package/node_modules/undici-types/balanced-pool.d.ts +29 -0
- package/node_modules/undici-types/cache.d.ts +36 -0
- package/node_modules/undici-types/client.d.ts +108 -0
- package/node_modules/undici-types/connector.d.ts +34 -0
- package/node_modules/undici-types/content-type.d.ts +21 -0
- package/node_modules/undici-types/cookies.d.ts +28 -0
- package/node_modules/undici-types/diagnostics-channel.d.ts +66 -0
- package/node_modules/undici-types/dispatcher.d.ts +256 -0
- package/node_modules/undici-types/env-http-proxy-agent.d.ts +21 -0
- package/node_modules/undici-types/errors.d.ts +149 -0
- package/node_modules/undici-types/eventsource.d.ts +61 -0
- package/node_modules/undici-types/fetch.d.ts +209 -0
- package/node_modules/undici-types/file.d.ts +39 -0
- package/node_modules/undici-types/filereader.d.ts +54 -0
- package/node_modules/undici-types/formdata.d.ts +108 -0
- package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
- package/node_modules/undici-types/global-origin.d.ts +7 -0
- package/node_modules/undici-types/handlers.d.ts +15 -0
- package/node_modules/undici-types/header.d.ts +4 -0
- package/node_modules/undici-types/index.d.ts +71 -0
- package/node_modules/undici-types/interceptors.d.ts +17 -0
- package/node_modules/undici-types/mock-agent.d.ts +50 -0
- package/node_modules/undici-types/mock-client.d.ts +25 -0
- package/node_modules/undici-types/mock-errors.d.ts +12 -0
- package/node_modules/undici-types/mock-interceptor.d.ts +93 -0
- package/node_modules/undici-types/mock-pool.d.ts +25 -0
- package/node_modules/undici-types/package.json +55 -0
- package/node_modules/undici-types/patch.d.ts +33 -0
- package/node_modules/undici-types/pool-stats.d.ts +19 -0
- package/node_modules/undici-types/pool.d.ts +39 -0
- package/node_modules/undici-types/proxy-agent.d.ts +28 -0
- package/node_modules/undici-types/readable.d.ts +65 -0
- package/node_modules/undici-types/retry-agent.d.ts +8 -0
- package/node_modules/undici-types/retry-handler.d.ts +116 -0
- package/node_modules/undici-types/util.d.ts +18 -0
- package/node_modules/undici-types/webidl.d.ts +228 -0
- package/node_modules/undici-types/websocket.d.ts +150 -0
- package/package.json +72 -0
- package/scripts/rebuild-forme.mjs +61 -0
- package/src/assets/adapter.ts +122 -0
- package/src/assets/files.ts +378 -0
- package/src/assets/import-worker.ts +294 -0
- package/src/assets/imports.ts +124 -0
- package/src/assets/index.ts +60 -0
- package/src/assets/store.ts +798 -0
- package/src/assets/usage.ts +118 -0
- package/src/cli/check.ts +25 -0
- package/src/cli/init.ts +119 -0
- package/src/cli/lock.ts +34 -0
- package/src/cli/main.ts +118 -0
- package/src/cli/process.ts +19 -0
- package/src/cli/start.ts +96 -0
- package/src/cli/update.ts +348 -0
- package/src/cli/workspace.ts +94 -0
- package/src/document/index.tsx +641 -0
- package/src/document/page.tsx +53 -0
- package/src/document/text-targets.tsx +162 -0
- package/src/media/files.ts +124 -0
- package/src/media/render.ts +63 -0
- package/src/rendering/resolve-sources.ts +84 -0
- package/src/runtime/jsx-dev-runtime.ts +2 -0
- package/src/runtime/jsx-runtime.ts +2 -0
- package/src/runtime/paths.ts +12 -0
- package/src/server/assets-cli.ts +162 -0
- package/src/server/assets-http.ts +100 -0
- package/src/server/client.ts +50 -0
- package/src/server/clipboard.ts +22 -0
- package/src/server/comments-cli.ts +64 -0
- package/src/server/comments.ts +130 -0
- package/src/server/create-cli.ts +33 -0
- package/src/server/create.ts +228 -0
- package/src/server/dependencies.ts +91 -0
- package/src/server/documents.ts +143 -0
- package/src/server/edits.ts +249 -0
- package/src/server/export-batch.ts +105 -0
- package/src/server/export-errors.ts +2 -0
- package/src/server/export-file.ts +57 -0
- package/src/server/export-inputs.ts +66 -0
- package/src/server/export-preview.ts +69 -0
- package/src/server/export.ts +32 -0
- package/src/server/exports.ts +283 -0
- package/src/server/files.ts +21 -0
- package/src/server/guides.ts +71 -0
- package/src/server/materials.ts +39 -0
- package/src/server/media-cli.ts +73 -0
- package/src/server/media-mutations.ts +168 -0
- package/src/server/pptx.ts +160 -0
- package/src/server/preflight.ts +129 -0
- package/src/server/projects-cli.ts +29 -0
- package/src/server/projects.ts +187 -0
- package/src/server/render-error.ts +9 -0
- package/src/server/render-source.ts +24 -0
- package/src/server/render.ts +48 -0
- package/src/server/review-cli.ts +40 -0
- package/src/server/review.ts +161 -0
- package/src/server/selection.ts +23 -0
- package/src/server/source-overrides.ts +97 -0
- package/src/server/templates-cli.ts +51 -0
- package/src/server/templates.ts +186 -0
- package/src/server/text-layout.ts +41 -0
- package/src/server/text-source.ts +307 -0
- package/src/server/themes-cli.ts +59 -0
- package/src/server/themes.ts +215 -0
- package/src/server/ttf2eot.d.ts +3 -0
- package/src/server/worker.ts +166 -0
- package/src/server/workspace.ts +242 -0
- package/src/shared/anchors.ts +69 -0
- package/src/shared/assets.ts +154 -0
- package/src/shared/export.ts +34 -0
- package/src/shared/media.ts +33 -0
- package/src/shared/projects.ts +19 -0
- package/src/shared/selection.ts +94 -0
- package/src/shared/skill-index.ts +14 -0
- package/src/shared/starters.ts +19 -0
- package/src/shared/templates.ts +18 -0
- package/src/shared/themes.ts +24 -0
- package/src/shared/types.ts +39 -0
- package/src/template/index.ts +27 -0
- package/src/themes/index.ts +3 -0
- package/src/themes/neutral.ts +20 -0
- package/src/themes/types.ts +110 -0
- package/starter/assets/brand/wordmark.png +0 -0
- package/starter/assets/fonts/InterUI-LICENSE.txt +93 -0
- package/starter/assets/fonts/InterUI-Medium.ttf +0 -0
- package/starter/assets/fonts/InterUI-Regular.ttf +0 -0
- package/starter/assets/fonts/InterUI-source.json +19 -0
- package/starter/assets/fonts/OpenDocMono-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Italic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Semibold.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-SemiboldItalic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Italic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Semibold.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-SemiboldItalic.ttf +0 -0
- package/starter/assets/fonts/SourceCode-LICENSE.md +93 -0
- package/starter/assets/fonts/SourceSans-LICENSE.md +93 -0
- package/starter/assets/fonts/SourceSerif-LICENSE.md +93 -0
- package/starter/assets/fonts/geist/OFL.txt +93 -0
- package/starter/assets/fonts/geist/asset.json +7 -0
- package/starter/assets/fonts/geist/files/1a9874b3be0fc168692a3d2327bccb4d28835653d3b91537a755296a467a83e3.ttf +0 -0
- package/starter/assets/fonts/geist/files/a8eefb873ba9c9020665f8a98302697ce1f3b79ab2deef6ee508c0ca6a82e876.ttf +0 -0
- package/starter/assets/fonts/geist/files/ccce59465ae5c61930ada5453834f60500fbd95084d85db63e0e65fad0125455.ttf +0 -0
- package/starter/assets/fonts/geist/files/f5e95110d70593672515080bee9148463ada0a7f77b89ed65a3d43cb2b0ff83a.pdf +0 -0
- package/starter/assets/fonts/geist/revisions/9a2bc12fb2f23cb27bc227087e63e1407bb804ee0586480bd6b7966ec69fb474.json +60 -0
- package/starter/assets/fonts/inter/OFL.txt +93 -0
- package/starter/assets/fonts/inter/asset.json +7 -0
- package/starter/assets/fonts/inter/files/1b08e7fc267a5c7e1d614100f604b83e7e8a0be241f0f288faa2b3ac93a683ba.ttf +0 -0
- package/starter/assets/fonts/inter/files/5b6f0c6f26e5c554a64cdcc3a9b5d802b7f9aec6206f1dbcfcdcad7b5860a2a9.ttf +0 -0
- package/starter/assets/fonts/inter/files/957db8560d510a198a7d0333fae7b6b444b00c20801581126273978d778eb3c3.pdf +0 -0
- package/starter/assets/fonts/inter/files/b37284b5701b6b168dfc770aa1a4ac492106422fd3ba76bc7641e37434e8019c.ttf +0 -0
- package/starter/assets/fonts/inter/files/c1811d32ac0f6eed1bbf57529f2ecdfc6c717d48a969dd864942436315a1b198.ttf +0 -0
- package/starter/assets/fonts/inter/files/e7a1aaf7eda9f2fad4131725fa556265ec75ca7b2d756260173a040363e8d4f7.ttf +0 -0
- package/starter/assets/fonts/inter/files/ef8f755d933b9310804cc9152f1f18cb2ac460d6b05054ec913d889c9f11f79e.ttf +0 -0
- package/starter/assets/fonts/inter/revisions/600391517c413963b71e278a57c26c40366c81fa3939a6b9755f446206766d12.json +99 -0
- package/starter/assets/fonts/inter/source.json +57 -0
- package/starter/assets/fonts/lato/OFL.txt +93 -0
- package/starter/assets/fonts/lato/asset.json +7 -0
- package/starter/assets/fonts/lato/files/4a6b566dbb28adb473a8789ce5169306f42f0c8a070ac92bae93636f36348b0d.pdf +0 -0
- package/starter/assets/fonts/lato/files/5adeb6b334d8fb99ef053bc052b952773d544315e0e1d668a12c0ce8bd51375c.ttf +0 -0
- package/starter/assets/fonts/lato/files/62c1b7f0d2e74b45960154c3520efc337b553db0961bfdc950d5618334596cc8.ttf +0 -0
- package/starter/assets/fonts/lato/files/71b8b7decbe75a881ed267be539d402bd1e9420b799658aada4e0d1bd5af803c.ttf +0 -0
- package/starter/assets/fonts/lato/files/8a0aace75d33794eece4b28187bfc1df0bbd2888b5d8a56e01788c8d65d16be1.ttf +0 -0
- package/starter/assets/fonts/lato/files/d636e4683231f931eda222d588e944d082bfd3bdba02f928bee461c0f185b251.ttf +0 -0
- package/starter/assets/fonts/lato/files/e399c44efe1387100531d26c7e4800c5d12251b890d6654a3098c7c679cb1786.ttf +0 -0
- package/starter/assets/fonts/lato/revisions/49ccb93400a9d466fab7d9843b1ecf8916ec6d47a475dd79a597a22eb39616bc.json +99 -0
- package/starter/assets/fonts/lato/source.json +57 -0
- package/starter/assets/fonts/merriweather/OFL.txt +93 -0
- package/starter/assets/fonts/merriweather/asset.json +7 -0
- package/starter/assets/fonts/merriweather/files/1c54f91b910454251c4c2b7bd4e472e1abf265fba7ca3c0ef2eee2f41324099e.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/8bde8da2bb7f0265e27ba0481f70bb48d0f98a976c145f2f239c648ddd6532e0.pdf +0 -0
- package/starter/assets/fonts/merriweather/files/90b7db4460fcd1a5ca49575c2668a793f3cd6447664d312a068d690e1c01e6bc.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/afff81272b7653417bb6f8bef57add055b1f9fda36f27eba5f32b40752bd08da.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/e029d3b71e5bae3877c73f4f2b15af28db16593d49b0aed2a328d37ff7075846.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/e9864a6790bf712a04e20f3662b206a1535186ed3e877fd859dd5fb9682335df.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/fa71baebdd20a7d0de2e5e445a5922530fe9e1d740efbe791f113b682d3cb093.ttf +0 -0
- package/starter/assets/fonts/merriweather/revisions/1888e390b3e4f38a3d7cd2dc1bb805aeb6ce13f986a97656f0265fd436bc91d2.json +99 -0
- package/starter/assets/fonts/merriweather/source.json +57 -0
- package/starter/assets/fonts/open-sans/OFL.txt +92 -0
- package/starter/assets/fonts/open-sans/asset.json +7 -0
- package/starter/assets/fonts/open-sans/files/1bc0594a83762b2c25d38915a34464b7fec6088298ca22d151757bf98d6700ec.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/47ed1cfaa7ffca04a04ab850b2938fd52c09d1b44cfa3e2980878e166b0cbd87.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/574939af301f07df8e21cfff279465c5981dd9d9cf62086f7515897df951c6f5.pdf +0 -0
- package/starter/assets/fonts/open-sans/files/6d3884d0d57c1b67e9c50c54eca7b69c535c114e76bd7a9cfda0258588185553.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/733eb93b167e6d45de09aa768f6c0355647c2c26f5416dbc7407a08ed41e81c6.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/75367e6da7d914eaed87883ba51b2a2b5816b5cdbb39f96ec5c81a5b032bfd5a.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/ff4fdc11204e0edd14e9a0bb6c374b847a9093b0ec2c16702e03afca79ac4ef7.ttf +0 -0
- package/starter/assets/fonts/open-sans/revisions/bbbe3a4915b9bccbc883c0decb4097511c43b6bd09ae22a1516aff128c219bc5.json +99 -0
- package/starter/assets/fonts/open-sans/source.json +57 -0
- package/starter/assets/fonts/roboto/OFL.txt +93 -0
- package/starter/assets/fonts/roboto/asset.json +7 -0
- package/starter/assets/fonts/roboto/files/22d45d989248a624252b8382067ac56550212fa675dcdbaf12f03d297dd87a58.pdf +0 -0
- package/starter/assets/fonts/roboto/files/35757eaa996b3359022f47f164a67ee9eac04971af24c5b8fbd4b89e844ff190.ttf +0 -0
- package/starter/assets/fonts/roboto/files/4d3035883c531846bd1ce2dc89f36d932e72dc114f56062c7e3a9cdd74f3d3ea.ttf +0 -0
- package/starter/assets/fonts/roboto/files/be7639306a4fc4a02ce2ae2ff59eb1335e4db4a7379dd0a384ed7cc053817789.ttf +0 -0
- package/starter/assets/fonts/roboto/files/d2920cbb1b60a3fd11fbf22049286e43a6baf522d37fdf1e7c89562319bcfea5.ttf +0 -0
- package/starter/assets/fonts/roboto/files/dece7c71bbe61710787f0839c722c65e87355dd2eb4a823e6b5488121ff81e4b.ttf +0 -0
- package/starter/assets/fonts/roboto/files/f478ba88b0292e685e487901dfbb1401457d32d6ebee4030cdfd5698235bffa8.ttf +0 -0
- package/starter/assets/fonts/roboto/revisions/bda5e2d84c17313373dd2dbf3e64fe0dd450c7e1b59e6929e69557e122fe976e.json +99 -0
- package/starter/assets/fonts/roboto/source.json +57 -0
- package/starter/assets/logos/opendoc/asset.json +6 -0
- package/starter/assets/logos/opendoc/files/831d5ccd9eb6709cc8439ea257c03d81452e81a28a3d1eedbd6a3b7daff687b6.png +0 -0
- package/starter/assets/logos/opendoc/revisions/834dde8926ddb81de687254195a168bb13bfb77803307f1257de1f2228be63b2.json +33 -0
- package/starter/assets/ui-fonts/geist/OFL.txt +93 -0
- package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-italic.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-normal.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-wght-italic.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-wght-normal.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/source.json +26 -0
- package/starter/documents/welcome/assets.json +7 -0
- package/starter/documents/welcome/index.tsx +160 -0
- package/starter/documents/welcome/media/.gitkeep +0 -0
- package/starter/documents/welcome/media/paper-architecture/image.png +0 -0
- package/starter/documents/welcome/media/paper-architecture/meta.json +9 -0
- package/starter/documents/welcome/media/paper-architecture/prompt.txt +1 -0
- package/starter/documents/welcome/media/studio-rhythm/chart.svg +2343 -0
- package/starter/documents/welcome/media/studio-rhythm/data.json +234 -0
- package/starter/documents/welcome/media/studio-rhythm/generation.json +9 -0
- package/starter/documents/welcome/media/studio-rhythm/image.png +0 -0
- package/starter/documents/welcome/media/studio-rhythm/meta.json +11 -0
- package/starter/documents/welcome/media/studio-rhythm/recipe.py +79 -0
- package/starter/documents/welcome/theme.tsx +5 -0
- package/starter/documents/welcome-presentation/assets.json +7 -0
- package/starter/documents/welcome-presentation/index.tsx +166 -0
- package/starter/documents/welcome-presentation/media/.gitkeep +0 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/image.png +0 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/meta.json +9 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/prompt.txt +1 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/chart.svg +1336 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/data.json +234 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/generation.json +9 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/image.png +0 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/meta.json +13 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/recipe.py +49 -0
- package/starter/documents/welcome-presentation/theme.tsx +5 -0
- package/starter/projects.json +17 -0
- package/starter/templates/AGENTS.md +9 -0
- package/starter/templates/_shared/BusinessLogo.tsx +14 -0
- package/starter/templates/_shared/Pricing.tsx +40 -0
- package/starter/templates/_shared/commerce.ts +93 -0
- package/starter/templates/brand-guidelines/AGENTS.md +32 -0
- package/starter/templates/brand-guidelines/index.tsx +62 -0
- package/starter/templates/brand-guidelines/preview.tsx +181 -0
- package/starter/templates/brand-guidelines/starter.tsx +179 -0
- package/starter/templates/brand-guidelines/template.json +15 -0
- package/starter/templates/business-proposal/AGENTS.md +13 -0
- package/starter/templates/business-proposal/README.md +36 -0
- package/starter/templates/business-proposal/data.json +37 -0
- package/starter/templates/business-proposal/examples/long.json +142 -0
- package/starter/templates/business-proposal/examples/sparse.json +17 -0
- package/starter/templates/business-proposal/examples/typical.json +37 -0
- package/starter/templates/business-proposal/index.tsx +59 -0
- package/starter/templates/business-proposal/preview.tsx +47 -0
- package/starter/templates/business-proposal/schema.ts +14 -0
- package/starter/templates/business-proposal/starter.tsx +18 -0
- package/starter/templates/business-proposal/template.json +11 -0
- package/starter/templates/company-profile/AGENTS.md +48 -0
- package/starter/templates/company-profile/index.tsx +69 -0
- package/starter/templates/company-profile/preview.tsx +185 -0
- package/starter/templates/company-profile/starter.tsx +186 -0
- package/starter/templates/company-profile/template.json +15 -0
- package/starter/templates/consulting-report/AGENTS.md +11 -0
- package/starter/templates/consulting-report/README.md +13 -0
- package/starter/templates/consulting-report/RESEARCH.md +10 -0
- package/starter/templates/consulting-report/index.tsx +44 -0
- package/starter/templates/consulting-report/preview.tsx +39 -0
- package/starter/templates/consulting-report/starter.tsx +15 -0
- package/starter/templates/consulting-report/template.json +11 -0
- package/starter/templates/editorial-essay/AGENTS.md +11 -0
- package/starter/templates/editorial-essay/README.md +11 -0
- package/starter/templates/editorial-essay/index.tsx +30 -0
- package/starter/templates/editorial-essay/preview.tsx +26 -0
- package/starter/templates/editorial-essay/starter.tsx +15 -0
- package/starter/templates/editorial-essay/template.json +11 -0
- package/starter/templates/executive-brief/AGENTS.md +9 -0
- package/starter/templates/executive-brief/README.md +11 -0
- package/starter/templates/executive-brief/index.tsx +33 -0
- package/starter/templates/executive-brief/preview.tsx +37 -0
- package/starter/templates/executive-brief/starter.tsx +11 -0
- package/starter/templates/executive-brief/template.json +11 -0
- package/starter/templates/image-story/AGENTS.md +37 -0
- package/starter/templates/image-story/index.tsx +106 -0
- package/starter/templates/image-story/preview.tsx +33 -0
- package/starter/templates/image-story/starter.tsx +24 -0
- package/starter/templates/image-story/template.json +13 -0
- package/starter/templates/invoice/AGENTS.md +13 -0
- package/starter/templates/invoice/README.md +40 -0
- package/starter/templates/invoice/data.json +61 -0
- package/starter/templates/invoice/examples/long.json +241 -0
- package/starter/templates/invoice/examples/sparse.json +33 -0
- package/starter/templates/invoice/examples/typical.json +61 -0
- package/starter/templates/invoice/index.tsx +57 -0
- package/starter/templates/invoice/preview.tsx +12 -0
- package/starter/templates/invoice/schema.ts +45 -0
- package/starter/templates/invoice/starter.tsx +12 -0
- package/starter/templates/invoice/template.json +11 -0
- package/starter/templates/literary-text/AGENTS.md +9 -0
- package/starter/templates/literary-text/README.md +11 -0
- package/starter/templates/literary-text/index.tsx +31 -0
- package/starter/templates/literary-text/preview.tsx +20 -0
- package/starter/templates/literary-text/starter.tsx +11 -0
- package/starter/templates/literary-text/template.json +11 -0
- package/starter/templates/magazine-feature/AGENTS.md +11 -0
- package/starter/templates/magazine-feature/README.md +13 -0
- package/starter/templates/magazine-feature/index.tsx +41 -0
- package/starter/templates/magazine-feature/preview.tsx +34 -0
- package/starter/templates/magazine-feature/starter.tsx +15 -0
- package/starter/templates/magazine-feature/template.json +11 -0
- package/starter/templates/monthly-report/AGENTS.md +11 -0
- package/starter/templates/monthly-report/README.md +24 -0
- package/starter/templates/monthly-report/data.json +131 -0
- package/starter/templates/monthly-report/examples/long.json +519 -0
- package/starter/templates/monthly-report/examples/sparse.json +20 -0
- package/starter/templates/monthly-report/examples/typical.json +37 -0
- package/starter/templates/monthly-report/index.tsx +92 -0
- package/starter/templates/monthly-report/preview.tsx +14 -0
- package/starter/templates/monthly-report/schema.ts +127 -0
- package/starter/templates/monthly-report/starter.tsx +13 -0
- package/starter/templates/monthly-report/template.json +11 -0
- package/starter/templates/pitch-deck/AGENTS.md +32 -0
- package/starter/templates/pitch-deck/index.tsx +46 -0
- package/starter/templates/pitch-deck/preview.tsx +142 -0
- package/starter/templates/pitch-deck/starter.tsx +140 -0
- package/starter/templates/pitch-deck/template.json +15 -0
- package/starter/templates/proposal-deck/AGENTS.md +25 -0
- package/starter/templates/proposal-deck/index.tsx +52 -0
- package/starter/templates/proposal-deck/preview.tsx +172 -0
- package/starter/templates/proposal-deck/starter.tsx +168 -0
- package/starter/templates/proposal-deck/template.json +7 -0
- package/starter/templates/quotation/AGENTS.md +13 -0
- package/starter/templates/quotation/README.md +42 -0
- package/starter/templates/quotation/data.json +64 -0
- package/starter/templates/quotation/examples/long.json +272 -0
- package/starter/templates/quotation/examples/sparse.json +31 -0
- package/starter/templates/quotation/examples/typical.json +64 -0
- package/starter/templates/quotation/index.tsx +51 -0
- package/starter/templates/quotation/preview.tsx +12 -0
- package/starter/templates/quotation/schema.ts +27 -0
- package/starter/templates/quotation/starter.tsx +12 -0
- package/starter/templates/quotation/template.json +11 -0
- package/starter/templates/scientific-paper/AGENTS.md +11 -0
- package/starter/templates/scientific-paper/README.md +13 -0
- package/starter/templates/scientific-paper/index.tsx +47 -0
- package/starter/templates/scientific-paper/preview.tsx +43 -0
- package/starter/templates/scientific-paper/starter.tsx +15 -0
- package/starter/templates/scientific-paper/template.json +11 -0
- package/starter/themes/Specimen.tsx +54 -0
- package/starter/themes/civic-spectrum/components.tsx +92 -0
- package/starter/themes/civic-spectrum/design.md +70 -0
- package/starter/themes/civic-spectrum/index.ts +57 -0
- package/starter/themes/civic-spectrum/preview.tsx +66 -0
- package/starter/themes/field-manual/components.tsx +106 -0
- package/starter/themes/field-manual/design.md +72 -0
- package/starter/themes/field-manual/index.ts +57 -0
- package/starter/themes/field-manual/preview.tsx +82 -0
- package/starter/themes/index.ts +3 -0
- package/starter/themes/mckinsey-consulting/components.tsx +69 -0
- package/starter/themes/mckinsey-consulting/design.md +68 -0
- package/starter/themes/mckinsey-consulting/index.ts +60 -0
- package/starter/themes/mckinsey-consulting/preview.tsx +53 -0
- package/starter/themes/neutral/design.md +35 -0
- package/starter/themes/neutral/index.ts +21 -0
- package/starter/themes/neutral/preview.tsx +4 -0
- package/starter/themes/opendoc-neutral/components.tsx +77 -0
- package/starter/themes/opendoc-neutral/design.md +70 -0
- package/starter/themes/opendoc-neutral/index.ts +54 -0
- package/starter/themes/opendoc-neutral/preview.tsx +43 -0
- package/starter/themes/types.ts +3 -0
- package/tsconfig.workspace.json +24 -0
- package/vendor/formepdf/LICENSE +21 -0
- package/vendor/formepdf/README.md +97 -0
- package/vendor/formepdf/font-subset.patch +228 -0
- package/vendor/formepdf/text-writer.patch +507 -0
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# OpenDoc
|
|
2
|
+
|
|
3
|
+
An open-source document-production workspace for making well-designed English documents and presentations with a coding agent, on your computer or in a remote agent environment.
|
|
4
|
+
|
|
5
|
+
Open source under the [MIT license](LICENSE). Start with the included welcome document and presentation; no personal workspace, account, or API key is included or required.
|
|
6
|
+
|
|
7
|
+
In normal OpenDoc, **Documents** and **Presentations** have separate library pages and share the same PDF reader, text corrections, comments, projects, media, and assets. Presentations use explicit 16:9 slides with strict overflow checks. Create one with `npx opendoc create my-deck --project client-work --title "My presentation" --format presentation`, then author it using `Presentation` and `Slide`; see [presentation authoring](docs/AUTHORING.md#presentations). **Templates → Presentations** offers researched Pitch deck, Brand guidelines, Company profile, and Proposal deck skeletons. Use `--template <id>` to start from one; its presentation format is inferred. Current themes supply fonts and colors.
|
|
8
|
+
|
|
9
|
+
Bring a brief and your source material. An external coding agent authors and designs the work using native PDF components. Normal OpenDoc gives you a browser workspace for review, quick text corrections, and comments. OpenDoc Headless lets a remote agent complete the same authoring, review, and export workflow, then deliver the finished PDF or editable PowerPoint through its existing channel. The recipient needs no OpenDoc installation.
|
|
10
|
+
|
|
11
|
+
Both editions share one repository, release version, engine, authoring API, and **full starter library** of editable templates, themes, fonts, and welcome examples. Your source and assets live in the workspace environment you choose. Headless removes the browser interface and its service dependencies; it does not remove the design library or introduce a hosted service, embedded AI, or messaging connector.
|
|
12
|
+
|
|
13
|
+
## Start
|
|
14
|
+
|
|
15
|
+
Requires **Node.js 24 or newer** and **npm** on macOS or Linux in the environment running OpenDoc. Windows has not yet been verified.
|
|
16
|
+
|
|
17
|
+
### Normal OpenDoc
|
|
18
|
+
|
|
19
|
+
For the browser workspace on your computer:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npx @ryanyahya/opendoc init
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The default location is `~/Documents/My OpenDoc`. Choose another location by passing it as the destination, for example `npx @ryanyahya/opendoc init ~/Documents/ClientPublications`. The destination must be new or empty. Initialization installs a pinned OpenDoc version, copies the welcome documents and editable catalogs, starts the local service in the foreground, and opens your browser. Use `--no-start` to create the workspace without launching, or `--no-open` to start without opening a browser.
|
|
26
|
+
|
|
27
|
+
Keep the terminal running while you use the app; press **Ctrl-C** to stop it. Open the localhost URL printed there if the browser does not open. The workspace starts with **Getting started → Welcome to OpenDoc**. Use the **+ beside Projects** in the sidebar to create a home for your work. **Create document** and **Create presentation** give you a prompt to paste into your coding agent; add your brief and material. The prompt carries any selected project, template, or theme. The resulting work appears automatically.
|
|
28
|
+
|
|
29
|
+
To return later:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
cd "$HOME/Documents/My OpenDoc"
|
|
33
|
+
npx opendoc start
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Document, template, theme, and asset edits refresh while the service runs. Commands find the workspace from your current directory or any parent; `--workspace /path/to/workspace` targets one explicitly. Run `npx opendoc --help` to discover commands, `<command> --help` for details, and add `--json` for structured output.
|
|
37
|
+
|
|
38
|
+
Installation and updates need network access; the app runs locally afterward without an account or API key. An external coding agent may have its own requirements. The service listens on loopback; use the printed address instead of assuming a port. `OPENDOC_PORT` requests a fixed port.
|
|
39
|
+
|
|
40
|
+
### OpenDoc Headless
|
|
41
|
+
|
|
42
|
+
Install where your remote agent runs, with an explicit new or empty destination:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
npx --yes @ryanyahya/opendoc-headless init ./workspace --json
|
|
46
|
+
cd ./workspace
|
|
47
|
+
npx opendoc check --json
|
|
48
|
+
npx opendoc review welcome --json
|
|
49
|
+
npx opendoc export welcome --json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Initialization is noninteractive and never opens a browser or starts a service. The welcome export is `output/welcome.pdf`; the review command supplies its page images, text, and technical issues for the agent to inspect. For actual work, the agent writes the requested content, checks and reviews it, revises it, then exports and delivers the requested files. A successful render alone is not a completed review.
|
|
53
|
+
|
|
54
|
+
Inside either edition, commands remain `npx opendoc` and authoring imports remain `opendoc`. Both use the `opendoc` dependency key with an exact npm alias: `npm:@ryanyahya/opendoc@<version>` for normal OpenDoc or `npm:@ryanyahya/opendoc-headless@<version>` for Headless. The Headless alias resolves its authoring imports without installing the normal application. The workspace can persist for future revisions and reusable themes/templates, or be disposable for a single job. See [OpenDoc Headless](docs/HEADLESS.md) for the complete remote workflow, specimen creation, structured results, and file delivery.
|
|
55
|
+
|
|
56
|
+
## Update an existing workspace
|
|
57
|
+
|
|
58
|
+
In normal OpenDoc, first stop the foreground service with **Ctrl-C**. Then run this from either edition's workspace:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
npx opendoc update
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
By default, the updater chooses the latest release within the installed version's compatible range and pins its exact version. `npx opendoc update --check` reports available versions without changing the installation. Use `npx opendoc update --version <exact-version>` to choose a published stable release explicitly, including an upgrade or downgrade outside that range; tags, ranges, and prereleases are not accepted.
|
|
65
|
+
|
|
66
|
+
Updates preserve the chosen edition: normal OpenDoc updates from `@ryanyahya/opendoc`; Headless updates from `@ryanyahya/opendoc-headless`. They replace the application and its versioned guides while preserving your documents, templates, themes, assets, feedback, and project records. They do not merge new catalog examples into an existing workspace or migrate an old source checkout. Keep working in the initialized workspace; restart with `npx opendoc start` when using the normal browser edition.
|
|
67
|
+
|
|
68
|
+
## Create and revise
|
|
69
|
+
|
|
70
|
+
Both editions use the same [agent guide](AGENTS.md) and skills. In Headless, the agent works from explicit task context and catalog IDs and delivers files remotely; it does not require an active browser selection. The following browser interactions apply to normal OpenDoc.
|
|
71
|
+
|
|
72
|
+
The book icon in the sidebar and PDF reader opens a quick index of the six `opendoc-` skills. Hover, focus, or tap it to see each skill's name and purpose. The root [AGENTS.md](AGENTS.md) routes ordinary requests to the matching workflow; naming a skill is optional. The app does not run the agent itself.
|
|
73
|
+
|
|
74
|
+
Open your workspace folder in your coding agent and ask:
|
|
75
|
+
|
|
76
|
+
> Create a presentation from these notes for our project kickoff. Use our project theme. Ask me if you need to clarify the audience or template.
|
|
77
|
+
|
|
78
|
+
The workspace's `AGENTS.md` and `.agents/skills/` point to the guidance shipped with its installed OpenDoc version. The agent uses [opendoc-create](.agents/skills/opendoc-create/SKILL.md) for both documents and presentations. It follows explicit choices, asks when a meaningful theme or template preference is unclear, and exercises judgment when design is delegated. Documents are delivered as reviewed PDFs; presentations include both PDF and editable PowerPoint unless you request otherwise. You can also invoke `$opendoc-create` explicitly. Edit your content in the workspace; the app and complete guides live under `node_modules/opendoc/`.
|
|
79
|
+
|
|
80
|
+
The agent resolves a project and design direction, then creates the source through the supported command. For a written brief:
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
npx opendoc projects create client-work --name "Client work" --theme neutral
|
|
84
|
+
npx opendoc create my-brief --project client-work --title "A better handoff"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Creation makes a minimal draft, its project assignment, exact asset selections in `assets.json`, and a `theme.tsx` adapter. The agent develops `documents/my-brief/index.tsx` using native PDF components. A project theme is a default for future documents; moving a document or changing that default leaves existing choices intact.
|
|
88
|
+
|
|
89
|
+
**Templates** offers reusable layouts with real PDF specimens and a readable **View AGENTS.md** guide. **Themes** offers design systems with their own components, palettes, typography, and design guides. Pick a template when its structure helps; the brief can also call for a bespoke document. [Authoring](docs/AUTHORING.md) describes the component API.
|
|
90
|
+
|
|
91
|
+
In the reader, select a component and choose **Edit** or **Comment**. Text edits preview as a browser draft; **Save all** writes the group to local source. Drafts survive navigation and reload in the same tab. Formatting, calculations, and structural changes belong with your agent. Comments save independently, retain their history, and stay attached through reflow when block identities are preserved. [Selection and corrections](docs/SELECTION.md) explains supported edits and conflict recovery.
|
|
92
|
+
|
|
93
|
+
Use the document **…** menu to rename, duplicate, move, or delete it. Rename changes the library name, while the PDF title remains authored content. Duplicate copies saved source, local data, media, and feedback. Delete offers Undo and keeps a recovery folder in `.opendoc/trash/`; existing exports remain in `output/`. [Projects](docs/PROJECTS.md) covers membership and recovery.
|
|
94
|
+
|
|
95
|
+
## Use media, logos, and fonts
|
|
96
|
+
|
|
97
|
+
**Media & Assets** separates document-owned visuals from reusable families:
|
|
98
|
+
|
|
99
|
+
- **Media:** photographs, illustrations, charts, and diagrams, with each visual's metadata and optional prepared data and recipe beside it. Add or regenerate these with your agent. Original reference material stays in its existing project location. See [Media](docs/MEDIA.md).
|
|
100
|
+
- **Logos:** import SVG or PNG, add named variations, and describe when to use each. A saved document binding pins the chosen version. Place it explicitly with `Logo`; the app's appearance does not select artwork.
|
|
101
|
+
- **Fonts:** import original static TTF/OTF faces and inspect their real PDF specimens. Inter, Roboto, Open Sans, Lato, and Merriweather are bundled with six styles each; Geist includes regular, medium, and bold. Each family retains its license. Fonts must pass compatibility checks before becoming body or heading defaults.
|
|
102
|
+
|
|
103
|
+
Theme details can choose assets for **new documents**. Updating a family or theme default does not silently change an existing document. Use the app or the same local CLI, described in [Assets](docs/ASSETS.md):
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
npx opendoc assets list
|
|
107
|
+
npx opendoc assets inspect logo acme
|
|
108
|
+
npx opendoc assets bind my-brief logo acme
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Review and export
|
|
112
|
+
|
|
113
|
+
Both editions can prepare review evidence without a browser:
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
npx opendoc review my-brief --json
|
|
117
|
+
npx opendoc review --theme neutral --json
|
|
118
|
+
npx opendoc review --template editorial-essay --json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Each successful result supplies a PDF, page PNGs, extracted text, render issues, and a manifest identifying the exact PDF revision and its sources. The command renders saved workspace source directly; in normal OpenDoc, save intended browser text corrections first. The agent inspects these artifacts and refines the work before final export. The manifest's `visualReview` and `factualReview` stay `required`: preparing evidence does not perform those reviews. See [Headless review](docs/HEADLESS.md#author-inspect-revise-deliver).
|
|
122
|
+
|
|
123
|
+
In normal OpenDoc, the reader shows the real PDF, including navigation, links, and current render warnings. An invalid revision keeps the last successful preview visible and blocks export until corrected. Review the current ready PDF, including every page, source notes, and representative copied text. The [opendoc-review-document skill](.agents/skills/opendoc-review-document/SKILL.md) supplies the final pass.
|
|
124
|
+
|
|
125
|
+
In the browser, **Export → Save PDF** saves the reviewed bytes in `output/`, preserving existing files with numbered names. Save pending text corrections and review the updated PDF first. The result can reveal the file, download a copy, or open the PDF to print. For presentations, choose **PowerPoint (.pptx)** to save editable text and shapes with embedded fonts. Images and existing chart artwork remain images. On macOS it can also copy the exported file to the system clipboard. **Previous exports** lists saved files with open, reveal, and delete-with-Undo actions. If a save response is interrupted, **Check export** recovers the same request.
|
|
126
|
+
|
|
127
|
+
Command-line export supports single documents and batches:
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
npx opendoc export my-brief
|
|
131
|
+
npx opendoc export welcome-presentation --format pptx
|
|
132
|
+
npx opendoc export welcome my-brief --json
|
|
133
|
+
npx opendoc export --all --json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
PowerPoint export uses the successful render’s content, media, and font bytes. It supports 16:9 slides with editable text, rectangular shapes, and images. Unsupported effects or fonts produce a specific error and preserve existing exports. Tables composed from individual blocks stay separate objects; chart images stay images. Embedded fonts must permit editing and have TrueType outlines. Representative slides were reviewed in PowerPoint on macOS; Windows compatibility has not yet been verified.
|
|
137
|
+
|
|
138
|
+
CLI export writes `output/<id>.pdf` or `output/<id>.pptx`, replacing that document's previous CLI output only after successful rendering and freshness checks. In normal OpenDoc, a running local service supplies current preview bytes; without it, export renders fresh. Headless always renders directly and does not consult a browser session. Inspect each batch result. Saved exports are independent of later edits and retain their asset provenance when available.
|
|
139
|
+
|
|
140
|
+
## Find the right guide
|
|
141
|
+
|
|
142
|
+
For development and pull requests, read [Contributing](CONTRIBUTING.md). Review the local trust model in [Security](SECURITY.md) and the bundled notices in [Third-party notices](THIRD_PARTY.md).
|
|
143
|
+
|
|
144
|
+
| Task | Read |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
| First agent task or source conventions | [AGENTS.md](AGENTS.md) |
|
|
147
|
+
| Produce finished files remotely without a GUI | [OpenDoc Headless](docs/HEADLESS.md) |
|
|
148
|
+
| Write a document or use PDF primitives | [Authoring](docs/AUTHORING.md) |
|
|
149
|
+
| Resolve the active document or feedback | [Current document skill](.agents/skills/opendoc-current-document/SKILL.md), [Selection](docs/SELECTION.md) |
|
|
150
|
+
| Create or adapt a reusable layout | [Templates](docs/TEMPLATES.md) |
|
|
151
|
+
| Create or apply a design system | [Themes](docs/THEMES.md) |
|
|
152
|
+
| Manage projects and document ownership | [Projects](docs/PROJECTS.md) |
|
|
153
|
+
| Prepare document visuals | [Media](docs/MEDIA.md) |
|
|
154
|
+
| Import and bind shared logos or fonts | [Assets](docs/ASSETS.md) |
|
|
155
|
+
| Change the app or prepare a release | [Validation](VALIDATION.md), [Appearance](docs/APPEARANCE.md) |
|
|
156
|
+
| Understand licenses and the PDF engine repair | [Third-party notices](THIRD_PARTY.md), [Forme repair](vendor/formepdf/README.md) |
|
|
157
|
+
|
|
158
|
+
## Develop the application
|
|
159
|
+
|
|
160
|
+
Contributors work in a source checkout with Node.js 24 or newer and **pnpm 12.3.4**, pinned in `package.json`:
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
pnpm install --frozen-lockfile
|
|
164
|
+
pnpm dev
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
For the built interface, run `pnpm build` followed by `pnpm start`. These contributor commands use the checkout's catalogs and local service. Ordinary writing in an installed workspace uses `npx opendoc` and does not require a source checkout or a frontend build.
|
|
168
|
+
|
|
169
|
+
Before opening a pull request, run `pnpm verify` for typechecking, the full test suite, and the production build. The same checks run on Linux and macOS in CI. See [Validation](VALIDATION.md) for the local workflow and PDF acceptance checks. Package both releases with `pnpm package:pack`; it produces `output/packages/ryanyahya-opendoc-<version>.tgz` and `output/packages/ryanyahya-opendoc-headless-<version>.tgz`. Use both reviewed tarballs for clean-install acceptance and any explicitly authorized npm publication. Both include the same repaired PDF engine and full starter catalogs; normal OpenDoc additionally contains the built browser interface. Use `--edition normal` or `--edition headless` for a focused package build. Do not substitute a direct `npm pack` from the checkout.
|
|
170
|
+
|
|
171
|
+
## Workspace boundaries
|
|
172
|
+
|
|
173
|
+
`documents/` holds authored work; `templates/` holds reusable layouts and data contracts; `themes/` holds executable visual systems; `assets/` holds shared local resources. `projects.json` records document membership. `.opendoc/` holds generated context, previews, recovery records, and session state; `output/` holds exported PDFs and PowerPoint files. Generated state and exports are ignored by Git.
|
|
174
|
+
|
|
175
|
+
Authoring uses the public imports `opendoc`, `opendoc/template`, `opendoc/assets`, and `opendoc/themes`. Keep references to your editable local catalogs relative to the workspace. The pinned application dependency lives in `node_modules/opendoc`; ordinary document work does not change it. The workspace's `package.json`, lockfile, and `.opendoc/workspace.json` identify its installation and format.
|
|
176
|
+
|
|
177
|
+
In a source checkout, `src/document/` implements the authoring API, `src/template/` binds validated data, `src/assets/` owns shared asset contracts, `src/rendering/` supplies shared render utilities, `src/cli/` owns installation and command dispatch, and `src/server/` contains render/file operations alongside the normal edition's service entry. `src/shared/` holds shared contracts and `src/app/` is the browser review interface. Shared render and export operations are callable without the service; both packages use the same implementation.
|
|
178
|
+
|
|
179
|
+
OpenDoc remains an English-only TSX authoring product that runs in the user's or agent's workspace. It has no embedded AI, Markdown document editor, visual theme editor, or cloud collaboration. Document code is trusted local code; render workers isolate crashes and timeouts, not hostile code. Keep the service local and never copy `.opendoc/server.json`'s session token into documents, logs, or messages.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
OpenDoc runs a local Node service bound to loopback. It has no hosted account system or cloud collaboration service. Keep it local; exposing its port through a proxy or tunnel is outside the supported deployment model.
|
|
4
|
+
|
|
5
|
+
Document, template, and theme TSX is trusted executable code. Render workers isolate crashes and timeouts, but they are not a security sandbox. Review unfamiliar repositories and TSX before opening or rendering them. An external coding agent has its own permissions and data-sharing behavior.
|
|
6
|
+
|
|
7
|
+
The app stores documents, source media, feedback, and recovery data locally. `.opendoc/server.json` includes a local session token. Do not publish that file or attach personal work, tokens, or unredacted recovery records to an issue.
|
|
8
|
+
|
|
9
|
+
For a vulnerability, use the hosting repository's private vulnerability reporting channel when available, or contact a maintainer privately. Include a minimal reproduction using synthetic data and the affected revision. Do not disclose exploitable details or private files in a public issue while coordinating a fix. Ordinary defects can use the issue tracker with the guidance in [CONTRIBUTING.md](CONTRIBUTING.md).
|
package/THIRD_PARTY.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
- **Forme 0.20.1**: shared React serializer, JavaScript definitions, and PDF rendering through repaired Node WASM. OpenDoc carries PDF text-writer and embedded font-subset metadata repairs in core 0.20.1-opendoc.3; both editions bundle the same repaired Node engine. Source patches, rebuild instructions, and MIT license are in `vendor/formepdf/`; the source repository also retains the rebuild archive, excluded from runtime packages. The attributed asset resolver in `src/rendering/resolve-sources.ts` is adapted from `@formepdf/renderer` 0.20.1 under that MIT license (Daniel Molitor, 2026); OpenDoc supplies its own TSX bundling and source-location capture. Original imported font files remain unchanged. https://github.com/formepdf/forme
|
|
4
|
+
- **PDF.js**: PDF preview, review page rendering, and text extraction. Apache-2.0. https://github.com/mozilla/pdf.js
|
|
5
|
+
- **@napi-rs/canvas 1.0.8**: Skia-backed Node canvas for PDF review page PNGs, without a browser. MIT; native dependencies retain their upstream notices. https://github.com/Brooooooklyn/canvas
|
|
6
|
+
- **Base UI 1.8.0**: accessible interface controls. MIT. https://github.com/mui/base-ui
|
|
7
|
+
- **React** and **Vite**: interface and development server. Their licenses are included in the installed packages.
|
|
8
|
+
- **ts-pptx 3.7.0**: editable PowerPoint generation. MIT. https://github.com/shbernal/ts-pptx
|
|
9
|
+
- **ttf2eot 3.1.0**: embedded TrueType font packaging for PowerPoint. MIT. https://github.com/fontello/ttf2eot
|
|
10
|
+
- **fontkit 2.0.4**: font inspection and metadata. MIT. https://github.com/foliojs/fontkit
|
|
11
|
+
- **resvg-js 2.6.2**: SVG rasterization. MPL-2.0; distributed through its installed package, with upstream source and notices at https://github.com/yisibl/resvg-js
|
|
12
|
+
|
|
13
|
+
## Bundled fonts
|
|
14
|
+
|
|
15
|
+
OpenDoc Sans, OpenDoc Serif, and OpenDoc Mono are renamed derivatives of Adobe Source Sans 3, Source Serif 4, and Source Code Pro, distributed under the SIL Open Font License 1.1. The original notices and licenses are retained beside the fonts in `assets/fonts/`. Sans and Serif include regular, semibold, italic, and semibold italic faces. Mono includes a regular face for code specimens.
|
|
16
|
+
|
|
17
|
+
These historical derivatives removed GSUB, GPOS, and legacy kern tables to work around the original Forme 0.20.1 writer's ligature and spacing bugs. The engine now fixes those bugs directly; the existing derivatives are retained unchanged for document continuity. Outlines are unchanged; these variants intentionally use unkerned character spacing. Family and PostScript names are renamed to respect the reserved name “Source”. The derived font software remains under OFL 1.1.
|
|
18
|
+
|
|
19
|
+
These checked-in derivatives retain their existing metrics for built-in themes. New font imports preserve the original files and shaping tables and are checked through the repaired PDF engine. The app needs no font conversion tools. Upstream sources:
|
|
20
|
+
|
|
21
|
+
- https://github.com/adobe-fonts/source-sans/tree/release/TTF
|
|
22
|
+
- https://github.com/adobe-fonts/source-serif/tree/release/TTF
|
|
23
|
+
- https://github.com/adobe-fonts/source-code-pro/tree/release/TTF
|
|
24
|
+
|
|
25
|
+
## Google Fonts asset families
|
|
26
|
+
|
|
27
|
+
Inter, Roboto, Open Sans, Lato, and Merriweather are bundled as shared font assets under the SIL Open Font License 1.1. Each includes regular (400), semibold (600), bold (700), and the corresponding italic styles. These are Google-supplied static TTF files preserved byte for byte, not OpenDoc derivatives. The app makes no network request to use or inspect them.
|
|
28
|
+
|
|
29
|
+
Each `assets/fonts/<family-id>/` folder retains `OFL.txt` with the original copyright notice and `source.json` with the exact download URLs, SHA-256 hashes, original filenames, and their managed asset paths. Lato comes from a pinned revision of the official `google/fonts` repository; the other four use the static TTF responses from the official Google Fonts CSS API, served by `fonts.gstatic.com`.
|
|
30
|
+
|
|
31
|
+
- Inter: https://fonts.google.com/specimen/Inter
|
|
32
|
+
- Roboto: https://fonts.google.com/specimen/Roboto
|
|
33
|
+
- Open Sans: https://fonts.google.com/specimen/Open+Sans
|
|
34
|
+
- Lato: https://fonts.google.com/specimen/Lato
|
|
35
|
+
- Merriweather: https://fonts.google.com/specimen/Merriweather
|
|
36
|
+
|
|
37
|
+
The bundled revisions include PDF compatibility results and specimens. The app uses those checks to determine eligibility for theme defaults; `tests/bundled-fonts.test.ts` and `tests/font-renderer.test.ts` cover the bundled files and text rendering, while `tests/font-subset.test.ts` checks metadata in the actual embedded font streams. Original font files, names, shaping tables, and hashes are preserved.
|
|
38
|
+
|
|
39
|
+
## Geist and interface fonts
|
|
40
|
+
|
|
41
|
+
Geist is distributed under SIL OFL 1.1. Its copyright and license are retained in `assets/ui-fonts/geist/OFL.txt` and `assets/fonts/geist/OFL.txt`. The interface uses variable WOFF2 files from `@fontsource-variable/geist` 5.3.0, with package provenance and exact hashes in `assets/ui-fonts/geist/source.json`. The shared document asset contains static regular, medium, and bold faces, with hashes and a PDF specimen recorded in its immutable revision. Upstream: https://github.com/vercel/geist-font
|
|
42
|
+
|
|
43
|
+
The retained Inter UI TTF files carry their own OFL notice, original URLs, and hashes in `assets/fonts/InterUI-LICENSE.txt` and `assets/fonts/InterUI-source.json`.
|
|
44
|
+
|
|
45
|
+
## OpenDoc examples and branding
|
|
46
|
+
|
|
47
|
+
The welcome document and presentation contain OpenDoc demo artwork and synthetic chart data. Their media metadata identifies the AI-generated paper illustration and the chart's data and recipe. They contain no customer records. OpenDoc-authored source and example assets follow the repository's MIT license; bundled font software retains its separate OFL license. The OpenDoc wordmark is project artwork.
|
|
48
|
+
|
|
49
|
+
The McKinsey Consulting theme is an independent interpretation of analytical publication conventions. It contains no McKinsey logo or proprietary font and does not imply affiliation or endorsement. Other theme and template specimens use illustrative content; their design guides retain relevant research references.
|
package/VALIDATION.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Verification and release checks
|
|
2
|
+
|
|
3
|
+
This guide describes repeatable checks, not a claim that an old run validates today's source. Run checks appropriate to the change; record the commands, results, and material limitations in the delivery or pull request. A successful build alone does not demonstrate the document workflow.
|
|
4
|
+
|
|
5
|
+
## Automated checks
|
|
6
|
+
|
|
7
|
+
From the repository root:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pnpm install --frozen-lockfile
|
|
11
|
+
pnpm verify
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`pnpm verify` runs typechecking, the production build, and all tests. Building first makes the installed interface available to server integration tests; run `pnpm build` before invoking those tests directly from a fresh checkout. CI runs the same checks on Linux and macOS. The suite exercises real PDF rendering as well as data and service contracts. It covers document creation and project membership; references and pagination; template schemas, arithmetic, and theme integration; selection, comments, and guarded text edits; asset import, versioning, bindings, and fonts; export freshness, receipts, and recovery. Tests use disposable workspaces rather than adding sample documents to the shipped library.
|
|
15
|
+
|
|
16
|
+
For a focused change, run the relevant existing test files with `pnpm exec tsx --test tests/<name>.test.ts`. Run the full checks before a release. Once successful checks cover the final source, repeat them only if new edits or evidence require it.
|
|
17
|
+
|
|
18
|
+
Keep tests tied to a distinct failure or observable contract. When a template already renders in a test, check its text ownership and other related guarantees on that result rather than adding another rendering pass. Test shared creation and validation rules once; keep template-specific checks for layout, editable content, and calculations. Avoid locking tests to incidental copy, catalog counts, or source formatting. Small wording and styling changes normally need review of the existing output, not new tests.
|
|
19
|
+
|
|
20
|
+
## Installed-package acceptance
|
|
21
|
+
|
|
22
|
+
After `pnpm verify`, run `pnpm package:pack` and use both generated tarballs: `output/packages/ryanyahya-opendoc-<version>.tgz` and `output/packages/ryanyahya-opendoc-headless-<version>.tgz`. Both include the same repaired Node PDF engine, full starter catalogs, and shared versioned guides. Normal OpenDoc also includes the built browser interface; Headless excludes that interface and its service dependencies. Direct `npm pack` from the repository is not the release packaging route. `pnpm package:pack --edition normal` or `--edition headless` supports focused package checks; a release needs both.
|
|
23
|
+
|
|
24
|
+
Exercise both tarballs outside the source checkout on macOS and Linux with Node.js 24 or newer and npm. For a release that is not published, set `OPENDOC_PACKAGE_TARBALL` to the selected tarball's absolute path so initialization installs the same reviewed artifact. For normal OpenDoc:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
export OPENDOC_PACKAGE_TARBALL=/absolute/path/to/ryanyahya-opendoc-0.4.0.tgz
|
|
28
|
+
npm exec --yes --package="$OPENDOC_PACKAGE_TARBALL" -- opendoc init /tmp/opendoc-acceptance --no-start --json
|
|
29
|
+
cd /tmp/opendoc-acceptance
|
|
30
|
+
npx opendoc check --json
|
|
31
|
+
npx opendoc start --no-open
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use a new or empty destination. Confirm initialization refuses nonempty folders and leaves existing files intact. Also exercise the interactive default `~/Documents/My OpenDoc` using an isolated home or explicitly chosen disposable folder, then check the default browser launch and `--no-open`. A noninteractive invocation must supply its destination.
|
|
35
|
+
|
|
36
|
+
Confirm the normal workspace pins `dependencies.opendoc` to the exact alias `npm:@ryanyahya/opendoc@<version>` and contains its own documents, themes, templates, assets, project records, and `.opendoc/workspace.json`. Verify its `AGENTS.md` and skill pointers reach the installed guidance, and that template/theme guides can open shared documentation without a checkout. From a nested folder, run a workspace command to check ancestor discovery; from elsewhere, use `--workspace`. Exercise `--help`, `--json`, and actionable failures.
|
|
37
|
+
|
|
38
|
+
Create and revise a document and presentation through `npx opendoc create`, then run `npx opendoc check`, PDF export, and PPTX export against that installed workspace. Confirm edits to its local theme/template affect the intended documents. Complete the relevant reader checks below. Successful repository tests alone do not prove the installed workflow.
|
|
39
|
+
|
|
40
|
+
Stop the foreground service with **Ctrl-C**, start it again, and stop it before update acceptance. Test update discovery with `npx opendoc update --check --json`; exercise a compatible update and an explicit exact-version request in a controlled fixture. Confirm the installed runtime and its package guidance change together while local documents, feedback, themes, templates, assets, and project files retain their bytes. Exercise invalid targets and a running-service rejection; keep legacy checkout migration and catalog merging outside the update path. Do not publish to test an update; use controlled registry fixtures or already authorized published versions.
|
|
41
|
+
|
|
42
|
+
## Headless installed-package acceptance
|
|
43
|
+
|
|
44
|
+
Use a separate disposable workspace and the Headless tarball:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
export OPENDOC_PACKAGE_TARBALL=/absolute/path/to/ryanyahya-opendoc-headless-0.4.0.tgz
|
|
48
|
+
npm exec --yes --package="$OPENDOC_PACKAGE_TARBALL" -- opendoc-headless init /tmp/opendoc-headless-acceptance --json
|
|
49
|
+
cd /tmp/opendoc-headless-acceptance
|
|
50
|
+
npx opendoc check --json
|
|
51
|
+
npx opendoc review welcome --json
|
|
52
|
+
npx opendoc review welcome-presentation --json
|
|
53
|
+
npx opendoc export welcome --json
|
|
54
|
+
npx opendoc export welcome-presentation --json
|
|
55
|
+
npx opendoc export welcome-presentation --format pptx --json
|
|
56
|
+
npx opendoc review --theme neutral --json
|
|
57
|
+
npx opendoc review --template editorial-essay --json
|
|
58
|
+
npx opendoc templates check editorial-essay --json
|
|
59
|
+
npx opendoc templates preview editorial-essay --json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Confirm `init` requires an explicit destination even when a terminal is available, never prompts or starts a browser/service, and refuses nonempty folders without replacing their files. The workspace marker records the Headless edition. Its exact dependency is `opendoc: npm:@ryanyahya/opendoc-headless@<version>`; public imports, `node_modules/opendoc/` guide links, nested command discovery, and `npx opendoc` must work without the normal package or checkout. `start` should reject the unsupported GUI operation with actionable production commands.
|
|
63
|
+
|
|
64
|
+
Compare the editable starter documents, templates, themes, fonts, and example media between clean installations. Both must retain the full library. Confirm the Headless package contains no built interface or GUI-only dependency tree; the native PDF/page-image dependencies remain available on each tested platform. Render the same unchanged workspace source and asset bytes in both editions and compare the PDFs and editable presentation content. Packaging reductions must not change document output.
|
|
65
|
+
|
|
66
|
+
Inspect each successful review result's exact PDF hash, page count and dimensions, page images/text, render issues, stable block/source information, and output paths. Open every page image of representative documents, decks, and specimens at readable scale; inspect text extraction and the final exported files. `visualReview: "required"` and `factualReview: "required"` must not be converted into automated claims that these reviews passed.
|
|
67
|
+
|
|
68
|
+
Exercise a failed/overflowing revision and source edits during rendering. Check nonzero exit status and structured issues when available, and confirm previous successful review files and exports remain intact without being labeled as the failed revision. Headless review/export must work without a live service, built interface, or browser context; stale or malformed `.opendoc/server.json` must not affect its direct production path. Include a bespoke document and a reusable theme/template change, then verify their specimens and dependent instance outside the checkout.
|
|
69
|
+
|
|
70
|
+
Check PPTX slide count/order, editable text, media, and font parts against the reviewed PDF. Native PowerPoint inspection is useful when available; a remote environment without PowerPoint can finish package/content checks and report that native appearance was not verified. Do not substitute a PDF for a failed requested PPTX or require the recipient to install OpenDoc to complete acceptance.
|
|
71
|
+
|
|
72
|
+
Exercise update discovery and an exact-version update in a controlled fixture. Confirm registry selection stays on `@ryanyahya/opendoc-headless`, the exact alias and workspace edition remain Headless, runtime/guidance update together, and all authored workspace content retains its bytes. Verify a remote delivery fixture exposes the actual PDF/PPTX through an accessible output mechanism; a host-only path is insufficient when the recipient cannot access it. No messaging service or publication is needed to demonstrate file production.
|
|
73
|
+
|
|
74
|
+
## Reader and contributor-checkout acceptance
|
|
75
|
+
|
|
76
|
+
Use a disposable copy of the workspace for destructive, conflict, and recovery exercises. Keep the shipped library at **Getting started → Welcome to OpenDoc**; template and theme specimens belong in their catalogs.
|
|
77
|
+
|
|
78
|
+
1. In a source checkout, start with `pnpm start` after building; in an installed workspace, use `npx opendoc start`. Confirm the printed local URL opens, Welcome renders, and Templates, Themes, and Media & Assets load. Also check `pnpm dev` after changes to the development server integration.
|
|
79
|
+
2. Create a project and a document using the documented command or template flow. Confirm assignment, the chosen theme, `theme.tsx`, and exact `assets.json` choices. Edit source and confirm the current PDF refreshes.
|
|
80
|
+
3. Open the document, make a text draft, navigate away and back, then save it. Confirm source and PDF agree. Leave a comment, apply the intended revision, and resolve it through `pnpm comments` in the checkout or `npx opendoc comments` in the installed workspace. For editing changes, exercise a stale-source conflict and ensure pending text survives.
|
|
81
|
+
4. Bind a shared font and logo; verify actual PDF usage, copied text, logo proportions, and the correct variation for the page background. For asset changes, check historical bindings remain readable and archive/Undo does not overwrite newer choices.
|
|
82
|
+
5. Save a PDF through Export and open it. For presentations, also save PowerPoint and check editable text, embedded fonts, and slide content against the preview. Check previous exports and a CLI export. For export changes, exercise an interrupted response and recovery, plus an invalid render that preserves the previous valid output.
|
|
83
|
+
6. Check the affected interface at desktop and narrow width, with keyboard navigation, light/dark appearance, and readable errors and empty states. Check every page of changed PDFs at a legible size; a thumbnail or contact sheet alone is insufficient.
|
|
84
|
+
|
|
85
|
+
Document duplicate, move, delete, and Undo should preserve local data and asset selections. Exercise these after lifecycle changes. Test startup, shutdown, and a second launch after server changes; do not leave acceptance documents or temporary server sessions in the release workspace.
|
|
86
|
+
|
|
87
|
+
## Review the actual output
|
|
88
|
+
|
|
89
|
+
For documents, use the [opendoc-review-document skill](.agents/skills/opendoc-review-document/SKILL.md). Shared templates need representative sparse and long input plus a second theme. Shared themes need a reviewed specimen and representative affected layouts. Newly imported fonts need their real PDF specimen and review in the intended document. Check visual clipping and page breaks as well as extracted text, links, figures, calculations, and references relevant to the change.
|
|
90
|
+
|
|
91
|
+
`pnpm themes -- preview <id>` in a source checkout, or `npx opendoc themes preview <id>` in either installed edition, exports a selected theme specimen for review. `npx opendoc templates preview <id>` exports a template specimen. `npx opendoc review --theme <id> --json` and `review --template <id> --json` also prepare page images/text for direct inspection without the app. Specimens do not become user documents. Use existing test fixtures for longer cases instead of keeping throwaway reports in `documents/`.
|
|
92
|
+
|
|
93
|
+
## Current boundaries
|
|
94
|
+
|
|
95
|
+
- The normal edition's built interface needs the local Node service and authoring dependencies. A static upload of `dist/` is not a working OpenDoc installation. Headless commands run directly without a service; they still require the document engine and native runtime dependencies.
|
|
96
|
+
- Render workers execute trusted local TSX. Their process boundary handles crashes and timeouts; it is not a hostile-code sandbox.
|
|
97
|
+
- Native Forme chart labels and inline link annotations have limitations. Use managed raster charts and whole-block links as described in [Authoring](docs/AUTHORING.md). Native list pagination uses OpenDoc's text-row workaround.
|
|
98
|
+
- OpenDoc carries Forme text-writer and embedded font-subset metadata repairs. Font regressions check extracted text and geometry, plus subset table lengths, checksums, and hinting profiles. Preserve original imported fonts; do not strip shaping tables to hide engine failures. See [the patches and rebuild guide](vendor/formepdf/README.md).
|
|
99
|
+
- Automated geometry and text checks do not establish factual accuracy, full accessibility conformance, legal compliance, or visual quality. State concrete unverified limits without presenting historical results as current proof.
|
package/bin/opendoc.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# App appearance
|
|
2
|
+
|
|
3
|
+
OpenDoc supports **Light**, **Dark**, and **System** through the sidebar footer and the reader's Document options menu. System is the default. The browser saves an explicit choice under `opendoc-appearance`, synchronizes it between workspace tabs, and applies it before the first paint. If storage is unavailable, the current session still works. System follows live device appearance changes.
|
|
4
|
+
|
|
5
|
+
## Source of truth
|
|
6
|
+
|
|
7
|
+
[colors.css](../src/app/colors.css) owns the semantic palette, including increased-contrast overrides. Reuse its roles for surfaces, text, controls, feedback, focus, and PDF inspection. Keep component styles in the existing app stylesheets and reuse [shared controls](../src/app/ui/ui.css). Do not duplicate palette values in documentation or component-local overrides.
|
|
8
|
+
|
|
9
|
+
The interface uses bundled Inter Regular and Medium, independently of the document font catalog. Shared typography and density tokens live in `src/app/ui/ui.css`: titles use 16/20px Medium, labels 13/16px Medium, and body text 14/20px Regular. Buttons use a 32px minimum height with a 10px radius; data rows use 40px and navigation/library rows 44px. Rows may grow for wrapped content. Existing status badges use a 20px height and 6px radius, with palette roles defined in `colors.css`. Switch dimensions are reserved as tokens (24×14px with a 10px thumb); no switch control is currently used in the app.
|
|
10
|
+
|
|
11
|
+
Preserve larger touch targets where the compact reader needs them. Keep labels and descriptions readable, long names and paths wrapping, visible keyboard focus, and usable controls at narrow widths. Use the existing reduced-motion behavior.
|
|
12
|
+
|
|
13
|
+
## Preserve the PDF boundary
|
|
14
|
+
|
|
15
|
+
Appearance changes the surrounding interface. Paper, media, logo variations, theme specimens, and exports retain their authored colors. Do not invert a PDF canvas or choose logo artwork from the app appearance. Media and asset preview backgrounds are inspection aids; they do not modify source files.
|
|
16
|
+
|
|
17
|
+
## Verify changes
|
|
18
|
+
|
|
19
|
+
Review affected views in light and dark appearance, then with increased contrast. Check text, actions, menus, notices, disabled states, and visible focus against their actual backgrounds. Check system switching, explicit overrides, reload persistence, and cross-tab synchronization when changing appearance state. Include the reader, comments, and a narrow workspace view after shared palette or shell changes.
|
|
20
|
+
|
|
21
|
+
Use measured contrast ratios and readable screenshots as evidence for the specific colors and states changed. Do not turn a palette measurement into a claim of complete accessibility conformance. A PDF rendered before and after an app-only appearance change should have identical bytes.
|
package/docs/ASSETS.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Media & Assets
|
|
2
|
+
|
|
3
|
+
OpenDoc keeps reusable **Logos** and **Fonts** in a shared workspace library. **Media** remains owned by its document: photographs, illustrations, charts, and diagrams retain their prepared data, recipes, and evidence. Do not copy a shared logo or font into every document. Original reference material stays wherever the surrounding project manages it.
|
|
4
|
+
|
|
5
|
+
The app and `npx opendoc assets` operate on the same local records, import checks, and conflict protection. Selecting a library item tells the agent what the user is looking at; it does not apply it to any document or theme.
|
|
6
|
+
|
|
7
|
+
Run commands from the workspace root. Asset, theme, document, and output paths in this guide refer to that workspace; this guide is installed under `node_modules/opendoc/docs`.
|
|
8
|
+
|
|
9
|
+
## Start from the document
|
|
10
|
+
|
|
11
|
+
1. Resolve the intended document and read fresh `.opendoc/current.json` when the user refers to the current selection.
|
|
12
|
+
2. Discover with `npx opendoc assets list`. Inspect only the relevant family to read its variations, guidance, compatibility, paths, relationships, and authoring examples.
|
|
13
|
+
3. Bind the chosen asset to the document. This saves an exact version immediately. Choose a logo variation from its guidance and the actual PDF background, never from the app's light/dark appearance.
|
|
14
|
+
4. Use `Logo` or the document's semantic fonts, render, and review the resulting PDF. A binding makes an asset available; it is not proof that the PDF uses it.
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
npx opendoc assets list logo
|
|
18
|
+
npx opendoc assets inspect logo acme
|
|
19
|
+
npx opendoc assets bind my-report logo acme --variation default
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The supported binding roles are `logo`, `body-font`, and `heading-font`. For example, bind an imported, eligible family with `npx opendoc assets bind my-report body-font acme-sans`. Use `--name partner` with the `logo` role to add a named logo instead of changing the preferred logo. `--revision <revision>` chooses a historical version; omission captures the current version at binding time. Repeating `bind` is an explicit update. `unbind <document> <role>` removes that choice; add `--name <binding>` when removing a named logo.
|
|
23
|
+
|
|
24
|
+
## Logos: one identity, several variations
|
|
25
|
+
|
|
26
|
+
In the app, choose **Add logo**, enter a name, then upload the default SVG or PNG. The logo opens as a folder with that default file. Use **Add variations** inside the folder to select one or more additional files together; names are suggested from filenames and can be edited before uploading. A family can mix SVG and PNG originals, with user-defined variation names and optional **When to use** descriptions. “On light backgrounds” and “On dark backgrounds” are suggestions, not fixed categories.
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
npx opendoc assets import logo --id acme --name "Acme" --description "Use for Acme publications." --file /path/to/acme.png --variation-name "On light backgrounds" --variation-description "Dark mark for white or pale surfaces."
|
|
30
|
+
npx opendoc assets inspect logo acme
|
|
31
|
+
npx opendoc assets add-variation acme --id on-dark --name "On dark backgrounds" --description "White mark for dark surfaces." --file /path/to/acme-white.svg --expected-revision <current-revision>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Copy the real revision returned by inspection; angle-bracket placeholders in this guide are not literal values. The first variation's stable ID is `default`, even when its display name is “On light backgrounds.” Names and guidance can change without changing family or variation IDs. To replace a variation's file, use `add-variation` with `--replace <variation-id>`, the desired name, and the latest `--expected-revision`. Replacement preserves the variation's identity and publishes a new family version.
|
|
35
|
+
|
|
36
|
+
Use a JSON file for revisions instead of long sets of metadata flags:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"expectedRevision": "copy-the-current-revision-from-inspect",
|
|
41
|
+
"description": "Brand guidance for the agent.",
|
|
42
|
+
"defaultVariation": "on-dark",
|
|
43
|
+
"variation": {
|
|
44
|
+
"id": "on-dark",
|
|
45
|
+
"name": "On dark backgrounds",
|
|
46
|
+
"description": "Use the white mark on dark navy or black backgrounds."
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
npx opendoc assets revise logo acme --metadata /path/to/logo-update.json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Omit unchanged fields. The revision operation also accepts `name`, `removeVariation`, or `removeFace` for the relevant asset kind. Keep at least one usable variation or face, and select an existing default variation. Concurrent changes produce a conflict; inspect again and reconcile the intended edit instead of blindly retrying old metadata.
|
|
56
|
+
|
|
57
|
+
The logo folder shows all variations as file tiles. Select a file to preview it, edit its name or guidance, replace it, make it the default, or remove it. Removing the default requires choosing a replacement; every logo keeps at least one variation. If a batch upload stops on an invalid file, successful files stay saved and the remaining upload list stays open for correction and retry. Its light, dark, and transparency backgrounds are inspection aids. They do not recolor artwork or choose the PDF variation. Preview and PDF use the same prepared PNG. SVG originals are preserved and prepared locally through resvg, with proportions and transparency retained. Unsupported external resources or unresolved text fonts produce a useful import error. Supply self-contained artwork with text converted to outlines when necessary. SVG imports are limited to 5 MB; PNG imports to 50 MB.
|
|
58
|
+
|
|
59
|
+
### Place a logo
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { Figure, Logo } from 'opendoc';
|
|
63
|
+
|
|
64
|
+
// The preferred document binding; omission of variation uses its saved default.
|
|
65
|
+
<Logo width={120} />
|
|
66
|
+
|
|
67
|
+
// A deliberate variation, identified by its stable ID from inspection.
|
|
68
|
+
<Logo variation="on-dark" width={120} alt="Acme" />
|
|
69
|
+
|
|
70
|
+
// A second logo bound with --name partner.
|
|
71
|
+
<Figure id="partner-mark" caption="Delivery partner">
|
|
72
|
+
<Logo name="partner" width={100} height={48} />
|
|
73
|
+
</Figure>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Width is required and measured in PDF points. Optional height is a maximum bound; the image retains its aspect ratio. An omitted variation uses the binding's explicit variation, otherwise the saved revision's default. Missing bindings and unknown variations fail with an actionable error. Logo placement is always explicit; a theme default does not add a logo to the page automatically. Preserve the enclosing block ID when replacing artwork so feedback stays attached.
|
|
77
|
+
|
|
78
|
+
## Fonts: actual files, actual PDF checks
|
|
79
|
+
|
|
80
|
+
Import static TTF/OTF faces from one family together, with repeated `--file` flags. The app asks only for font files. OpenDoc reads their family name, embedded English description (when present), weight, and style, then renders and checks a PDF specimen. A font without an embedded description stays blank; optional agent guidance can be edited later. Variable fonts, font collections, and web-font conversion are outside this release.
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
npx opendoc assets import font --id acme-sans --file /path/to/AcmeSans-Regular.ttf --file /path/to/AcmeSans-Bold.ttf --file /path/to/AcmeSans-Italic.ttf
|
|
84
|
+
npx opendoc assets inspect font acme-sans
|
|
85
|
+
npx opendoc assets add-faces acme-sans --file /path/to/AcmeSans-BoldItalic.ttf --expected-revision <current-revision>
|
|
86
|
+
npx opendoc assets bind my-report body-font acme-sans
|
|
87
|
+
npx opendoc assets bind my-report heading-font acme-sans
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Import at most 24 faces and 100 MB at once. Added faces must belong to the existing embedded font family, even when replacing every face; import a different family separately. Original files are preserved; OpenDoc does not rewrite font tables or synthesize missing faces. General body and heading defaults require a regular face plus a semibold or bold face and passing compatibility checks. A family needing attention can remain in the library for inspection, but cannot become a body/heading default. Missing styles are visible in the family detail; explicitly requesting an unavailable weight or italic style fails when rendering. A semibold request can use a real bold face of the same style when semibold is absent; it retains that face's actual weight.
|
|
91
|
+
|
|
92
|
+
Inter, Roboto, Open Sans, Lato, and Merriweather are included in the library, each with regular, semibold, bold, italic, semibold italic, and bold italic faces. Their Google-supplied static TTF files are preserved, with an OFL license and download provenance in each family folder. Their retained bundled revisions contain passing compatibility results and reviewed specimens from the repaired PDF writer, making them available as body and heading defaults. Original font files are unchanged. The renderer patch is maintained with the OpenDoc application; ordinary workspace authoring does not require rebuilding it.
|
|
93
|
+
|
|
94
|
+
The specimen checks ligature words, ordinary mixed styles, and kerning-sensitive boundaries as well as glyphs. Inspect its real PDF appearance and copied text. A successful automated check does not establish suitability for every document. Keep font licensing information with the supplied material and respect it when using or sharing the font.
|
|
95
|
+
|
|
96
|
+
New documents use their generated theme adapter before any template factory runs:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
// documents/my-report/theme.tsx, generated by the create command
|
|
100
|
+
import { theme as base } from '../../themes/neutral';
|
|
101
|
+
import { withDocumentAssets, type DocumentAssets } from 'opendoc/assets';
|
|
102
|
+
import assets from './assets.json';
|
|
103
|
+
export const theme = withDocumentAssets(base, assets as DocumentAssets);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The document entry imports `{ theme }` from `./theme` and passes that same theme to `Document` and its template factory. Do not replace this adapter with a direct base-theme import: that would bypass the saved fonts during template construction. Binding fonts upgrades recognized older theme imports to this adapter while preserving the base theme, aliases, and document text. Custom or ambiguous imports produce an actionable error without replacing source; the agent should integrate the same adapter into the existing factory before retrying.
|
|
107
|
+
|
|
108
|
+
Native semantic body and heading roles receive the saved choices. Theme components that need a family explicitly can call `documentFont('body')` or `documentFont('heading')` from `opendoc` **inside their render function**, then use the returned family in their native PDF style. Do not call this helper at module scope. Deliberate code, caption, label, and furniture families remain intact; explicit authored style overrides remain last.
|
|
109
|
+
|
|
110
|
+
## Theme defaults and document versions
|
|
111
|
+
|
|
112
|
+
The theme detail's **Assets for new documents** section chooses an optional preferred logo, body font, and heading font. **Keep theme font** leaves the theme's own family in place. Defaults live separately from design tokens:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"version": 1,
|
|
117
|
+
"logo": { "id": "acme", "variation": "default" },
|
|
118
|
+
"bodyFont": "acme-sans",
|
|
119
|
+
"headingFont": "acme-sans"
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
This is `themes/<theme-id>/assets.json`. Omit optional properties to clear them; `{ "version": 1 }` means no shared asset defaults. Inspect and update through the same service as the app:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
npx opendoc assets defaults neutral
|
|
127
|
+
npx opendoc assets defaults neutral --metadata /path/to/theme-assets.json --expected-revision <defaults-revision>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The read command returns `{ defaults, revision }`, including a revision for an absent defaults file. The metadata file contains the complete defaults object, not that response wrapper. Preserve defaults the user did not ask to change.
|
|
131
|
+
|
|
132
|
+
Creation resolves these choices once into `documents/<id>/assets.json`. Its version-1 object has optional `logo`, named `logos`, `bodyFont`, and `headingFont` fields. Every selection contains `id` and an exact `revision`; logo selections can also include `variation`. An explicitly empty record is written when no defaults are set. Only asset selections are frozen: the document continues to use its live base theme for color, geometry, and other visual rules.
|
|
133
|
+
|
|
134
|
+
Changing defaults, publishing a replacement, editing guidance, or adding a variation does not update existing documents. Defaults are validated against actual referenced files when saved and when a document is created. Rename, move, duplicate, and Trash restore preserve saved choices. Older documents without a binding file retain their existing rendering until deliberately bound and adapted. The current PDF's rendered asset usage distinguishes what was actually used from what was only available through bindings.
|
|
135
|
+
|
|
136
|
+
Generated `.opendoc/current.json` keeps these concepts separate:
|
|
137
|
+
|
|
138
|
+
- `selectedAsset`: the inspected library family, version, folder, and any selected variation or face.
|
|
139
|
+
- `theme.assetDefaults`: the defaults `file` and `choices`, with `appliesTo: "new-documents"`.
|
|
140
|
+
- `documentAssets`: the binding `file`, exact `bindings`, and `saved`; `saved: false` means a legacy document has no binding file.
|
|
141
|
+
- `renderedAssets`: actual `uses`, the rendered bindings, `renderHash`, and `current`. If `current` is false, usage belongs to the last successful PDF while the current source is rendering or failing.
|
|
142
|
+
|
|
143
|
+
Read error fields before applying replacements. Do not edit generated context by hand. Navigation between library items and documents clears incompatible selections; selecting a family never adds it to a document.
|
|
144
|
+
|
|
145
|
+
Saved PDF receipts retain `assetBindings` for the exact choices available to the exported render and `assets` for the deduplicated logo variations and font faces actually used. These fields come from that render, never from today's library state, and later source or library edits do not rewrite them. Earlier receipts may omit them; omission means usage is unknown, not that the PDF used no assets. Per-block usage remains in the render artifact.
|
|
146
|
+
|
|
147
|
+
## Local records and safe lifecycle
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
assets/logos/<logo-id>/
|
|
151
|
+
asset.json current version and archive state
|
|
152
|
+
revisions/<revision>.json immutable family versions
|
|
153
|
+
files/<content-hash>.png prepared image or PNG original
|
|
154
|
+
files/<content-hash>.svg preserved SVG original
|
|
155
|
+
assets/fonts/<font-id>/
|
|
156
|
+
asset.json
|
|
157
|
+
revisions/<revision>.json
|
|
158
|
+
files/<content-hash>.ttf original font face (or .otf)
|
|
159
|
+
files/<content-hash>.pdf checked PDF specimen
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Family, variation, and face IDs are stable lowercase IDs with single hyphens. Filenames and display names are not identities. Unchanged files are reused across versions. Use the CLI or app to publish changes; never overwrite historical manifests or content-addressed files. Changed historical bytes are detected and must be restored or imported as a new version, rather than silently accepted.
|
|
163
|
+
|
|
164
|
+
Import validation completes before the family is published. Failed imports leave existing families and versions intact. A broken neighboring asset is reported independently rather than hiding the whole library. Prepared artwork, inspections, and specimens are cached; previews load on demand. Rendering watches saved dependencies, so new versions and changed defaults refresh the catalog without rerendering documents that still use earlier versions. Legacy source assets retain conservative dependency tracking.
|
|
165
|
+
|
|
166
|
+
Archive hides an asset from normal selection while preserving its historical files and existing document bindings. The app offers Undo. When a theme uses the asset as a default, the archive flow names those relationships and offers to clear them explicitly. CLI equivalent:
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
npx opendoc assets archive logo acme --expected-revision <current-revision> --clear-defaults
|
|
170
|
+
npx opendoc assets list logo --archived
|
|
171
|
+
npx opendoc assets restore logo acme --expected-revision <current-revision>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Omit `--clear-defaults` unless clearing those defaults is intended; archiving an assigned default otherwise fails. Restoration makes the family selectable again and restores the defaults cleared by that archive only where no later defaults edit would be overwritten. No permanent delete or historical-file cleanup is provided. Documents in Trash and previous PDFs remain usable. A failed current render preserves its last successful preview, and an in-flight export cannot publish against inputs that have changed.
|
|
175
|
+
|
|
176
|
+
Use `--json` for machine-readable command output. Failures print an actionable message to stderr and exit nonzero. Use `npx opendoc assets --help` for asset command syntax or `npx opendoc --help` for the full command list. Read [Media](MEDIA.md) for document-owned visuals and [Themes](THEMES.md) for executable design systems.
|