Skip to content

Extensions: convention packs — distribute formatting presets via extensions #169

@tmustier

Description

@tmustier

Summary

Allow extensions to read and apply formatting convention presets — so an extension can ship a "house style" that sets default font, header style, color conventions, number format presets, and custom presets in one click.

Background

#168 expands the conventions system to support custom fonts, header styles, color conventions, and user-defined format presets. Once that ships, all the building blocks exist for a user to manually configure their style. But configuring 10+ settings by hand is tedious, especially across workbooks or teams.

Extensions are the natural distribution mechanism — a "convention pack" extension bundles a complete style preset and applies it via a slash command or widget button.

Depends on

What's needed

Option A: api.conventions bridge surface (clean)

Add a dedicated bridge method so extensions can read and write conventions:

interface ConventionsAPI {
  /** Read the current resolved conventions. */
  get(): Promise<ResolvedConventions>;
  /** Apply a partial conventions update (same shape as the conventions tool's "set" action). */
  set(overrides: Partial<StoredConventions>): Promise<void>;
  /** Reset all conventions to defaults. */
  reset(): Promise<void>;
}

Permission: conventions.write — granted by default for builtin/local-module, denied by default for inline-code/remote-url.

This lets a convention pack extension do:

export function activate(api) {
  api.registerCommand("apply-ib-style", {
    description: "Apply investment banking formatting conventions",
    handler: async () => {
      await api.conventions.set({
        visualDefaults: { fontName: "Arial", fontSize: 8 },
        headerStyle: { fillColor: "#002060", fontColor: "#FFFFFF", bold: true },
        colorConventions: { hardcodedValueColor: "#0000FF", crossSheetLinkColor: "#008000" },
        presetFormats: {
          number: { format: '#,##0.00_);(#,##0.00);"--"_)' },
          currency: { format: '$#,##0.00_);($#,##0.00);("--")_)' },
          percent: { format: '0.0%_);(0.0%);("--")_)' },
        },
      });
      api.toast("Applied IB formatting conventions");
    },
  });
}

Option B: Extension registers a tool that calls the conventions tool (no new bridge needed)

The extension registers a tool that returns a structured conventions payload, and the agent applies it via the existing conventions tool. Simpler to implement but requires an LLM round-trip and is less direct.

Recommendation

Option A is cleaner and doesn't waste tokens. If the convention system from #168 ships first, adding api.conventions to the bridge is a thin wrapper over setStoredConventions().

Example convention packs

Investment Banking

Font: Arial 8
Headers: dark navy fill (#002060), white font, bold
Colors: blue = hardcoded, green = cross-sheet
Numbers: 2dp, parens for negatives, double-dash for zeros, accounting padding
Currency: $ prefix, 2dp
Percent: 1dp
Custom presets: "bps" → '#,##0 "bps"', "multiple" → '0.0x'

Corporate / Brand

Font: Georgia 12
Headers: brand green fill (#1B5E20), white font, bold
Colors: default
Numbers: 2dp, minus for negatives, zero for zeros

Consulting / Presentation

Font: Calibri 10
Headers: dark grey fill (#404040), white font, bold
Colors: blue = hardcoded
Numbers: 1dp, parens for negatives, dash for zeros

Academic / Research

Font: Times New Roman 11
Headers: no fill, bold, bottom border only
Colors: default (all black)
Numbers: 3dp, minus for negatives, zero for zeros

Distribution

Convention packs can be:

  1. Bundled — ship in src/extensions/ as local modules (e.g., convention-ib.ts)
  2. Installed from chat — user says "make all my headers Georgia 12 dark green" → agent uses extensions_manager install_code to create a pack on the fly
  3. Shared via URL — future: api.http to fetch pack definition from a team's shared config URL

UI considerations

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions