Ghostcode builds a flat codebase snapshot. It scans the directory you run it in, records the repository tree, reads the included source files, and writes either a single pasteable snapshot, a chunked export, or a zipped export based on the local .gc.json.
It also includes an Autosnapshot service that can periodically snapshot the current repo in the background using the same local config file.
Ghostcode can also store repo-local annotations through a native terminal editor. Annotations are written to .gc.json and included as metadata in future snapshots without modifying source files.
Ghostcode reads .gc.json from the current working directory and then:
- Applies built-in excludes for common generated, binary, and dependency files.
- Applies the configured include and exclude rules from
.gc.json. - Builds a readable tree of the included files.
- Reads each allowed text file into a structured
<<<FILE: ...>>>block. - Skips binary files and files larger than the configured size limit.
- Writes the result under
<name>_export/<snapshot-id>/in the configured output format, chunked export files, or<name>.zipdepending on the config values.
.gc.json itself is excluded from snapshots by default.
From the project directory, install Ghostcode so the gstc and ghostcode commands are added to your shell path:
python3 -m pip install .For a user-level install:
python3 -m pip install --user .On Debian or Ubuntu, pipx is the recommended application-style install:
sudo apt update
sudo apt install pipx
pipx ensurepath
pipx install .After installation, verify it is available:
gstc --helpCreate a starter config in the current directory:
gstc initInspect the current effective config:
gstc config showRun Ghostcode from that directory:
gstcGhostcode always snapshots the directory it is called in. To run it for another project, change into that directory first.
Open the annotation editor for files included by the current snapshot config:
gstc annotateRestore a snapshot back into a project directory:
gstc restore ghostcode_export/<snapshot-id>/ghostcode.h.txtThe normal workflow is:
- Run
gstc init - Edit
.gc.json - Run
gstc
gstc snapshot is supported as an alias of gstc. The longer ghostcode command remains available.
Restore from a single snapshot file:
gstc restore path/to/ghostcode_export/<snapshot-id>/ghostcode.h.txt
gstc restore path/to/ghostcode_export/<snapshot-id>/ghostcode.h.md
gstc restore path/to/ghostcode_export/<snapshot-id>/ghostcode.h.json -o restored_projectRestore from a chunked export directory:
gstc restore path/to/ghostcode_export/<snapshot-id>By default, restore writes into a new restored_<root-name> directory and refuses to overwrite existing files. Use --dry-run to validate a restore without writing files, or --force to overwrite existing files in the output directory.
Try the included demo fixture:
cd demo/sample_project
python3 ../../ghostcode.py init
python3 ../../ghostcode.pyShow the effective config for the current directory:
gstc config showgstc init and gstc config show are the main support commands. Snapshot behavior and Autosnapshot settings are controlled by editing .gc.json directly.
Ghostcode stores project snapshot settings in .gc.json in the directory being scanned.
Default shape:
{
"name": "ghostcode",
"file_type": "txt",
"include_instructions": false,
"follow_symlinks": false,
"zip_output": false,
"respect_gitignore": true,
"chunk_bytes": 180000,
"max_file_bytes": 300000,
"encoding": "utf-8",
"include_extensions": [],
"exclude_dirs": [],
"exclude_files": [],
"exclude_globs": [],
"exclude_extensions": [],
"autosnapshot": {
"interval_seconds": 900,
"out_dir": null
},
"annotations": {}
}Behavior:
nameis the output base name.file_typecontrols the output syntax and file extension. Usetxt,markdown, orjson.- Every save writes into
<name>_export/<snapshot-id>/. Files that include a Ghostcode header use.hbefore the output extension, for example<name>.h.txt. - When the export exceeds
chunk_bytes, the first part is<name>.h.txtand later parts continue as<name>_part2.txt,<name>_part3.txt, and so on. Only the first part contains the snapshot header. - When
zip_outputistrue, Ghostcode packages the generated export artifact into<name>_export/<snapshot-id>/<name>.zip. - When
respect_gitignoreistrue, Ghostcode asks Git to exclude paths matched by the repo's ignore rules, including.gitignore. include_extensionsandexclude_extensionsaccept values with or without a leading dot.autosnapshot.interval_secondscontrols the background snapshot cadence for the current repo. The minimum is 1 second.autosnapshot.out_dirmay benullto use the default state directory, an absolute path, or a path relative to the repo root.annotationsstores line and column ranges keyed by repository-relative file path.- Older exclude-only
.gc.jsonfiles still work. Missing fields fall back to built-in defaults. - Invalid config files are reported by Ghostcode with the affected line, error type, and suggested valid values where possible.
Run the native terminal editor from a directory that contains .gc.json:
gstc annotateThe picker only shows files included by the effective snapshot config. In the file viewer, use shifted movement to select lines, Enter to write an annotation, L to list existing annotations, S to apply one annotation from the list, F to semantically search current-file annotations, C to clear the applied annotation, and Q to return to the picker.
Autosnapshot is now repo-local. Run these commands from the project root that contains .gc.json.
Run one autosnapshot pass immediately:
gstc auto onceRun the autosnapshot worker in the background:
gstc auto runRun it in the foreground when you want to keep the terminal attached:
gstc auto run-fCheck the autosnapshot status for the current repo:
gstc auto statusStop the autosnapshot worker for the current repo:
gstc auto stopStop all running Autosnapshot workers:
gstc auto stop -aAutosnapshot runtime state is stored outside the repo under the Ghostcode state directory.
Default path:
~/.local/state/ghostcode/
Behavior:
- Each repo has its own Autosnapshot worker state keyed by the repo path.
- The worker reads the current repo's
.gc.jsoneach loop, so changingautosnapshot.interval_secondsorautosnapshot.out_diraffects future runs. - Default Autosnapshot output is written outside the repo under
~/.local/state/ghostcode/autosnapshots/....
Snapshot generation writes:
- A
GHOSTCODE_SNAPSHOTheader - A unique SHA1 snapshot ID
- The resolved root path
- File counts and total included bytes
- A directory tree
- An optional instruction section when
include_instructionsistrue - Structured file blocks containing text content
- Optional annotation metadata for each included file