andesine 0.0.1-alpha.0 → 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.
Files changed (103) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/LICENSE +1 -1
  3. package/README.md +364 -133
  4. package/dist/cli.js +9108 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/config.schema.json +138 -0
  7. package/dist/templates/pages/.env.example +5 -0
  8. package/dist/templates/pages/AGENTS.md +79 -0
  9. package/dist/templates/pages/LICENSE +21 -0
  10. package/dist/templates/pages/README.md +72 -0
  11. package/dist/templates/pages/andesine.config.ts +39 -0
  12. package/dist/templates/pages/astro.config.ts +23 -0
  13. package/dist/templates/pages/gitignore +13 -0
  14. package/dist/templates/pages/package.template.json +45 -0
  15. package/dist/templates/pages/src/api/openapi.yaml +246 -0
  16. package/dist/templates/pages/src/assets/andesine.svg +1 -0
  17. package/dist/templates/pages/src/assets/andesine.ts +6 -0
  18. package/dist/templates/pages/src/assets/favicon.svg +13 -0
  19. package/dist/templates/pages/src/assets/social-dots.svg +14 -0
  20. package/dist/templates/pages/src/components/content/callout.astro +26 -0
  21. package/dist/templates/pages/src/components/content/card-grid.astro +1 -0
  22. package/dist/templates/pages/src/components/content/card.astro +31 -0
  23. package/dist/templates/pages/src/components/content/code-block.astro +34 -0
  24. package/dist/templates/pages/src/components/content/code-group.astro +13 -0
  25. package/dist/templates/pages/src/components/content/copy-button.tsx +53 -0
  26. package/dist/templates/pages/src/components/content/disclosure.astro +26 -0
  27. package/dist/templates/pages/src/components/content/figure.astro +10 -0
  28. package/dist/templates/pages/src/components/content/file-tree.astro +47 -0
  29. package/dist/templates/pages/src/components/content/index.ts +30 -0
  30. package/dist/templates/pages/src/components/content/steps.astro +16 -0
  31. package/dist/templates/pages/src/components/content/tab.astro +7 -0
  32. package/dist/templates/pages/src/components/content/tabs.astro +15 -0
  33. package/dist/templates/pages/src/components/content/tabs.tsx +99 -0
  34. package/dist/templates/pages/src/components/effects/page-scroll-shadow.tsx +27 -0
  35. package/dist/templates/pages/src/components/effects/page-scrollbar.tsx +35 -0
  36. package/dist/templates/pages/src/components/layout/call-to-action.tsx +28 -0
  37. package/dist/templates/pages/src/components/layout/footer.astro +44 -0
  38. package/dist/templates/pages/src/components/layout/group-label.tsx +34 -0
  39. package/dist/templates/pages/src/components/layout/header.astro +53 -0
  40. package/dist/templates/pages/src/components/layout/mobile-navigation.tsx +51 -0
  41. package/dist/templates/pages/src/components/layout/navigation-links.tsx +57 -0
  42. package/dist/templates/pages/src/components/layout/navigation-tree.tsx +138 -0
  43. package/dist/templates/pages/src/components/layout/outline.tsx +162 -0
  44. package/dist/templates/pages/src/components/layout/page-actions.tsx +87 -0
  45. package/dist/templates/pages/src/components/layout/powered-by.tsx +29 -0
  46. package/dist/templates/pages/src/components/layout/section-tabs.tsx +83 -0
  47. package/dist/templates/pages/src/components/layout/sidebar.tsx +65 -0
  48. package/dist/templates/pages/src/components/primitives/button.tsx +121 -0
  49. package/dist/templates/pages/src/components/primitives/card.tsx +25 -0
  50. package/dist/templates/pages/src/components/primitives/dialog.tsx +47 -0
  51. package/dist/templates/pages/src/components/primitives/input.tsx +22 -0
  52. package/dist/templates/pages/src/components/primitives/logo.tsx +41 -0
  53. package/dist/templates/pages/src/components/primitives/menu.tsx +121 -0
  54. package/dist/templates/pages/src/components/primitives/scroll-area.tsx +103 -0
  55. package/dist/templates/pages/src/components/primitives/shortcut.tsx +60 -0
  56. package/dist/templates/pages/src/components/primitives/tooltip.tsx +39 -0
  57. package/dist/templates/pages/src/components/reference/facts.astro +27 -0
  58. package/dist/templates/pages/src/components/reference/fields.astro +102 -0
  59. package/dist/templates/pages/src/components/reference/method-badge.astro +18 -0
  60. package/dist/templates/pages/src/components/reference/methods.ts +17 -0
  61. package/dist/templates/pages/src/components/reference/operation.astro +252 -0
  62. package/dist/templates/pages/src/components/reference/styles.ts +14 -0
  63. package/dist/templates/pages/src/components/search/highlighted-text.tsx +22 -0
  64. package/dist/templates/pages/src/components/search/search-answer.tsx +123 -0
  65. package/dist/templates/pages/src/components/search/search-palette.tsx +174 -0
  66. package/dist/templates/pages/src/components/search/search-results.tsx +229 -0
  67. package/dist/templates/pages/src/components/social/card.ts +77 -0
  68. package/dist/templates/pages/src/content/docs/customization/index.mdx +11 -0
  69. package/dist/templates/pages/src/content/docs/customization/styles.mdx +18 -0
  70. package/dist/templates/pages/src/content/docs/getting-started/api-reference.mdx +100 -0
  71. package/dist/templates/pages/src/content/docs/getting-started/components.mdx +156 -0
  72. package/dist/templates/pages/src/content/docs/getting-started/configuration.mdx +194 -0
  73. package/dist/templates/pages/src/content/docs/getting-started/deployment.mdx +142 -0
  74. package/dist/templates/pages/src/content/docs/getting-started/index.mdx +22 -0
  75. package/dist/templates/pages/src/content/docs/getting-started/writing-pages.mdx +35 -0
  76. package/dist/templates/pages/src/content/docs/index.mdx +21 -0
  77. package/dist/templates/pages/src/content.config.ts +1 -0
  78. package/dist/templates/pages/src/layouts/page.astro +195 -0
  79. package/dist/templates/pages/src/styles/global.css +95 -0
  80. package/dist/templates/pages/tsconfig.json +10 -0
  81. package/dist/templates/pages/uno.config.ts +168 -0
  82. package/package.json +53 -61
  83. package/dist/api.cjs +0 -1
  84. package/dist/api.d.cts +0 -22
  85. package/dist/api.d.mts +0 -22
  86. package/dist/api.d.ts +0 -22
  87. package/dist/api.mjs +0 -1
  88. package/dist/extensions.cjs +0 -1
  89. package/dist/extensions.d.cts +0 -351
  90. package/dist/extensions.d.mts +0 -351
  91. package/dist/extensions.d.ts +0 -351
  92. package/dist/extensions.mjs +0 -1
  93. package/dist/shared/andesine.3cb4e565.d.cts +0 -458
  94. package/dist/shared/andesine.5e4b2db8.d.cts +0 -201
  95. package/dist/shared/andesine.5e4b2db8.d.mts +0 -201
  96. package/dist/shared/andesine.5e4b2db8.d.ts +0 -201
  97. package/dist/shared/andesine.bcb7a57d.d.ts +0 -458
  98. package/dist/shared/andesine.e974d2fa.d.mts +0 -458
  99. package/dist/transformers.cjs +0 -31
  100. package/dist/transformers.d.cts +0 -231
  101. package/dist/transformers.d.mts +0 -231
  102. package/dist/transformers.d.ts +0 -231
  103. package/dist/transformers.mjs +0 -31
