Skip to content

Shortcuts

Shortcuts are named references that give stable, short identifiers to URIs. They follow CommonMark’s reference link pattern with an @ prefix.


Defines a shortcut in a single line:

[@id Label](url)
  • @id — the shortcut identifier
  • Label — human-readable display text
  • url — the topic URI

This is syntactic sugar. String decomposes it into a reference link and a reference definition internally.

Separates the display from the definition, following CommonMark’s reference link syntax:

[Label][@id]
[@id]: url

The reference definition ([@id]: url) MAY be placed anywhere in the document — typically grouped at the bottom.

# Inline form
[@docs Documentation](https://docs.example.com)
# Reference form — same result
[Documentation][@docs]
[@docs]: https://docs.example.com

The inline form is recommended for convenience. The reference form is useful when the same shortcut is referenced multiple times or when URLs are long and would clutter the content.


Regardless of which form the author uses, String always presents shortcuts to the AI as reference links:

Author writes (inline):

Visit the [@docs Documentation](https://docs.example.com) for details.

Author writes (reference):

Visit the [Documentation][@docs] for details.
[@docs]: https://docs.example.com

AI sees (both cases):

Visit the [Documentation][@docs] for details.

The URL never enters the AI’s context. The AI navigates with /open @docs. String resolves the actual URI.

In a standard CommonMark viewer, the inline form renders as a normal link. The reference form renders as a standard reference link (CommonMark-compatible).


Shortcut IDs MUST follow these rules:

RuleValidInvalid
Lowercase letters@docs@Docs
Numbers allowed@section2
Hyphens allowed@getting-started
Underscores allowed@api_ref
Must start with a letter@api@2api
MUST NOT start with link-@links@link-1

Pattern: @[a-z][a-z0-9_-]*

The link- prefix is reserved for auto-generated shortcuts. Named shortcuts MUST NOT use IDs starting with link-.


Visit the [@docs Documentation](https://docs.example.com) for
more details, or see the [@changelog Changelog](./changelog.md).

Menu files consist of shortcut lines:

[@home Home](../index.md)
[@api API Reference](../api/index.md)

Grouped at the bottom of a document or section:

[@docs]: https://docs.example.com
[@api]: https://api.example.com/v2
[@pricing]: ./pricing.md

Shortcuts are namespaced by their source.

Shortcuts defined in the document (inline or reference) belong to the page namespace. The prefix is implicit:

@docs = @page.docs

Both forms are valid. The short form @docs is preferred.

Shortcuts from nav menus are prefixed with the menu name:

Menu file (nav/main.md, menu name main):

[@home Home](../index.md)
[@api API Reference](../api/index.md)

AI sees:

[Home][@main.home]
[API Reference][@main.api]
SourceNamespaceAI seesFull form
Document [@docs ...]page[@docs][@page.docs]
Menu main [@home ...]main[@main.home][@main.home]
Menu api [@auth ...]api[@api.auth][@api.auth]

Regular Markdown links without explicit shortcut IDs are automatically assigned identifiers by the runtime.

Only links with long or external topics are converted:

Link topicConverted?Example
https:// or http:// URLYes[Docs](https://docs.example.com)
Relative path > 40 charsYes[Guide](./very/deep/nested/path/to/doc.md)
Short relative pathNo[Home](./index.md)

Short relative paths are already readable — no shortcut needed. Author-defined shortcuts ([@id Label](url)) are never converted; they keep their explicit ID.

The runtime attempts to derive a readable slug from the link label. A slug is used when the label meets all of these conditions:

  1. 20 characters or fewer
  2. Contains only letters, numbers, spaces, or hyphens
  3. Not a duplicate of an already-assigned slug in the same document

The slug is produced by: lowercase → remove non-word characters (except spaces and hyphens) → trim → replace spaces with hyphens.

GitHub → github
MDN Web Docs → mdn-web-docs
Example API → example-api

When the same slug appears more than once, a numeric suffix is appended starting from 2:

@docs ← first occurrence
@docs-2 ← second
@docs-3 ← third

The suffix is per-slug — duplicates of @docs and duplicates of @github maintain independent counters.

When the label does not qualify for a slug (too long, special characters, or empty after sanitizing), the runtime assigns @link-N where N increments from 1 per document:

ConditionLabelResult
Exceeds 20 charsA Very Long Label That Exceeds Limit@link-1
Special charactersC++ Reference (2024)@link-2
Empty slugLabel produces empty string after sanitizing@link-3

The link-N counter is independent from slug duplicate counters.

Source:

Visit [GitHub](https://github.com) for code.
Read the [MDN Web Docs](https://developer.mozilla.org) reference.
See [Docs](https://docs.first.com) and [Docs](https://docs.second.com).
And [Docs](https://docs.third.com) too.
Check [A Very Long Documentation Title Here](https://example.com/long).
Stay on [Home](./index.md).

AI view:

Visit [GitHub][@github] for code.
Read the [MDN Web Docs][@mdn-web-docs] reference.
See [Docs][@docs] and [Docs][@docs-2].
And [Docs][@docs-3] too.
Check [A Very Long Documentation Title Here][@link-1].
Stay on [Home](./index.md).
  • @github, @mdn-web-docs, @docs — label-derived slugs
  • @docs-2, @docs-3 — duplicate slug with suffix
  • @link-1 — non-sluggable fallback (label exceeds 20 chars)
  • [Home](./index.md) — short relative path, not converted
  • Slugs and @link-N IDs belong to the page namespace.
  • The link- prefix is reserved — named shortcuts MUST NOT use it.
  • Auto-shortcuts are scoped to the current document. When the document changes, previous auto-shortcuts are invalidated.
  • Same document content always produces the same auto-shortcuts (deterministic, top-to-bottom order).

Shortcuts can point to action invocations instead of documents. The act: URI scheme tells the runtime to dispatch the action on the current document instead of loading a new page.

act:<action-id>
act:<action-id>?<key>=<value>&<key>=<value>...

The action id matches an act.<id> block on the document holding the shortcut. Query parameters become the action’s --key value flags.

[Read post]({act-url})
for: post in Response.body.posts
- [{post.title}](act:read?id={post.id}) — by {post.author.name}
end:

After auto-shortcut assignment, the AI sees:

- [I have started treating...][@link-1] — by SparkLabScout
- [they built a kill switch...][@link-2] — by pyclaw001

When the AI runs /open @link-1, the runtime:

  1. Resolves the shortcut → act:read?id=861040aa-...
  2. Sees the act: scheme — does NOT fetch a document
  3. Looks up act.read on the current document
  4. Parses query string → --id "861040aa-..."
  5. Executes the action and renders its response template

The session’s currentDoc is unchanged. The agent stays on the same page (e.g. the feed) and can follow other shortcuts in the same list without re-fetching.

A SPA URL like https://app.example.com/post/X is rendered for humans (JavaScript hydrates the content). An agent fetching it gets the loading shell.

The right primitive for “read this thing” is the action that calls the API and returns structured content — act.read in the example above.

act: URI scheme lets templates output one-click drill-in links without forcing the AI to type the full action call. The list shortcut and the action invocation become a single primitive: follow the link, get the result.

PatternShortcut valueWhat /open @link-1 does
[t](https://example.com/x)URLHTTP fetch, currentDoc replaced
[t](file:///path.md)local pathFile load, currentDoc replaced
[t](act:read?id=X)action callDispatch action, currentDoc unchanged
  • The action MUST be defined on the document where /open runs. If the agent navigates to a sub-page that doesn’t define the action, dispatch fails with Action not found.
  • Query keys map to action field names (--<key> "<value>").
  • Values are URL-decoded before substitution.
  • No fragment (#block) — act: URLs don’t refer to documents.
  • The currentDoc does not change. Auto-shortcuts from the prior rendering remain valid (drill-in patterns stay navigable).
ConditionError
No document openCannot dispatch action: no document open.
Missing action idact: URI missing action id
Unknown actionAction not found: "<id>"
Required field missingStandard action validation error

  • Inline shortcut IDs MUST be unique within a document.
  • Menu shortcut IDs MUST be unique within a menu file.
  • Same IDs in different menus are allowed (namespacing prevents collision: @main.home vs @admin.home).
  • An inline shortcut MAY have the same ID as a menu shortcut. The inline shortcut takes priority during resolution.

When a shortcut reference like [@id] is resolved:

  1. Inline shortcuts — defined in the current document
  2. Auto-generated shortcuts — slugs, @slug-N duplicates, and @link-N fallbacks
  3. Menu shortcuts — namespaced entries from nav menus

If a reference includes a namespace (@main.home), it resolves directly to that menu. No priority lookup is needed.


  1. Inline form: [@id Label](url) — defines and displays in one line.
  2. Reference form: [Label][@id] + [@id]: url — separated.
  3. AI always sees: [Label][@id] — URL never in AI context.
  4. IDs: [a-z][a-z0-9_-]* — MUST NOT start with link-.
  5. Inline IDs MUST be unique within a document.
  6. Menu IDs MUST be unique within a menu file.
  7. Menu shortcuts are namespaced: @menu_name.id.
  8. Inline shortcuts use implicit page namespace.
  9. Auto-generated: external URLs and long paths only (short relative paths excluded).
  10. Slug from label if ≤ 20 chars, alphanumeric/space/hyphen only, and non-empty.
  11. Duplicate slugs: @slug-2, @slug-3 (per-slug counter).
  12. Non-sluggable fallback: @link-N (reserved prefix, global counter).
  13. Resolution order: inline > auto > menu.
  14. In CommonMark viewers, both forms render as standard links.
  15. act:<action-id>?<key>=<value> URLs dispatch actions on /open without changing currentDoc.