Build companion

Tutorial

Create a completion pack

Create, test, import, and share your own local Ghost Text completion pack.

What you will make

In this tutorial, you will create a small completion pack for React and TypeScript files. A completion pack gives Kashira a set of local Ghost Text suggestions that appear when a line matches a trigger you define.

You can build a pack in the in-app Pack Editor or prepare a JSON file and import it. Both approaches produce the same kind of custom pack.

1. Open the Pack Editor

Open Settings → Editor, scroll to Completion Packs, and select New Pack. The Pack Editor lets you create a pack without writing JSON by hand.

  1. 1
    Pack ID

    Use a permanent, unique name such as acme.react-helpers. Avoid spaces and do not reuse another pack’s ID.

  2. 2
    Name

    Use a clear human-friendly name, such as Acme React Helpers.

  3. 3
    Language IDs

    For React TypeScript, enter typescriptreact. Add javascriptreact too if the pack should work in JSX files.

  4. 4
    File Extensions

    For React TypeScript, enter tsx. Add jsx if you also support JavaScript React files.

  5. 5
    Description

    Describe the shortcuts the pack provides so it is easy to recognize later.

2. Create your first rule

Use the values below in the first rule in the Pack Editor. This makes typing rfc on an otherwise empty line offer a simple React component.

Copy-ready example Rule ID
react.function-component

Title
Function component

Trigger Pattern
^\s*rfc\s*$

Insert Text
export function Component() {
${nextIndent}return <div />;
${indent}}

Replace
Current word

Flags
i

3. Save and test the rule

Select Save in the Pack Editor. Open a .tsx file, start a blank line, type rfc, and pause briefly. Ghost Text should appear. Press Tab to accept it. If it does not appear, confirm the pack is enabled and that the file matches the language ID or extension you entered.

Create a single-rule pack from JSON

If you prefer importing a file, copy the JSON below into a new file named react-component.kashira-completions.json. Then choose Import from the Completion Packs section in Settings → Editor.

Copy-ready example {
  "id": "acme.react.component",
  "name": "React Component Starter",
  "description": "Adds an rfc shortcut for React component files.",
  "enabled": true,
  "languageIds": ["typescriptreact", "javascriptreact"],
  "fileExtensions": ["tsx", "jsx"],
  "rules": [
    {
      "id": "react.function-component",
      "title": "Function component",
      "linePrefixPattern": "^\\s*rfc\\s*$",
      "insertText": "export function Component() {\n${nextIndent}return <div />;\n${indent}}",
      "replace": "currentWord",
      "flags": "i"
    }
  ]
}

Create a multi-rule pack

A pack can hold as many rules as you need. The example below includes one shortcut for a component and another for a useEffect block. Copy it into a .kashira-completions.json file, then import it in Settings → Editor → Completion Packs.

Copy-ready example {
  "id": "acme.react.essentials",
  "name": "React Essentials",
  "description": "Component and effect shortcuts for React files.",
  "enabled": true,
  "languageIds": ["typescriptreact", "javascriptreact"],
  "fileExtensions": ["tsx", "jsx"],
  "rules": [
    {
      "id": "react.function-component",
      "title": "Function component",
      "linePrefixPattern": "^\\s*rfc\\s*$",
      "insertText": "export function Component() {\n${nextIndent}return <div />;\n${indent}}",
      "replace": "currentWord",
      "flags": "i"
    },
    {
      "id": "react.effect",
      "title": "Effect starter",
      "linePrefixPattern": "^\\s*ue\\s*$",
      "insertText": "useEffect(() => {\n${nextIndent}\n${indent}}, []);",
      "replace": "currentWord",
      "flags": "i"
    }
  ]
}

Understand trigger patterns

Trigger Pattern uses a regular expression. Start simple: ^\s*rfc\s*$ means “allow optional spaces, then match rfc, and nothing else on the line.” The i flag makes the shortcut case-insensitive. Keep triggers short, distinct, and easy for your team to remember.

Copy-ready example ^\s*rfc\s*$    Match rfc on its own line
^\s*ue\s*$     Match ue on its own line
^\s*log\s*$    Match log on its own line

Use formatting variables

Completion-pack insert text can use ${indent} for the current line’s indentation, ${nextIndent} for one level deeper, and ${currentWord} for the word at your cursor. These make a pack feel natural in different files and indentation styles.

Copy-ready example ${indent}      Current line indentation
${nextIndent}  One indentation level deeper
${currentWord} Current word at the cursor

Ask an LLM to create a pack

Copy the prompt below into the LLM of your choice, replace the bracketed details with what you want, and ask it to return the finished JSON. Save that response with a .kashira-completions.json extension, then import it from Settings → Editor → Completion Packs.

Copy-ready example Create a valid Kashira local completion pack for [LANGUAGE OR FRAMEWORK].

I want these shortcuts and behaviors:
[DESCRIBE EACH SHORTCUT, WHAT THE USER TYPES, AND WHAT IT SHOULD INSERT]

Return only valid JSON. Do not wrap it in Markdown and do not explain it. The JSON must be either one pack object or an array of pack objects using exactly this shape:

{
  "id": "unique.pack.id",
  "name": "Human-friendly pack name",
  "description": "What the pack does",
  "enabled": true,
  "languageIds": ["language-id"],
  "fileExtensions": ["extension-without-dot"],
  "rules": [
    {
      "id": "unique-rule-id",
      "title": "Human-friendly rule title",
      "linePrefixPattern": "a valid JavaScript regular expression string",
      "insertText": "text to insert; use \n for new lines",
      "replace": "cursor" or "currentWord",
      "flags": "i"
    }
  ]
}

Requirements:
- Include as many rules as needed in the rules array.
- Use ^ and $ in each trigger pattern when the shortcut should match the entire current line.
- Escape backslashes correctly for JSON; for example, write \\s for whitespace in a JSON regex string.
- Use ${indent}, ${nextIndent}, and ${currentWord} only when helpful.
- Make every id unique, lowercase, and hyphen or dot separated.
- Set enabled to true.

Before returning the JSON, check that it is valid JSON and that every rule includes id, linePrefixPattern, insertText, and replace.

Import, edit, and export

To import a pack you received or downloaded, return to Settings → Editor → Completion Packs and select Import. Kashira adds it to your custom packs, where you can enable, edit, export, or remove it. Export a finished pack to share it with another Kashira installation or a teammate.

Test before sharing

Open a matching file, type every shortcut you added, and confirm the Ghost Text appears and inserts exactly what you expect. Start with a small pack, then add rules as you discover repeated code patterns in your project.

Keep packs focused

Small packs organized around one framework, convention, or team workflow are easier to understand and maintain.