GROWI Documentation

repository·master·Indexed 23 days ago

https://github.com/growilabs/growi

A pluggable, markdown-based wiki platform supporting hierarchical pages, real-time collaborative editing, and authentication via LDAP, OAuth, and SAML. Includes guides for Docker and Helm deployment, V8 memory management, and the GROWI Vault feature which allows cloning the wiki as a read-only git repository of Markdown files. Also covers developer documentation for Jotai state management migration and apiv3 authorization regression testing.

Tokens
92.3K
Snippets
179
Records
685
Agent score
80%

What's inside GROWI

  1. Use Startup Memory A/B Tools to compare GROWI builds

    master

    The Startup Memory A/B Tools are lightweight Linux-only tools (designed for devcontainers) used to compare the boot-time memory footprint and loaded-module set of two GROWI production builds. Use these tools when you need to answer "what does the server load and cost at startup?" rather than analyzing memory behavior under sustained load.

    Key Metrics to Watch:

    • installed-idle stable RSS: The steady-state memory usage after the server has finished booting and idling.
    • boot-phase max: The transient peak memory usage during startup, which is critical for preventing OOM-kills in resource-constrained environments (like Kubernetes pods).
  2. Understand growi-vault-manager MVP limitations

    master

    The current version of growi-vault-manager has the following limitations:

    • Read-only: git push (write-back) is not supported. Changes in the vault are not synced to GROWI.
    • No Attachments: Binary files attached to pages are not exported.
    • No Metadata: Comments, likes, bookmarks, and tags are not exported.
    • No Drafts: Only published pages are exported.
    • No Pre-existing History: Only revisions created after the vault feature is enabled are captured.
    • Limited Filtering: Only the published sparse:oid spec (for excluding user/) is supported. Other filters like blob:none or client-chosen patterns are refused by the server.
  3. What is GROWI Vault and how does it work?

    master

    GROWI Vault turns a GROWI wiki into a git repository, allowing users to git clone the wiki as a tree of Markdown files. This enables searching with grep, using local editors, or providing files to AI agents.

    Key Characteristics:

    • Read-Only: git push is rejected. Attachments, comments, likes, and tags are not exported.
    • Permission-Aware: Each clone contains only the pages the specific user is authorized to read. Unauthorized pages are completely absent from the tree and refs.
    • Architecture: The Vault Manager is not a standalone application. It is an engine that runs alongside the GROWI app container. The GROWI app handles all domain knowledge (access control, authentication, group resolution) and proxies clone traffic to the Vault Manager, which maintains the bare git repository and serves git upload-pack.
  4. Use the @growi/editor playground for feature simulation

    master
    The @growi/editor package includes a playground designed to simulate features of @growi/app. If you need to test or simulate specific application behaviors, you can implement them within the playground environment. The playground implementation is located in the components/playground directory.
  5. How GROWI page paths are mapped to filenames

    master

    The VaultPathMapper converts GROWI page paths into deterministic git-tree file paths. This allows the vault to reconstruct file paths from page records without a reverse index.

    Encoding Rules (v1)

    Rules are applied in order:

    1. Windows reserved characters: < > : " / \ | ? * are percent-encoded (e.g., <%3C).
    2. Control characters: U+0000–U+001F or U+007F are percent-encoded.
    3. Leading/trailing spaces: Percent-encoded (%20).
    4. Windows reserved filenames: Segments matching CON, PRN, AUX, NUL, COM0-9, or LPT0-9 (case-insensitive) are prefixed with _ (e.g., CON_CON).
    5. Case collision (reactive): If two paths in the same view differ only by case (e.g., /Foo and /foo), a __<hash8> suffix (first 8 chars of sha1(<path>.md)) is appended to the filename component.
    6. Length limit: If a component exceeds 255 UTF-8 bytes, it is shortened (on character boundaries) and appended with a __<hash8> suffix.
    7. Orphan pages: Paths /trash or starting with /trash/ are prefixed with _orphaned/.
    8. Extension: .md is appended to the final component.

    Key Behaviors

    • Parent pages with children: A page with children does not use README.md. Instead, it uses <name>.md alongside a <name>/ directory.
    • mapPrefix(pagePath): A variant that applies encoding and reserved-name prefixing but does not append .md or the __<hash8> suffix. Used for directory-only operations.
  6. Syntax: Generic Directives

    master

    This extension implements the generic directives proposal. There are three types of directives:

    1. Text Directives

    Used within text lines. Syntax: :name[label]{attributes}. Example: :cite[smith04] or :abbr[HTML]{title="HyperText Markup Language"}.

    2. Leaf Directives

    Block-level directives without content. Syntax: ::name[label]{attributes} on its own line. Example: ::youtube[Video]{vid=01ab2cd3efg}.

    3. Container Directives

    Blocks that can contain other content. Syntax: :::name to open and ::: to close. Example:

    :::spoiler
    Content here
    :::

    Rules & Constraints:

    • Naming: The name is required. It must start with a letter. Other characters can be alphanumeric, -, or _. - or _ cannot end a name.
    • Labels: The [label] part is optional. :x and :x[] are equivalent. Labels can include text constructs like emphasis (:x[a *b* c]).
    • Attributes: The {attributes} part is optional. Supports standard HTML attribute syntax.
      • Shortcuts: {#id} for {id=id} and {.class} for {class=class}.
      • Multiple classes: {.red .blue} or {class="red blue"} are both valid.
    • Nesting: Containers can be nested using more colons (e.g., :::: to wrap :::) and must be closed with an equal or greater number of colons.
    • Strictness: No whitespace is allowed between colons and the name, or between name/label/attributes. Labels and attributes cannot contain line endings.
  7. Preventing double application of changes during Accept

    master

    When using useUnifiedMergeView, executing an Accept action in Editor 1 can cause changes to be applied twice. This happens because the change applied to the primaryDoc is synchronized back to Editor 1 via Yjs, which then attempts to apply it to the originalDoc again.

    Solution: Using Yjs Transaction Origins

    To prevent this, you must track the source of the transaction using a unique origin token.

    1. When Accepting: Wrap the primaryDoc transaction with a specific origin.
    2. During Synchronization: Check the transaction origin and skip processing if it matches the acceptance token.

    Implementation Pattern:

    // 1. Define a unique origin token
    const SYNC_BY_ACCEPT_CHUNK = 'accept';
    
    // 2. When performing the Accept action
    primaryDoc.transact(() => {
      // ... apply changes ...
    }, SYNC_BY_ACCEPT_CHUNK);
    
    // 3. In the synchronization handler
    if (event.transaction.origin === SYNC_BY_ACCEPT_CHUNK) {
      return; // Skip to prevent double application
    }
  8. Analyze memory-profiler output files

    master

    The tool generates four files in the specified --outputDir:

    • snapshot-a.heapsnapshot: Heap snapshot at the baseline boundary (end of baseline idle phase).
    • snapshot-b.heapsnapshot: Heap snapshot at the load boundary (end of load phase).
    • snapshot-c.heapsnapshot: Heap snapshot at the drain boundary (end of drain idle phase).
    • rss-timeseries.csv: Process RSS / heap time-series sampled throughout the run.

    The CSV file uses the following fixed header: timestamp,phase,rss,heap_used,heap_total,external

    Security Warning: Heap snapshots (*.heapsnapshot) may contain sensitive runtime data (user content, session tokens, secrets). Do not commit these files to the repository or share them externally without explicit review.

  9. Requirements for GROWI Vault

    master

    To run GROWI Vault, you must meet the following requirements:

    1. GROWI Version: GROWI >= 8.0.0 (growilabs/growi:8) with the Vault feature enabled.
    2. MongoDB: MongoDB (>= 6.0) running as a replica set. The vault uses MongoDB change streams to stay up to date; a single-node replica set is sufficient.
    3. Shared Filesystem: A persistent filesystem for the bare repository that is shared between the GROWI app container and the Vault Manager container.
      • Note: The Vault Manager container starts as root to set permissions, then drops to the node user (uid/gid 1000), matching the GROWI app's user for volume compatibility.