package/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ ## 0.4.0
4
+
5
+ - Add `andesine pages init [directory]`, which creates an Andesine Pages site from
6
+ the template of the same release in a new or empty directory (default `docs`).
7
+ - Depend on `@andesine/sdk` 0.4.0. Align the version with the other Andesine
8
+ packages.
9
+
10
+ ## 0.3.0
11
+
12
+ - Add generated webhook commands for management (including bulk enable/disable and
13
+ delete), delivery history, signed tests, and single or bulk replay.
14
+
15
+ ## 0.2.0
16
+
17
+ - Add slug-path API flags, collection selection, and generated type bindings.
18
+
19
+ ## 0.1.0
20
+
21
+ - Add `types generate`, read-only `--check`, foreground `--watch`, atomic output
22
+ replacement, and optional first generation through `init --generate`.
23
+ - Add the pure content type generator with workspace maps, collection/revision
24
+ types, property and fragment constraints, and optional entry/tree declarations.
25
+ - Expose current and published type metadata through generated API commands.
26
+ - Add generated public API commands with SDK transport, JSON/file input, binary
27
+ output, snapshot-aware pagination, SSE output, and shared CLI progress visuals.
28
+ - Add guided and non-interactive project initialization with public API validation,
29
+ configuration previews, and safe updates to existing files.
30
+ - Add the CLI foundation, project configuration, and package build.
31
+ - Add device login, online authentication status, logout, OS credential storage,
32
+ explicit private-file storage, and coordinated OAuth refresh.
33
+ - Add formatted authentication panels and progress spinners, with plain output
34
+ for non-interactive use and unchanged JSON results on stdout.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Vrite, Inc.
3
+ Copyright (c) 2026 Vrite, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,163 +1,394 @@
1
- # Vrite JavaScript SDK
1
+ # Andesine CLI
2
2
 
