Skene
Product
Pricing
Docs
Blog
Events
About
Log InStart free
ProductPricingDocsBlogEventsAbout
Log InStart free
Skene subpage background texture

From an earlier version of Skene. See the current product →

  1. Home
  2. /
  3. Resources
  4. /
  5. Docs
  6. /
  7. skene CLI
CLI docs

Python API

Navigation

skene CLI

  • Quickstart
  • Overview
  • Installation
  • Push
  • Login
  • Status
  • Features
  • LLM Providers
  • Configuration
  • MCP Server
  • CLI Reference
  • HTTP API
  • Python API
  • Troubleshooting

Resources

  • Skene Cloud docs
  • Playbooks
  • Glossary

skene CLI

  • Quickstart
  • Overview
  • Installation
  • Push
  • Login
  • Status
  • Features
  • LLM Providers
  • Configuration
  • MCP Server
  • CLI Reference
  • HTTP API
  • Python API
  • Troubleshooting

Resources

  • Skene Cloud docs
  • Playbooks
  • Glossary

Programmatic access to skene's codebase exploration, configuration, LLM client, and journey models.

Quick example

from pathlib import Path
import yaml

from skene import CodebaseExplorer
from skene.analyzers.journey.models import Journey

# Sandboxed access to a codebase
explorer = CodebaseExplorer(Path("/path/to/repo"))

# Load and validate a journey.yaml produced by `skene analyse-journey`
journey = Journey.model_validate(
    yaml.safe_load(Path("skene-context/journey.yaml").read_text())
)
print(journey.product.name)
for stage in journey.stages:
    print(stage.name, [m.name for m in stage.milestones])

CodebaseExplorer

Safe, sandboxed access to codebase files. Automatically excludes common build/cache directories.

from pathlib import Path
from skene import CodebaseExplorer, DEFAULT_EXCLUDE_FOLDERS

# Create with default exclusions
explorer = CodebaseExplorer(Path("/path/to/repo"))

# Create with custom exclusions (merged with defaults)
explorer = CodebaseExplorer(
    Path("/path/to/repo"),
    exclude_folders=["tests", "vendor", "migrations"]
)

Methods

MethodReturnsDescription
await get_directory_tree(start_path, max_depth)dictDirectory tree with file counts
await search_files(start_path, pattern)dictFiles matching glob pattern
await read_file(file_path)strFile contents
await read_multiple_files(file_paths)dictMultiple file contents
should_exclude(path)boolCheck if a path should be excluded

Related

  • build_directory_tree: Standalone function for building directory trees
  • DEFAULT_EXCLUDE_FOLDERS: List of default excluded folder names

Configuration

from skene import Config, load_config

# Load config from files + env vars
config = load_config()

# Access properties
config.api_key       # str | None
config.provider      # str (default: "openai")
config.model         # str (auto-determined if not set)
config.output_dir    # str (default: "./skene-context"; legacy "./skene" auto-detected)
config.debug         # bool (default: False)
config.exclude_folders  # list[str] (default: [])
config.base_url      # str | None
config.upstream      # str | None (upstream workspace URL)

# Get/set arbitrary keys
config.get("api_key", default=None)
config.set("provider", "gemini")

Upstream credentials

from skene.config import (
    save_upstream_to_config,    # Save upstream URL, workspace, API key to .skene.config
    remove_upstream_from_config,# Remove upstream credentials from .skene.config
    resolve_upstream_token,     # Resolve token from env/config
)

LLM Client

from pydantic import SecretStr
from skene.llm import create_llm_client, LLMClient

client: LLMClient = create_llm_client(
    provider="openai",          # openai, gemini, anthropic, ollama, lmstudio, generic
    api_key=SecretStr("key"),
    model="gpt-4o",
    base_url=None,              # Required for generic provider
    debug=False,                # Log LLM I/O to ~/.local/state/skene/debug/
)

Journey models

The journey.yaml schema is defined by Pydantic v2 models in skene.analyzers.journey.models. They are validated end-to-end before the file is written by skene analyse-journey.

from skene.analyzers.journey.models import (
    Journey,        # The whole document
    Product,        # Product metadata (name, description, generated_at, source_commit)
    Stage,          # A lifecycle stage containing milestones and KPIs
    Milestone,      # A user-facing milestone with evidence
    Kpi,            # A stage KPI
    KpiDerivation,  # How a KPI is derived from tables/events
    Layer,          # A named layer spanning multiple stages
    Connector,      # A cross-stage link between milestones
    Evidence,       # Re-exported from skene.schema.feature
    EvidenceSource, # Re-exported from skene.schema.feature
    TriggerType,    # Enum: email, scheduled, webhook, event_bus, unknown
    ConnectorStyle, # Enum: solid, dashed, dotted
    KpiUnit,        # Enum: percentage, count, duration_days, duration_hours, ratio, currency
)

