` +
`For AI agents: Documentation index at ` +
@@ -370,7 +508,7 @@ export default function agentDocs() {
}
logger.info(`Injected agent signaling into ${injected} HTML pages`);
- // 4. Alias sitemap-index.xml → sitemap.xml
+ // 7. Alias sitemap-index.xml → sitemap.xml
// Astro's sitemap integration outputs sitemap-index.xml, but crawlers
// and the agentdocsspec checker expect /sitemap.xml by convention.
const sitemapIndex = path.join(outDir, "sitemap-index.xml");
@@ -379,6 +517,31 @@ export default function agentDocs() {
fs.copyFileSync(sitemapIndex, sitemapAlias);
logger.info("Copied sitemap-index.xml → sitemap.xml");
}
+
+ // 8. Convert og-image.svg → og-image.png
+ // SVG is the source of truth; PNG is what og:image / twitter:image reference
+ // because Twitter/X rejects SVG for social sharing previews.
+ const ogSvgPath = path.join(outDir, "og-image.svg");
+ if (fs.existsSync(ogSvgPath)) {
+ const fontDir = path.resolve("node_modules/@fontsource/inter/files");
+ const fontBuffers = ["400", "500", "600", "700"]
+ .map((w) => {
+ const p = path.join(fontDir, `inter-latin-${w}-normal.woff`);
+ return fs.existsSync(p) ? fs.readFileSync(p) : null;
+ })
+ .filter(Boolean);
+
+ const svg = fs.readFileSync(ogSvgPath, "utf-8");
+ const resvg = new Resvg(svg, {
+ font: fontBuffers.length > 0
+ ? { fontBuffers, loadSystemFonts: false, defaultFontFamily: "Inter", sansSerifFamily: "Inter" }
+ : { loadSystemFonts: true },
+ fitTo: { mode: "original" },
+ });
+ const pngBuffer = resvg.render().asPng();
+ fs.writeFileSync(path.join(outDir, "og-image.png"), pngBuffer);
+ logger.info("Generated og-image.png from og-image.svg");
+ }
},
},
};
diff --git a/docs-site/public/.well-known/ic-domains b/docs-site/public/.well-known/ic-domains
new file mode 100644
index 00000000..d540913d
--- /dev/null
+++ b/docs-site/public/.well-known/ic-domains
@@ -0,0 +1 @@
+cli.internetcomputer.org
diff --git a/docs-site/public/og-image.svg b/docs-site/public/og-image.svg
new file mode 100644
index 00000000..e79026ec
--- /dev/null
+++ b/docs-site/public/og-image.svg
@@ -0,0 +1,81 @@
+
diff --git a/docs-site/src/components/Footer.astro b/docs-site/src/components/Footer.astro
new file mode 100644
index 00000000..7b448a2e
--- /dev/null
+++ b/docs-site/src/components/Footer.astro
@@ -0,0 +1,90 @@
+---
+import EditLink from 'virtual:starlight/components/EditLink';
+import LastUpdated from 'virtual:starlight/components/LastUpdated';
+import Pagination from 'virtual:starlight/components/Pagination';
+import config from 'virtual:starlight/user-config';
+import { Icon } from '@astrojs/starlight/components';
+
+---
+
+
+
+
diff --git a/docs-site/test-version-switcher.sh b/docs-site/test-version-switcher.sh
index f0b33161..0e402a73 100755
--- a/docs-site/test-version-switcher.sh
+++ b/docs-site/test-version-switcher.sh
@@ -19,8 +19,7 @@ cleanup() {
# Set up trap to catch Ctrl+C and other termination signals
trap cleanup SIGINT SIGTERM
-# Configuration - matches production setup
-BASE_PREFIX="/icp-cli"
+# Configuration - matches production setup (versions at domain root)
TEST_DIR="dist-test"
TEST_PORT=4321
@@ -32,17 +31,16 @@ echo ""
# Clean everything for a fresh start
echo "Cleaning all previous builds and caches..."
rm -rf "$TEST_DIR" dist .astro
-mkdir -p "$TEST_DIR$BASE_PREFIX"
+mkdir -p "$TEST_DIR"
# Set common environment variables
export NODE_ENV=production
export PUBLIC_SITE=http://localhost:4321
-export PUBLIC_BASE_PREFIX="$BASE_PREFIX"
# Function to build a version
build_version() {
local version=$1
- local version_path="${BASE_PREFIX}/${version}/"
+ local version_path="/${version}/"
echo ""
echo "Building version $version..."
@@ -70,11 +68,11 @@ build_version() {
echo " Built with BASE_URL: $BUILT_BASE"
# Copy to test directory
- mkdir -p "$TEST_DIR$BASE_PREFIX/$version"
- cp -r dist/* "$TEST_DIR$BASE_PREFIX/$version/"
+ mkdir -p "$TEST_DIR/$version"
+ cp -r dist/* "$TEST_DIR/$version/"
# Verify copy succeeded
- local file_count=$(ls "$TEST_DIR$BASE_PREFIX/$version" | wc -l)
+ local file_count=$(ls "$TEST_DIR/$version" | wc -l)
echo " Copied $file_count files to test directory"
echo "✓ Version $version built successfully"
@@ -88,7 +86,7 @@ build_version "main"
# Generate test versions.json
echo ""
echo "Generating test versions.json..."
-cat > "$TEST_DIR$BASE_PREFIX/versions.json" << 'EOF'
+cat > "$TEST_DIR/versions.json" << 'EOF'
{
"$comment": "Test versions.json for local testing",
"versions": [
@@ -104,24 +102,70 @@ cat > "$TEST_DIR$BASE_PREFIX/versions.json" << 'EOF'
EOF
echo "✓ versions.json created"
+# Determine latest version (mirrors publish-root-files CI logic)
+LATEST_VERSION=$(jq -r ".versions[] | select(.latest == true) | .version" "$TEST_DIR/versions.json")
+if [[ -z "$LATEST_VERSION" ]]; then
+ LATEST_VERSION="main"
+fi
+echo "Latest version: $LATEST_VERSION"
+
# Generate redirect index.html
echo ""
echo "Generating root redirect..."
-cat > "$TEST_DIR$BASE_PREFIX/index.html" << EOF
+cat > "$TEST_DIR/index.html" << EOF
-
+
Redirecting to latest version...
- Redirecting to latest version...
+ Redirecting to latest version...
EOF
echo "✓ index.html created"
+# Copy root-level files from latest version (mirrors publish-root-files CI logic)
+echo ""
+echo "Copying root-level files from $LATEST_VERSION/..."
+for f in llms.txt llms-full.txt feed.xml og-image.png; do
+ if [ -f "$TEST_DIR/$LATEST_VERSION/$f" ]; then
+ cp "$TEST_DIR/$LATEST_VERSION/$f" "$TEST_DIR/$f"
+ echo "✓ Copied $f from $LATEST_VERSION/"
+ else
+ echo "⚠️ $f not found in $LATEST_VERSION/ — skipping"
+ fi
+done
+
+# Generate robots.txt (mirrors publish-root-files CI logic)
+# /main/ is disallowed unless it IS the latest version (no releases yet fallback).
+{
+ echo "User-agent: *"
+ echo "Allow: /${LATEST_VERSION}/"
+ for version in $(jq -r '.versions[].version' "$TEST_DIR/versions.json"); do
+ if [[ "$version" != "$LATEST_VERSION" ]]; then
+ echo "Disallow: /${version}/"
+ fi
+ done
+ if [[ "$LATEST_VERSION" != "main" ]]; then echo "Disallow: /main/"; fi
+ echo ""
+ echo "Sitemap: http://localhost:${TEST_PORT}/sitemap.xml"
+} > "$TEST_DIR/robots.txt"
+echo "✓ robots.txt generated"
+
+# Generate root sitemap.xml (mirrors publish-root-files CI logic)
+{
+ echo ''
+ echo ''
+ echo ' '
+ echo " http://localhost:${TEST_PORT}/${LATEST_VERSION}/sitemap-0.xml"
+ echo ' '
+ echo ''
+} > "$TEST_DIR/sitemap.xml"
+echo "✓ sitemap.xml generated"
+
echo ""
echo "=================================================="
echo "✓ All versions built successfully!"
@@ -130,33 +174,33 @@ echo ""
# Verify the structure
echo "Verifying test structure..."
-echo "Directory: $TEST_DIR$BASE_PREFIX/"
-ls -lah "$TEST_DIR$BASE_PREFIX/"
+echo "Directory: $TEST_DIR/"
+ls -lah "$TEST_DIR/"
echo ""
echo "Checking version subdirectories..."
for version in 0.1 0.2 main; do
echo ""
- if [ -d "$TEST_DIR$BASE_PREFIX/$version" ]; then
+ if [ -d "$TEST_DIR/$version" ]; then
echo "✓ $version/ exists"
- echo " Files: $(ls "$TEST_DIR$BASE_PREFIX/$version" | wc -l)"
+ echo " Files: $(ls "$TEST_DIR/$version" | wc -l)"
- if [ -f "$TEST_DIR$BASE_PREFIX/$version/index.html" ]; then
+ if [ -f "$TEST_DIR/$version/index.html" ]; then
echo " index.html: ✓"
# Check BASE_URL in the built HTML
- BASE_URL_IN_HTML=$(grep -o 'import\.meta\.env\.BASE_URL[^"]*"[^"]*"' "$TEST_DIR$BASE_PREFIX/$version/index.html" | head -1 || echo "not found")
+ BASE_URL_IN_HTML=$(grep -o 'import\.meta\.env\.BASE_URL[^"]*"[^"]*"' "$TEST_DIR/$version/index.html" | head -1 || echo "not found")
echo " BASE_URL in HTML: $BASE_URL_IN_HTML"
# Check if version switcher is present
- if grep -q "version-switcher" "$TEST_DIR$BASE_PREFIX/$version/index.html"; then
+ if grep -q "version-switcher" "$TEST_DIR/$version/index.html"; then
echo " VersionSwitcher: ✓ present"
# Check what's rendered (dev/main badge or button)
- if grep -q "version-button" "$TEST_DIR$BASE_PREFIX/$version/index.html"; then
+ if grep -q "version-button" "$TEST_DIR/$version/index.html"; then
echo " Renders: version button (interactive dropdown)"
- elif grep -q ">main<" "$TEST_DIR$BASE_PREFIX/$version/index.html"; then
+ elif grep -q ">main<" "$TEST_DIR/$version/index.html"; then
echo " Renders: 'main' badge (⚠️ unexpected for $version)"
- elif grep -q ">dev<" "$TEST_DIR$BASE_PREFIX/$version/index.html"; then
+ elif grep -q ">dev<" "$TEST_DIR/$version/index.html"; then
echo " Renders: 'dev' badge (⚠️ unexpected)"
else
echo " Renders: unknown"
@@ -169,8 +213,8 @@ for version in 0.1 0.2 main; do
fi
# Check for assets directory
- if [ -d "$TEST_DIR$BASE_PREFIX/$version/_astro" ]; then
- echo " _astro/ assets: ✓ ($(ls "$TEST_DIR$BASE_PREFIX/$version/_astro" | wc -l) files)"
+ if [ -d "$TEST_DIR/$version/_astro" ]; then
+ echo " _astro/ assets: ✓ ($(ls "$TEST_DIR/$version/_astro" | wc -l) files)"
else
echo " _astro/ assets: ✗ MISSING"
fi
@@ -183,7 +227,7 @@ echo ""
# Start Python HTTP server (most reliable for static files)
if ! command -v python3 &> /dev/null; then
echo "⚠️ Warning: python3 not found. Cannot start server."
- echo "Files are built in: $TEST_DIR$BASE_PREFIX/"
+ echo "Files are built in: $TEST_DIR/"
else
echo "Starting local server with Python..."
echo "Server starting at: http://localhost:${TEST_PORT}"
@@ -191,10 +235,14 @@ else
echo "Press Ctrl+C to stop the server when done testing"
echo ""
echo "Test URLs:"
- echo " - http://localhost:${TEST_PORT}$BASE_PREFIX/ (should redirect to 0.2)"
- echo " - http://localhost:${TEST_PORT}$BASE_PREFIX/0.2/ (version 0.2)"
- echo " - http://localhost:${TEST_PORT}$BASE_PREFIX/0.1/ (version 0.1)"
- echo " - http://localhost:${TEST_PORT}$BASE_PREFIX/main/ (main branch)"
+ echo " - http://localhost:${TEST_PORT}/ (should redirect to $LATEST_VERSION)"
+ echo " - http://localhost:${TEST_PORT}/0.2/ (version 0.2)"
+ echo " - http://localhost:${TEST_PORT}/0.1/ (version 0.1)"
+ echo " - http://localhost:${TEST_PORT}/main/ (main branch)"
+ echo " - http://localhost:${TEST_PORT}/feed.xml (RSS feed, latest version)"
+ echo " - http://localhost:${TEST_PORT}/llms.txt (agent index, latest version)"
+ echo " - http://localhost:${TEST_PORT}/robots.txt (robots, latest version)"
+ echo " - http://localhost:${TEST_PORT}/sitemap.xml (root sitemap index)"
echo ""
echo "Expected behavior:"
echo " ✓ Version 0.2: Button shows 'v0.2', dropdown shows both versions"
diff --git a/docs/reference/cli.md b/docs/reference/cli.md
index ebe00c6f..22562467 100644
--- a/docs/reference/cli.md
+++ b/docs/reference/cli.md
@@ -197,6 +197,7 @@ Make a canister call
- `hex`:
Print raw response as hex
+* `--json` — Output command results as JSON
@@ -241,7 +242,11 @@ Examples:
Default value: `2000000000000`
* `--subnet ` — The subnet to create canisters on
+* `--proxy ` — Principal of a proxy canister to route the create_canister call through.
+
+ When specified, the canister will be created on the same subnet as the proxy canister by forwarding the management canister call through the proxy's `proxy` method.
* `--detached` — Create a canister detached from any project configuration. The canister id will be printed out but not recorded in the project configuration. Not valid if `Canister` is provided
+* `--json` — Output command results as JSON
@@ -261,6 +266,7 @@ Delete a canister from a network
* `-k`, `--root-key ` — The root key to use if connecting to a network by URL. Required when using `--network `
* `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used
* `--identity ` — The user identity to run this command as
+* `--proxy ` — Principal of a proxy canister to route the management canister call through
@@ -283,9 +289,9 @@ Install a built WASM to a canister on a network
Possible values: `auto`, `install`, `reinstall`, `upgrade`
* `--wasm ` — Path to the WASM file to install. Uses the build output if not explicitly provided
-* `--args ` — Inline initialization arguments, interpreted per `--args-format` (Candid by default)
-* `--args-file ` — Path to a file containing initialization arguments
-* `--args-format ` — Format of the initialization arguments
+* `--args ` — Inline arguments, interpreted per `--args-format` (Candid by default)
+* `--args-file ` — Path to a file containing arguments
+* `--args-format ` — Format of the arguments
Default value: `candid`
@@ -302,6 +308,7 @@ Install a built WASM to a canister on a network
* `-k`, `--root-key ` — The root key to use if connecting to a network by URL. Required when using `--network `
* `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used
* `--identity ` — The user identity to run this command as
+* `--proxy ` — Principal of a proxy canister to route the management canister call through
@@ -314,6 +321,7 @@ List the canisters in an environment
###### **Options:**
* `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used
+* `--json` — Output command results as JSON
@@ -341,6 +349,7 @@ Fetch and display canister logs
* `--until ` — Show logs before this timestamp (exclusive). Accepts nanoseconds since Unix epoch or RFC3339 (e.g. '2024-01-01T00:00:00Z'). Cannot be used with --follow
* `--since-index ` — Show logs at or after this log index (inclusive). Cannot be used with --follow
* `--until-index ` — Show logs before this log index (exclusive). Cannot be used with --follow
+* `--json` — Output command results as JSON
@@ -361,6 +370,7 @@ Read a metadata section from a canister
* `-k`, `--root-key ` — The root key to use if connecting to a network by URL. Required when using `--network `
* `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used
* `--identity ` — The user identity to run this command as
+* `--json` — Output command results as JSON
@@ -384,6 +394,7 @@ Migrate a canister ID from one subnet to another
* `-y`, `--yes` — Skip confirmation prompts
* `--resume-watch` — Resume watching an already-initiated migration (skips validation and initiation)
* `--skip-watch` — Exit as soon as the migrated canister is deleted (don't wait for full completion)
+* `--proxy ` — Principal of a proxy canister to route the management canister calls through
@@ -422,6 +433,7 @@ By default this queries the status endpoint of the management canister. If the c
* `-i`, `--id-only` — Only print the canister ids
* `--json` — Format output in json
* `-p`, `--public` — Show the only the public information. Skips trying to get the status from the management canister and looks up public information from the state tree
+* `--proxy ` — Principal of a proxy canister to route the management canister call through
@@ -462,6 +474,7 @@ Change a canister's settings to specified values
* `--set-log-viewer `
* `--add-environment-variable `
* `--remove-environment-variable `
+* `--proxy ` — Principal of a proxy canister to route the management canister calls through
@@ -481,6 +494,7 @@ Synchronize a canister's settings with those defined in the project
* `-k`, `--root-key ` — The root key to use if connecting to a network by URL. Required when using `--network `
* `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used
* `--identity ` — The user identity to run this command as
+* `--proxy ` — Principal of a proxy canister to route the management canister calls through
@@ -518,6 +532,9 @@ Create a snapshot of a canister's state
* `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used
* `--identity ` — The user identity to run this command as
* `--replace ` — Replace an existing snapshot instead of creating a new one. The old snapshot will be deleted once the new one is successfully created
+* `--json` — Output command results as JSON
+* `-q`, `--quiet` — Suppress human-readable output; print only snapshot ID
+* `--proxy ` — Principal of a proxy canister to route the management canister calls through
@@ -538,6 +555,7 @@ Delete a canister snapshot
* `-k`, `--root-key ` — The root key to use if connecting to a network by URL. Required when using `--network `
* `-e`, `--environment ` — Override the environment to connect to. By default, the local environment is used
* `--identity ` — The user identity to run this command as
+* `--proxy ` — Principal of a proxy canister to route the management canister call through
@@ -560,6 +578,7 @@ Download a snapshot to local disk
* `--identity ` — The user identity to run this command as
* `-o`, `--output