3
- [Vrite JavaScript SDK](https://github.com/vriteio/vrite/tree/main/packages/sdk) is a one-stop-shop when building any kind of Vrite-powered website or web app.
3
+ MIT-licensed command-line tools for Andesine. Requires Node.js 22.12 or later.
4
4
 
5
- Currently it includes the following parts:
6
-
7
- - **API client** — for easy access to Vrite API;
8
- - **Content transformers** — functions used to transform Vrite JSON content into different formats;
9
- - **Astro integration** — dedicated integration for [Astro](<%5Bhttps://astro.build/%5D(https://astro.build/)>);
10
- - **Extensions SDK** - for building custom extensions for Vrite;
11
-
12
- ## Installation
13
-
14
- ```shell
15
- npm i @vrite/sdk
5
+ ```sh
6
+ npm install --save-dev andesine @andesine/sdk
7
+ npx andesine init
16
8
  ```
17
9
 
18
- ## Usage
10
+ Use `npm install --global andesine` for a system-wide executable. The CLI depends
11
+ on an exact SDK release. Keep `@andesine/sdk` as a direct project dependency when
12
+ application code imports the generated types or creates a client. Optional native
13
+ credential bindings are only loaded for OS-store authentication; API keys and
14
+ explicit file storage also work when those bindings are omitted.
19
15
 
20
- The Vrite SDK is modular, so you can import only the parts of it you need. On top of that, it's **isomorphic**, with both the API client and content transformers library being able to run both in the browser and Node.js.
16
+ This package is under development. Help, configuration, OAuth authentication,
17
+ project initialization, public API commands, and content type generation are implemented.
21
18
 
22
- ### API client
19
+ ```sh
20
+ andesine --help
21
+ andesine --version
22
+ ```
23
23
 
24
- Start by initializing the API client, by importing the library, and providing your API access token:
24
+ ## Documentation sites
25
25
 
26
- ```javascript
27
- import { createClient } from "@vrite/sdk/api";
28
- const vrite = createClient({
29
- token: "[YOUR_API_TOKEN]"
30
- });
26
+ ```sh
27
+ npx andesine pages init docs
31
28
  ```
32
29
 
33
- With the client configured, you can access [all the endpoints of the Vrite API](https://generator.swagger.io/?url=https://api.vrite.io/swagger.json) via convenient JavaScript methods. Here are a few examples:
34
-
35
- ```javascript
36
- // Get all content groups
37
- const contentGroups = await vrite.contentGroups.list();
38
- // Get all content pieces from a content group
39
- const contentPieces = await vrite.contentPieces.list({
40
- contentGroupId: "[CONTENT_GROUP_ID]"
41
- });
42
- // Get the entire conten piece with JSON content
43
- const contentPiece = await vrite.contentPieces.get({
44
- id: "[CONTENT_PIECE_ID]",
45
- content: true
46
- });
30
+ Creates an Andesine Pages site in a new or empty directory (default `docs`) from the
31
+ template of this CLI release, with `@andesine/pages` and `@andesine/ui` pinned to the
32
+ same version. Then run `npm install` and `npm run dev` in the directory. The command
33
+ needs no credentials.
34
+
35
+ ## Project configuration
36
+
37
+ Run `andesine init` for guided setup. It uses Clack prompts and progress indicators
38
+ to select a workspace, current or published content, collections, and a generated
39
+ types path. If credentials are missing, it offers browser login. API keys use their
40
+ own workspace; OAuth users select from their accessible workspaces.
41
+
42
+ ```sh
43
+ andesine init
44
+ andesine init --config ./config/andesine.json
45
+ andesine init --no-interactive --workspace ws_example \
46
+ --source published --channel published \
47
+ --collection /Docs coll_example/Guides --output src/content.generated.ts
48
+ andesine init --no-interactive --source current --all-collections --yes
47
49
  ```
48
50
 
49
- To explore available endpoints, check out [Vrite API docs](https://generator.swagger.io/?url=https://api.vrite.io/swagger.json). On top of that, the API client is **fully typed** (written in TypeScript) so you can easily find your way using your modern code editor's autocomplete functionality.
50
-
51
- ### Content transformers
52
-
53
- **Content transformers** are functions dedicated to processing Vrite JSON output and adapting it to required string-based formats.
54
-
55
- The JSON output, based on the [ProseMirror](https://prosemirror.net/) library powering the Vrite Editor, is very versatile and easy to process, making it the ideal choice, no matter how your content has to be delivered. Content transformers help with this process by further simplifying the processing of these recursive JSON trees to output strings.
56
-
57
- ```javascript
58
- import { createContentTransformer, gfmTransformer, htmlTransformer } from "@vrite/sdk/transformers";
59
-
60
- const sampleVriteJSON = {
61
- // ...
62
- };
63
- // Transforms JSON to GitHub Flavored Markdown format
64
- const gfmOutput = gfmTransformer(sampleVriteJSON);
65
- // Transforms JSON to HTML format
66
- const htmlOutput = htmlTransformer(sampleVriteJSON);
67
- // Create your own content transformers
68
- const customContentTransformer = createContentTransformer({
69
- applyInlineFormatting(type, attrs, content) {
70
- switch (type) {
71
- case "link":
72
- return `<a href="${attrs.href}">${content}</a>`;
73
- case "bold":
74
- return `<strong>${content}</strong>`;
75
- case "code":
76
- return `<code>${content}</code>`;
77
- case "italic":
78
- return `<em>${content}</em>`;
79
- default:
80
- return content;
81
- }
82
- },
83
- transformNode(type, attrs, content) {
84
- switch (type) {
85
- case "paragraph":
86
- return `<p>${content}</p>`;
87
- case "heading":
88
- return `<h${attrs?.level || 1}>${content}</h${attrs?.level || 1}>`;
89
- case "blockquote":
90
- return `<blockquote>${content}</blockquote>`;
91
- case "bulletList":
92
- return `<ul>${content}</ul>`;
93
- case "orderedList":
94
- return `<ol>${content}</ol>`;
95
- case "listItem":
96
- return `<li>${content}</li>`;
97
- case "horizontalRule":
98
- return `<hr/>`;
99
- default:
100
- return content;
101
- }
51
+ Non-interactive setup requires a saved login or `ANDESINE_API_KEY`. Supply
52
+ `--workspace` when the OAuth account has multiple workspaces and no configured
53
+ selection. Defaults are the `published` channel, all accessible collections, and
54
+ `src/andesine.generated.ts`; existing configuration values are retained unless
55
+ changed by flags. `--snapshot snp_…` selects a fixed snapshot instead of a channel.
56
+ Use `--include-entry-ids`, `--include-entry-paths`, and `--include-tree` to opt into
57
+ additional types, or their `--no-…` forms to remove existing selections.
58
+
59
+ The collection picker offers IDs for rename stability, name paths, and slug paths.
60
+ `--collection` accepts one or more IDs or decoded paths, including collection-ID
61
+ anchors. Use `--collection-slug-path /docs` for derived URL paths; it can be
62
+ combined with `--collection`. The API validates them against the selected source. `--all-collections`
63
+ clears an existing selection. Empty collection selections mean all accessible
64
+ collections, including collections added later.
65
+
66
+ Setup shows changes before saving. An existing configuration requires confirmation
67
+ or `--yes`; non-interactive updates require `--yes`. Unchanged configurations are
68
+ not rewritten. A file changed during setup is rejected. Only the selected JSON
69
+ configuration is written; tokens stay in user credential storage. After saving,
70
+ interactive setup offers first generation. Use `--generate` to request it directly
71
+ or `--no-generate` to skip it. Non-interactive setup generates only with `--generate`;
72
+ `--yes` alone does not enable generation. Initialization does not install packages.
73
+ If generation fails, the saved configuration and last successful types file remain.
74
+
75
+ Commands use the nearest `andesine.json`, searching from the working directory up
76
+ to the filesystem root. `--config <file>` or `ANDESINE_CONFIG` selects an explicit
77
+ file instead. Explicit files must exist except when `init` creates them. Help and version do not load any config.
78
+ Configuration is JSON only; the CLI does not load `.env` files or execute config.
79
+
80
+ ```json
81
+ {
82
+ "$schema": "./node_modules/andesine/dist/config.schema.json",
83
+ "version": 1,
84
+ "baseURL": "https://api.andesine.app",
85
+ "workspaceID": "ws_example",
86
+ "types": {
87
+ "source": { "kind": "published", "channel": "published" },
88
+ "collections": ["/Tutorials"],
89
+ "output": "src/andesine.generated.ts",
90
+ "includeEntryIDs": false,
91
+ "includeEntryPaths": false,
92
+ "includeTree": false
102
93
  }
103
- });
94
+ }
104
95
  ```
105
96
 
106
- The SDK provides built-in content transformers for both HTML and GFM formats.
97
+ The JSON Schema ships at `dist/config.schema.json` and is also exported as
98
+ `andesine/config.schema.json`. Unknown configuration fields are rejected.
99
+ Keep credentials out of this file.
107
100
 
108
- ### Astro integration
101
+ Values use this precedence: flags, environment, project configuration, selected
102
+ user profile, then defaults. Supported global overrides:
109
103
 
110
- Vrite Astro integration makes integrating Vrite with your Astro-powered website really easy!
104
+ | Flag | Environment variable | Project field |
105
+ | ------------- | ----------------------- | ------------- |
106
+ | `--config` | `ANDESINE_CONFIG` | — |
107
+ | `--base-url` | `ANDESINE_BASE_URL` | `baseURL` |
108
+ | `--workspace` | `ANDESINE_WORKSPACE_ID` | `workspaceID` |
109
+ | `--profile` | `ANDESINE_PROFILE` | `profile` |
111
110
 
112
- Start by adding the Vrite plugin into the Astro config:
111
+ The default API root is `https://api.andesine.app`. Self-hosted roots can include
112
+ a deployment prefix. Credentials, query strings, and fragments in the URL are
113
+ rejected. Trailing slashes are removed.
113
114
 
114
- ```javascript
115
- import { defineConfig } from "astro/config";
116
- import { vritePlugin } from "@vrite/sdk/astro";
117
- export default defineConfig({
118
- integrations: [
119
- // ...
120
- vritePlugin({
121
- accessToken: "[YOUR_ACCESS_TOKEN]",
122
- contentGroupId: "[CONTENT_GROUP_ID]"
123
- })
124
- // ...
125
- ]
126
- });
127
- ```
115
+ The default type source is the `published` channel. Use
116
+ `{ "kind": "published", "snapshotID": "snp_example" }` for a fixed snapshot, or
117
+ `{ "kind": "current" }` for current schemas. Channel and snapshot are exclusive.
118
+ Collection selectors are IDs, name paths, or `{ "collectionSlugPath": "/docs" }`
119
+ objects, resolved by the API in the generation
120
+ step. An omitted or empty collection list selects all accessible collections.
121
+ Entry IDs, entry paths, and tree types are off by default.
122
+
123
+ Output defaults to `src/andesine.generated.ts`. Relative output paths resolve
124
+ against the configuration directory, or the working directory if no config
125
+ exists. No files are generated during package installation or import.
128
126
 
129
- In the configuration provide both your **API access token**, as well as the **ID of the content group** containing the posts for publishing on your Astro-powered website.
127
+ ## User profiles
130
128
 
131
- If you're using **TypeScript**, add the following to your _tsconfig.json_, under `compilerOptions.types`:
129
+ User metadata lives in `andesine/profiles.json` under `XDG_CONFIG_HOME`, or under
130
+ the platform default: `~/Library/Application Support` on macOS, `%APPDATA%` on
131
+ Windows, and `~/.config` on Linux. Override directories must be absolute paths.
132
132
 
133
133
  ```json
134
- { "compilerOptions": { "types": ["@vrite/sdk/types"] } }
134
+ {
135
+ "version": 1,
136
+ "defaultProfile": "local",
137
+ "profiles": {
138
+ "local": {
139
+ "baseURL": "http://localhost:3000",
140
+ "workspaceID": "ws_example"
141
+ }
142
+ }
143
+ }
135
144
  ```
136
145
 
137
- Now you can import from a `virtual:vrite` module that provides configured API client, along with a few utils for integrating Vrite with Astro:
138
-
139
- ```astro
140
- ---
141
- import { Content, client, getContentPieces, getStaticPaths } from "virtual:vrite";
146
+ Profiles can also contain `accountID` and an opaque `credentialRef`. Tokens live
147
+ in the selected credential store, never in this metadata file. A profile's workspace and credential reference
148
+ are used only when its normalized API root matches the resolved instance,
149
+ including its deployment prefix. Missing selected profiles are errors except during `auth login`, which can create
150
+ the named profile. The first login uses `default` if no profile is selected and
151
+ sets the first saved profile as the default. A profile cannot be replaced by a
152
+ login to a different instance; supply a new `--profile` name instead.
153
+
154
+ ## Authentication
155
+
156
+ ```sh
157
+ andesine auth login
158
+ andesine --profile work auth login
159
+ andesine --base-url https://api.example.com auth login --no-browser
160
+ andesine auth login --credential-store file --no-browser --no-interactive
161
+ andesine auth status
162
+ andesine auth logout
163
+ ```
142
164
 
143
- // Pre-configured Vrite API client
144
- const settings = await client.userSettings.get();
145
- // Utility to retrieve content pieces from the configured content group
146
- const contentPieces = await getContentPieces();
147
- // Shortcut for retriving all content pieces for use with Astro SSG
148
- export getStaticPaths;
149
- ---
165
+ Login displays the instance, browser URL, and user code on stderr. The browser
166
+ shows the account and asks you to approve or deny access. `--no-browser` keeps the same
167
+ flow but leaves opening the URL to you. The CLI polls until approval, denial,
168
+ expiry, or cancellation. Ctrl+C stops polling. No callback server is started.
169
+
170
+ In a terminal, authentication commands use formatted panels, status icons, and
171
+ progress spinners. Login shows the browser URL and code while it waits for approval.
172
+ Progress stops on success, failure, or cancellation. CI, redirected stderr,
173
+ `TERM=dumb`, and `--no-interactive` use plain text without animation. Colors respect
174
+ `NO_COLOR`. JSON results on stdout remain unchanged.
175
+
176
+ The default store is the OS credential store: macOS Keychain, Windows Credential
177
+ Manager, or Linux Secret Service. Linux requires a running Secret Service; the CLI
178
+ does not silently use the nonpersistent kernel keyring. Native bindings are optional
179
+ and loaded only when needed. No install script downloads credentials or generates
180
+ project files.
181
+
182
+ If the OS store is unavailable, interactive login offers **unencrypted file
183
+ storage** with an explicit confirmation. `--credential-store file` selects that
184
+ option directly, including in non-interactive sessions. Credentials are stored in
185
+ `andesine/credentials` beside `profiles.json`. POSIX directories use `0700` and
186
+ files use `0600`. Windows directories use a protected ACL for the current user,
187
+ with inheritance for new files; PowerShell is required to establish that ACL.
188
+ File writes use a temporary file and atomic replacement. Do not put the user
189
+ configuration directory inside a shared or committed project.
190
+
191
+ `auth status` verifies the credential online and emits JSON with its source,
192
+ instance, account (or API-key ID), selected profile, and workspace ID. A missing,
193
+ expired, or rejected credential fails with a nonzero exit code. OAuth refresh
194
+ occurs when the access token has less than one minute left. Concurrent processes
195
+ serialize refreshes. An interrupted or uncertain exchange requires a new login;
196
+ the CLI never retries a refresh token that might already have been rotated. API
197
+ requests are not replayed to recover authentication.
198
+
199
+ `ANDESINE_API_KEY` takes precedence over saved OAuth credentials for API requests
200
+ and `auth status`. An empty or rejected key does not fall back to OAuth. Login and
201
+ logout still manage the selected saved profile and do not change the environment.
202
+ No credential is used for a different API root, including a different deployment
203
+ prefix. HTTP redirects are not followed for authenticated requests.
204
+
205
+ Login and status emit metadata only on stdout. Tokens are never printed. API
206
+ commands use the same SDK authentication helper.
207
+
208
+ Logout revokes the latest known refresh token and removes local credentials.
209
+ Its JSON result reports `localRemoved` and `revocation` separately. If remote
210
+ revocation cannot be confirmed, local removal still occurs and the command exits
211
+ with an error. Browser sessions are not signed out. Older access tokens may remain
212
+ valid for up to 15 minutes. Provider refresh-token reuse can invalidate other CLI
213
+ logins for the same user/client; complete per-device revocation is deferred.
214
+
215
+ ## Public API commands
216
+
217
+ `andesine api <resource> <operation>` exposes the public API through the SDK.
218
+ Names use kebab-case: `content.getTree` becomes `api content get-tree`.
219
+ Each operation has `--help` with its fields, description, authentication, and
220
+ example input. `--schema` prints its bundled input JSON Schema. Both work offline
221
+ without loading project configuration or credentials.
222
+
223
+ After OAuth login, run `andesine init` to save a workspace for this project, or
224
+ select one for a command with `--workspace <id>`. Login alone does not select a
225
+ workspace. Use `andesine api workspaces list` to find the available IDs; that
226
+ command does not require a workspace. Workspace operations report a configuration
227
+ error before sending the API request if no workspace is selected.
228
+
229
+ ```sh
230
+ andesine api --help
231
+ andesine api content get-tree --help
232
+ andesine api entries create --schema
233
+ andesine api content get-tree --channel published
234
+ andesine api content get --slug-path /docs/introduction --channel published --full
235
+ andesine api content list-entries --channel published --paginate
236
+ andesine api search published --input @search.json --semantic false
237
+ andesine api search ask-published-stream --input @question.json --format text
238
+ andesine api assets upload --asset-id ast_example --file ./image.png
239
+ andesine api type-metadata get-published --collections '["/Tutorials"]'
240
+ andesine api webhooks list
241
+ andesine api webhooks send-test --help
242
+ ```
150
243
 
151
- <!-- Renders the Vrite content piece, specified by ID or slug -->
152
- <content contentPieceId="..." slug="..." />
244
+ Pass simple values as flags, or supply an API input object through `--input @file`
245
+ or `--input -` for stdin. JSON uses API field names, such as `collectionID`; flags
246
+ use `--collection-id`. Flags replace matching JSON fields. Boolean flags require
247
+ `true` or `false`; arrays and objects require JSON. Nullable fields accept `null`.
248
+ Use `--help` for required inputs. File fields accept a path or `-` for stdin;
249
+ stdin can supply either the JSON object or one file per command.
250
+
251
+ Normal responses are one JSON value per line. `--full` includes HTTP status,
252
+ headers, and data, for example to retrieve an ETag. Endpoints with conditional
253
+ reads accept `--if-none-match`; unchanged content emits a `notModified` result.
254
+ Empty responses emit no stdout unless `--full` is selected. Binary responses
255
+ require `--output <new-file>` or `--output -` for raw bytes; existing files are
256
+ never replaced.
257
+
258
+ `--paginate` emits one complete page per line, including pagination and snapshot
259
+ metadata. Published content retains the first page's snapshot. To resume published
260
+ pagination, provide both `--cursor` and `--snapshot-id` from the same result.
261
+ `--full` and conditional reads cannot be combined with `--paginate`.
262
+
263
+ AI streams emit NDJSON events by default. `--format text` emits answer text as it
264
+ arrives. A failed or incomplete stream keeps the output already emitted, reports
265
+ the error on stderr, and exits with a failure code.
266
+
267
+ Requests use a 30-second timeout; `--timeout <ms>` changes it and `--timeout 0`
268
+ disables it. Ctrl+C cancels the request. Retries are disabled, including for writes
269
+ and AI calls. Writes execute directly. Use the operation's documented expected
270
+ revision or snapshot fields when it supports change checks.
271
+
272
+ Commands use the configured API root and credentials. OAuth workspace selection
273
+ uses `--workspace`; API keys remain bound to their workspace. OAuth-only operations
274
+ require a saved login with `ANDESINE_API_KEY` unset. Anonymous asset reads do not
275
+ send credentials. Public API errors retain their code, details, hints, and request
276
+ ID on stderr when available.
277
+
278
+ In a terminal, commands use the shared Clack headings, request spinners, and status
279
+ messages on stderr. Redirected output and non-interactive use keep plain diagnostics
280
+ and machine-readable stdout. Command definitions are bundled with the package;
281
+ the CLI does not download executable definitions from the server.
282
+
283
+ `api type-metadata get-current` and `get-published` return collection/schema
284
+ metadata for type generation. Use `--include-entries true` or `--include-tree true`
285
+ for optional entry and ordered tree data. Published metadata retains its snapshot
286
+ and recorded schema revisions; collections with no recorded schema use a general
287
+ type without warnings. These API commands return metadata only; use
288
+ `andesine types generate` to write TypeScript files.
289
+
290
+ ## Content type generator
291
+
292
+ ```sh
293
+ andesine types generate
294
+ andesine types generate --check
295
+ andesine types generate --watch
296
+ andesine types generate --source current --collection-slug-path /tutorials
297
+ andesine types generate --snapshot snp_example --include-entry-paths
298
+ andesine init --generate
153
299
  ```
154
300
 
155
- - `Content` — renders Vrite content piece specified either by ID (`contentPieceId` prop) or a slug (`slug` prop); Useful when in SSR mode;
156
- - `client` — pre-configured Vrite API client for easy access;
157
- - `getContentPieces` — retrieves content pieces from the content group specified in the config file. Accepts an object with the following properties:
158
- - `limit?: number | "all" = 50` — how many content pieces to retrieve; `"all"` retrieves all of them, in batches of 50;
159
- - `startPage?: number = 1` — if `limit` is a number and pagination is used, what page to start retrieving content pieces from?
160
- - `tagId?: string` — Tag ID, if you want to filter results by specific tag.
161
- - `getStaticPaths` — shortcut function for easy re-export when using Vrite SSG and inside _[slug].astro_ file. It returns `params.slug` as the content piece's slug and all basic content piece properties as `props`.
301
+ Generation reads public metadata for the configured source and writes the configured
302
+ TypeScript file. Flags override saved settings without changing `andesine.json`.
303
+ Use the same source, collection, output, and optional-type flags as `init`.
304
+ OAuth requires a selected workspace; an API key uses its workspace binding.
305
+ Output paths are relative to the configuration directory, or the working directory
306
+ without configuration. Supported extensions are `.ts`, `.mts`, and `.cts`, including
307
+ declaration files such as `.d.ts`.
308
+
309
+ Writes are atomic. Identical output is not rewritten. An unrelated file requires
310
+ explicit `--force`; links and non-regular files are rejected. A file changed during
311
+ generation is preserved. Metadata, access, and generation failures leave the last
312
+ successful output intact.
313
+
314
+ Commit the generated file and run `andesine types generate --check` in CI, with
315
+ `ANDESINE_API_KEY` available as a secret. Check mode makes no types-file writes and
316
+ returns exit code `3` for missing or stale output. Request and generation failures
317
+ return `1`; invalid options/configuration return `2`. A channel or current source is
318
+ checked against live metadata. Pin `--snapshot` for a fixed source while that
319
+ snapshot is retained. Authentication failures are never reported as stale output.
320
+
321
+ Watch runs in the foreground, polling every 10 seconds. `--interval <seconds>`
322
+ accepts 1–300 seconds. It holds the resolved configuration fixed; restart after
323
+ config changes. Polls do not overlap. Metadata fingerprints avoid repeated type
324
+ generation, and identical files stay untouched. Local deletion or changes to a
325
+ marked generated file are corrected on the next successful poll. `--force` only
326
+ authorizes unrelated-file replacement until the first successful generation.
327
+
328
+ Transient metadata read failures, rate limits, and schema migrations retry with
329
+ backoff, respecting `Retry-After`. Other failures stop the command. Watch refreshes
330
+ OAuth credentials between polls and preserves the last output during failures.
331
+ Press Ctrl+C to stop (exit `130`). There is no daemon or install-time generation.
332
+ `--check` cannot be combined with `--watch` or `--force`.
333
+
334
+ Commands print JSON results on stdout and use Clack progress/status on stderr.
335
+ Watch prints its initial result, changed output, and recovery; unchanged polls stay
336
+ quiet. The pure generator remains separate in `src/types/generate.ts`, with no
337
+ network, credential, or filesystem access.
338
+
339
+ Generated files export `Workspace` for `createClient<Workspace>()`, plus types
340
+ such as `TutorialsCollection`, `TutorialsCollectionContent`, and
341
+ `TutorialsCollectionStructuredContent`. Each recorded revision has a named schema
342
+ and content type. Names use stable suffixes when collection names conflict after
343
+ conversion to TypeScript identifiers. Field keys keep the API's derived spelling.
344
+
345
+ All declared schema fields are required. Numbers use `number | null`, selects
346
+ include `""`, and multi-selects use arrays of allowed values. Fragment types narrow
347
+ allowed block kinds. Custom element names and properties remain general because
348
+ schemas do not define them. Defaults are not treated as value constraints.
349
+ Empty and schema-free collections use general content types without warnings.
350
+
351
+ `--include-entry-paths` emits both name-path and slug-path bindings, plus named
352
+ `EntryPath` and `EntrySlugPath` unions. Collection and tree bindings include slug
353
+ paths automatically.
354
+
355
+ Entry ID bindings, entry path bindings, and ordered tree types are separate
356
+ opt-ins. Tree exports include their entry identities. Published trees narrow
357
+ `content.getTree()`; current trees describe the metadata's child-ID lists only.
358
+ The SDK generic changes types only: callers must configure the matching workspace
359
+ and source. Channel generation omits changing snapshot IDs and expiry; explicit
360
+ snapshot generation records the configured snapshot. Output contains no executable
361
+ values, content bodies, or timestamps.
362
+
363
+ ## Command conventions
364
+
365
+ - Command data uses stdout. JSON responses use one JSON value per line; streamed
366
+ events use NDJSON. Text output preserves the supplied text.
367
+ - Diagnostics and Clack prompts use stderr. Prompts require a terminal for stdin
368
+ and stderr, are disabled in CI, and can be disabled with `--no-interactive`.
369
+ - Exit codes: `0` success, `1` runtime failure, `2` usage/configuration error,
370
+ `3` stale generated types, `130` cancellation.
371
+ - API retries are disabled.
372
+
373
+ ## Development
374
+
375
+ ```sh
376
+ pnpm exec turbo run typecheck --filter=andesine
377
+ pnpm api:generate
378
+ pnpm build --filter=andesine
379
+ node packages/public/cli/dist/cli.js --help
380
+ ```
162
381
 
163
- For a more detailed guide on using the Vrite Astro integration, [check out this blog post](https://vrite.io/blog/start-programming-blog-in-minutes-with-astro-and-vrite/).
382
+ `src/program.ts` owns command registration. Actions create a shared context
383
+ through `src/context.ts`; help does not create that context. Custom commands own
384
+ their logic. The `api` group uses metadata generated at build time from the
385
+ SDK OpenAPI artifact. It executes through the SDK, with no backend modules
386
+ or remotely downloaded executable command definitions at runtime.
387
+
388
+ The Rolldown build emits the executable and creates the JSON Schema from the same
389
+ Zod definition used to validate configuration. It also regenerates API metadata
390
+ and typed SDK bindings. Commit those generated sources with spec changes.
391
+ `prepack` builds the package, checks types, and runs Publint. The public-package
392
+ workflows check and publish the CLI archive after its exact SDK release is available.
393
+ See the [release guide](https://github.com/vriteio/andesine/blob/andesine/packages/public/README.md) and [release review](https://github.com/vriteio/andesine/blob/andesine/packages/public/CLI-RELEASE-REVIEW.md)
394
+ for rollout order and checks that still need browser or platform access.