Journey fields

FieldType
productProduct
layerslist[Layer]
stageslist[Stage] (min 1)
connectorslist[Connector]

Model validators enforce unique stage/layer/connector IDs, unique stage orders, and that layers and connectors reference real stages/milestones.

Stage fields

FieldType
idstr (snake_case ID)
orderint (>= 1)
namestr
subtitlestr | None
milestoneslist[Milestone] (min 1, unique IDs and orders)
kpislist[Kpi] (unique IDs)

Milestone fields

FieldType
idstr (snake_case ID)
orderint (>= 1)
namestr
descriptionstr
evidencelist[Evidence] (min 1)
tracked_eventstr | None
confidencefloat (0.0–1.0, default 1.0)

Connector fields

FieldType
idstr (snake_case ID)
fromstr ("<stage_id>.<milestone_id>")
tostr (milestone ref or the literal "unknown")
labelstr
trigger_typeTriggerType
styleConnectorStyle (default dashed)
confidencefloat (0.0–1.0, default 1.0)
evidencelist[Evidence] (min 1)

Serialization

from skene.analyzers.journey import serialize

yaml_text = serialize.to_yaml(journey)   # Render Journey to YAML
json_text = serialize.to_json(journey)   # Render Journey to JSON
serialize.write(journey, path)           # Write journey.yaml to disk

Journey pipeline

The rest of the journey machinery lives alongside the models and is orchestrated by skene.core.journey:

  • skene.analyzers.journey.merge: merge_features deduplicates features from the code and schema agents into the feature map
  • skene.analyzers.journey.synthesize: synthesize_milestones_llm composes user-journey milestones from the feature map
  • skene.analyzers.journey.classify: classify_feature / classify_all per-feature stage assignment (the synthesis fallback)
  • skene.analyzers.journey.assemble: assemble_journey builds the final validated Journey
  • skene.analyzers.schema_parsers: parse_schema_dir (SQL files) and introspect_db (live PostgreSQL) produce the schema input

Feature registry

from skene.feature_registry import (
    load_feature_registry,              # Load registry from disk
    write_feature_registry,             # Write registry to disk
    merge_features_into_registry,       # Merge new features with existing registry
    upsert_registry_from_engine,        # Upsert registry entries from engine.yaml features
    export_registry_to_format,          # Export to json, csv, or markdown
    derive_feature_id,                  # Convert feature name to snake_case ID
    compute_loop_ids_by_feature,        # Map feature_id -> list of loop_ids
)

Key functions

FunctionDescription
merge_features_into_registry(new_features, registry)Merges new features: adds new, updates matched, archives missing
upsert_registry_from_engine(engine_doc, registry_path)Upserts feature-registry entries from engine.yaml features
export_registry_to_format(registry, format)Exports to "json", "csv", or "markdown"

Engine and migrations

from skene.engine import (
    load_engine_document,               # Load engine.yaml from the bundle dir
    write_engine_document,              # Write engine.yaml to the bundle dir
    merge_engine_documents,             # Merge delta by key
    parse_source_to_db_event,           # Parse schema.table.operation source
    engine_features_to_loop_definitions # Adapter for migration builder
)

from skene.growth_loops.push import (
    ensure_base_schema_migration,       # Check, build, update base schema (creates or overwrites)
    build_loops_to_supabase,            # Build Supabase migrations from trigger definitions
    build_migration_sql,                # Generate migration SQL
    find_trigger_migration,             # Latest telemetry migration path (*_skene_triggers.sql + legacy names)
    write_migration,                    # Write timestamped *_skene_triggers.sql (default migration_name)
    push_to_upstream,                   # Push to upstream API
)

from skene.growth_loops.upstream import (
    validate_token,                     # Validate token via upstream API
    collect_push_files,                 # [{path, content}]: full bundle under output_dir + trigger SQL
    build_push_manifest,                # Create push manifest with checksum over files
    push_to_upstream,                   # POST {manifest, files} to /api/v1/push
)
Previous← HTTP APINextTroubleshooting →
Skene

Product

How it worksFeaturesSupabaseArchitectureIntegrationsSecurityPricing

Resources

DocumentationGlossaryPlaybooksBlog

Company

AboutOpen sourceContactPrivacyTerms
© 2026 Skene. All rights reserved.
Privacy PolicyTerms of Service
Skene