teamdocs

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Index

Constants

View Source
const (
	VisibilityAlways  = "always"
	VisibilityIndexed = "indexed"
	VisibilityHidden  = "hidden"
)

Visibility levels control how docs are disclosed to agents during prime.

Progressive disclosure model (inspired by Agent Skills spec):

  • "always" — content auto-inlined into prime output. Reserved for future use; intended for small, universally-needed docs (<200 tokens) like glossaries. Not yet implemented — accepted as a valid value but treated as "indexed" for now.
  • "indexed" — listed in catalog with title + description + when triggers. Agent reads full content on demand when task matches. This is the default.
  • "hidden" — not visible to agents at all. Use for human-only docs, drafts, meeting notes, or directory instructions (like README.md).
View Source
const (
	RuleStatusActive = "active"
	RuleStatusDraft  = "draft"
	// RuleStatusSupersededPrefix is matched as a prefix on status values like
	// "superseded-by:<other-rule-name>".
	RuleStatusSupersededPrefix = "superseded-by:"
)

Rule status values.

View Source
const (
	RuleAudienceAI    = "ai"
	RuleAudienceHuman = "human"
	RuleAudienceBoth  = "both"
)

Rule audience values.

View Source
const DefaultRuleAudience = RuleAudienceAI

DefaultRuleAudience is what's assumed when frontmatter omits the field.

View Source
const DefaultRuleVisibility = VisibilityIndexed

DefaultRuleVisibility is what's assumed when frontmatter omits the field. "indexed" — much closer to Claude's paths-deferred lazy loading than "always" is. Loading every team rule into prime would silently bloat context as the rule library grows; opting in to "always" forces teams to think about cost.

View Source
const DefaultVisibility = VisibilityIndexed

DefaultVisibility is the visibility applied when frontmatter omits the field. Docs in team context docs/ are visible by default — the whole point of the directory is sharing knowledge with the team, including AI coworkers.

Variables

This section is empty.

Functions

This section is empty.

Types

type TeamDoc

type TeamDoc struct {
	Name        string `json:"name"`                  // filename (e.g., "principles.md")
	Title       string `json:"title"`                 // from frontmatter or first H1 heading
	Description string `json:"description,omitempty"` // one-line summary for catalog
	Path        string `json:"path"`                  // absolute path — agent reads on demand
	When        string `json:"when,omitempty"`        // natural language triggers for when to read
	Visibility  string `json:"visibility"`            // always | indexed | hidden
}

TeamDoc represents a single team document discovered from the docs/ directory within a team context. These docs are cataloged during ox agent prime so agents know what's available and when to read each document on demand.

func DiscoverDocs

func DiscoverDocs(teamPath string) ([]TeamDoc, error)

DiscoverDocs scans the docs/ directory in a team context for markdown files and returns a catalog of documents visible to agents.

Only .md files are processed. Rationale:

  • Agents read markdown natively — no conversion tooling needed
  • YAML frontmatter is a markdown convention with universal tooling support (Jekyll, Hugo, Obsidian, VS Code, Agent Skills spec)
  • Token estimation is trivial for text content
  • Non-markdown assets (images, PDFs, data files) need entirely different disclosure mechanisms and are out of scope for this catalog

README.md is always excluded — it contains instructions about the directory itself, not content for agents. Server-side hardcodes this as hidden.

Returns only docs with visibility != "hidden". Sorted by filename for stable, deterministic output.

type TeamRule added in v0.8.0

type TeamRule struct {
	Name            string   `json:"name"`                       // kebab-case identifier; from frontmatter or filename
	Description     string   `json:"description,omitempty"`      // one-line summary
	RelPath         string   `json:"rel_path"`                   // path relative to rules root (e.g., "backend/postgres.md")
	AbsPath         string   `json:"abs_path"`                   // absolute path on disk
	Repos           []string `json:"repos,omitempty"`            // repo filter; empty = all team repos
	Audience        string   `json:"audience,omitempty"`         // "ai" | "human" | "both" (default: "ai")
	Visibility      string   `json:"visibility"`                 // "always" | "indexed" | "hidden"
	Status          string   `json:"status,omitempty"`           // "active" | "draft" | "superseded-by:<other>"
	FromDiscussion  string   `json:"from_discussion,omitempty"`  // optional provenance link
	Body            string   `json:"body,omitempty"`             // markdown body (excluding frontmatter); only populated for visibility=always
	EstimatedTokens int      `json:"estimated_tokens,omitempty"` // rough estimate (len(body)/4); only set when Body is loaded
}

TeamRule represents a single team-context behavioral rule discovered under agents/rules/ (preferred) or coworkers/rules/ (legacy fallback).

Team rules apply to every supported AI coding agent (Claude, Codex, Amp, Cursor, etc.) used by teammates running ox. They are the team-scope cousin of Claude's .claude/rules/<topic>.md — modular, one concern per file, and loaded into agent context via ox agent prime.

Subdirectories under agents/rules/ are walked recursively. The relative path is preserved so organization (e.g., backend/postgres.md) stays meaningful for navigation and dedupe.

func DiscoverRules added in v0.8.0

func DiscoverRules(teamPath, repoSlug string) ([]TeamRule, error)

DiscoverRules walks the team context for behavioral rule files under agents/rules/**/*.md (preferred) and coworkers/rules/**/*.md (legacy fallback for any teams that adopted that location early). Subdirectories are walked recursively, mirroring how Claude Code walks .claude/rules/.

Rules with audience: human are excluded (this scanner is for agent consumption). Rules with status: draft and visibility: hidden are excluded. Rules with status starting with superseded-by: are excluded.

If repoSlug is non-empty, rules with a non-empty repos: list that does NOT contain repoSlug are excluded. Empty/absent repos: means the rule applies to all team repos.

For visibility: always rules, the markdown body (excluding frontmatter) is loaded into TeamRule.Body so the prime emitter can inline it. For indexed rules, only metadata is returned; the agent reads the file on demand from AbsPath.

Results are sorted by RelPath for stable output.

TODO(sync-out): A future daemon-driven optimization could sync filtered, repo-scoped team rules OUT of team context and into each cloned repo's agent-native rules directory (e.g., .claude/sageox-team-<slug>/rules/ for Claude, .cursor/rules/sageox-team-<slug>/ for Cursor). That would let team rules participate in the agent's NATIVE rule-loading machinery (Claude's `paths:`-scoped lazy loading, Cursor's `globs:` matching, etc.) instead of being delivered up front via prime XML.

Implementation considerations when picking this up:

  1. Adapter dispatch — each agent has its own rules dir convention. The pkg/adapterprotocol RulesParams + handleInstallRules pattern already abstracts this (cmd/ox-adapter-claude-code/rules.go is the reference implementation). Sync-out would extend the rule file list passed to handleInstallRules with discovered team rules.

  2. Namespace — write to a sageox-team-<slug>/ subdirectory under the agent's rules dir, never directly into .claude/rules/ root, to avoid colliding with project-local rules of the same name and to make cleanup unambiguous.

  3. Lifecycle — daemon writes on team-context sync (after pull), and on repo-open. Daemon removes files for rules that disappear from team context (true mirror, not append-only). At prime time the sync state is read-only.

  4. Filtering — apply the same repos:/audience:/status: filters here that DiscoverRules already applies, so a teammate working in repo A doesn't get repo B's rules synced into their working tree.

  5. Multi-adapter coverage — today only ox-adapter-claude-code and ox-adapter-droid implement handleInstallRules. Other adapters (codex, amp, aider, gemini, opencode, pi) need rules.go before they can participate. Tracking the gap is the prerequisite for a uniform sync-out story.

  6. Per-user knowledge bubble — when the user-context bubble lands, sync-out for user rules has the same shape but reads from the user-context location and tags entries with audience: ai, source: user (so the budget accounting in agent_prime_xml.go attributes them correctly to BudgetSourceUser).

Not implemented yet; this comment IS the design memo until someone picks up the work.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL