schist 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
schist-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: schist
3
+ Version: 0.1.0
4
+ Summary: Agent-first knowledge graph: git is truth, SQLite is query, humans just watch
5
+ Author: schist contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/yibeichan/schist
8
+ Project-URL: Repository, https://github.com/yibeichan/schist
9
+ Project-URL: Issues, https://github.com/yibeichan/schist/issues
10
+ Project-URL: Changelog, https://github.com/yibeichan/schist/blob/main/CHANGELOG.md
11
+ Keywords: knowledge-graph,agents,mcp,markdown,sqlite
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: python-frontmatter>=1.1.0
21
+ Requires-Dist: pyyaml>=6.0.3
22
+
23
+ # schist
24
+
25
+ Agent-first knowledge graph. Git is truth, SQLite is query, humans just watch.
26
+
27
+ **schist** is a generic, domain-agnostic knowledge graph where AI agents are the primary writers. Content is markdown + YAML frontmatter, version-controlled in git. SQLite provides the query layer. A static web viewer (D3.js + lunr.js) gives humans a read-only visualization.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install schist
33
+ ```
34
+
35
+ This installs the `schist` CLI and the `schist-ingest` console script (used by the git post-commit hook).
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ # Create a vault
41
+ mkdir -p ~/vaults/research/{notes,papers,concepts,.schist}
42
+
43
+ # Add your first note
44
+ schist add --vault ~/vaults/research \
45
+ --title "First Note" \
46
+ --tags getting-started \
47
+ --body "Hello, knowledge graph."
48
+
49
+ # Search it
50
+ schist search --vault ~/vaults/research "knowledge"
51
+
52
+ # Get graph context (useful for agent session start)
53
+ schist context --vault ~/vaults/research
54
+ ```
55
+
56
+ ## CLI Commands
57
+
58
+ | Command | Description |
59
+ |---------|-------------|
60
+ | `schist add` | Create a new note |
61
+ | `schist link` | Add a connection between nodes |
62
+ | `schist search` | Full-text search |
63
+ | `schist query` | Raw SQL query |
64
+ | `schist build` | Generate static viewer data |
65
+ | `schist context` | Dump session context |
66
+ | `schist schema` | Print or validate schema |
67
+
68
+ ## MCP Server
69
+
70
+ The schist MCP server (`@schist/mcp-server`) is published separately on npm:
71
+
72
+ ```bash
73
+ npm install -g @schist/mcp-server
74
+ ```
75
+
76
+ Add to `~/.claude/settings.json`:
77
+
78
+ ```json
79
+ {
80
+ "mcpServers": {
81
+ "schist": {
82
+ "command": "node",
83
+ "args": ["/absolute/path/to/schist/mcp-server/dist/index.js"],
84
+ "env": {
85
+ "SCHIST_VAULT_PATH": "/absolute/path/to/vault"
86
+ }
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ See the [full README](https://github.com/yibeichan/schist#readme) for architecture docs, hub & spoke setup, and MCP tool reference.
93
+
94
+ ## License
95
+
96
+ MIT
schist-0.1.0/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # schist
2
+
3
+ Agent-first knowledge graph. Git is truth, SQLite is query, humans just watch.
4
+
5
+ **schist** is a generic, domain-agnostic knowledge graph where AI agents are the primary writers. Content is markdown + YAML frontmatter, version-controlled in git. SQLite provides the query layer. A static web viewer (D3.js + lunr.js) gives humans a read-only visualization.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install schist
11
+ ```
12
+
13
+ This installs the `schist` CLI and the `schist-ingest` console script (used by the git post-commit hook).
14
+
15
+ ## Quick Start
16
+
17
+ ```bash
18
+ # Create a vault
19
+ mkdir -p ~/vaults/research/{notes,papers,concepts,.schist}
20
+
21
+ # Add your first note
22
+ schist add --vault ~/vaults/research \
23
+ --title "First Note" \
24
+ --tags getting-started \
25
+ --body "Hello, knowledge graph."
26
+
27
+ # Search it
28
+ schist search --vault ~/vaults/research "knowledge"
29
+
30
+ # Get graph context (useful for agent session start)
31
+ schist context --vault ~/vaults/research
32
+ ```
33
+
34
+ ## CLI Commands
35
+
36
+ | Command | Description |
37
+ |---------|-------------|
38
+ | `schist add` | Create a new note |
39
+ | `schist link` | Add a connection between nodes |
40
+ | `schist search` | Full-text search |
41
+ | `schist query` | Raw SQL query |
42
+ | `schist build` | Generate static viewer data |
43
+ | `schist context` | Dump session context |
44
+ | `schist schema` | Print or validate schema |
45
+
46
+ ## MCP Server
47
+
48
+ The schist MCP server (`@schist/mcp-server`) is published separately on npm:
49
+
50
+ ```bash
51
+ npm install -g @schist/mcp-server
52
+ ```
53
+
54
+ Add to `~/.claude/settings.json`:
55
+
56
+ ```json
57
+ {
58
+ "mcpServers": {
59
+ "schist": {
60
+ "command": "node",
61
+ "args": ["/absolute/path/to/schist/mcp-server/dist/index.js"],
62
+ "env": {
63
+ "SCHIST_VAULT_PATH": "/absolute/path/to/vault"
64
+ }
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ See the [full README](https://github.com/yibeichan/schist#readme) for architecture docs, hub & spoke setup, and MCP tool reference.
71
+
72
+ ## License
73
+
74
+ MIT
@@ -0,0 +1,56 @@
1
+ [build-system]
2
+ requires = ["setuptools>=82.0.1"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "schist"
7
+ version = "0.1.0"
8
+ description = "Agent-first knowledge graph: git is truth, SQLite is query, humans just watch"
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "schist contributors" }
14
+ ]
15
+ keywords = ["knowledge-graph", "agents", "mcp", "markdown", "sqlite"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ ]
24
+ dependencies = ["python-frontmatter>=1.1.0", "pyyaml>=6.0.3"]
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/yibeichan/schist"
28
+ Repository = "https://github.com/yibeichan/schist"
29
+ Issues = "https://github.com/yibeichan/schist/issues"
30
+ Changelog = "https://github.com/yibeichan/schist/blob/main/CHANGELOG.md"
31
+
32
+ [project.scripts]
33
+ schist = "schist.__main__:main"
34
+ schist-ingest = "schist.ingest:main"
35
+
36
+ # Explicit package list — without this, setuptools 82+ flat-layout
37
+ # auto-discovery fails when a local `cli/hooks/` directory exists (as
38
+ # created by test_rate_limit.py's `rejected-pushes.log`, which lands
39
+ # under cli/hooks/ by default even though the log file is gitignored).
40
+ # setuptools then errors with "Multiple top-level packages discovered in
41
+ # a flat-layout: ['hooks', 'schist']" because .gitignore is invisible
42
+ # to it. Pinning packages to ["schist"] makes the install deterministic
43
+ # regardless of stray local directories.
44
+ [tool.setuptools]
45
+ packages = ["schist"]
46
+
47
+ # Ship .sql files (schema.sql, seed-domains.sql) inside the wheel so
48
+ # `schist-ingest` works after `pip install schist` — ingest.py reads
49
+ # schema.sql via Path(__file__).parent / 'schema.sql'.
50
+ [tool.setuptools.package-data]
51
+ schist = ["*.sql"]
52
+
53
+ [tool.pytest.ini_options]
54
+ markers = [
55
+ "integration: slow tests that spawn real git subprocesses",
56
+ ]
File without changes
@@ -0,0 +1,122 @@
1
+ #!/usr/bin/env python3
2
+ """schist CLI — agent-first knowledge graph."""
3
+
4
+ import argparse
5
+ import os
6
+ import sys
7
+
8
+ from . import commands, sync
9
+
10
+
11
+ def main():
12
+ parser = argparse.ArgumentParser(prog='schist', description='Agent-first knowledge graph CLI')
13
+ parser.add_argument('--vault', default=os.environ.get('SCHIST_VAULT_PATH'), help='Path to vault root (or set SCHIST_VAULT_PATH)')
14
+ parser.add_argument('--db', default=None, help='Path to SQLite database (default: <vault>/.schist/schist.db)')
15
+
16
+ sub = parser.add_subparsers(dest='command')
17
+
18
+ # add
19
+ p_add = sub.add_parser('add', help='Create a new note')
20
+ p_add.add_argument('--title', required=True)
21
+ p_add.add_argument('--body', default=None)
22
+ p_add.add_argument('--tags', default=None, help='Comma-separated tags')
23
+ p_add.add_argument('--concepts', default=None, help='Comma-separated concept slugs')
24
+ p_add.add_argument('--status', default='draft')
25
+ p_add.add_argument('--dir', default='notes', dest='directory')
26
+
27
+ # link
28
+ p_link = sub.add_parser('link', help='Add a connection between documents')
29
+ p_link.add_argument('--source', required=True)
30
+ p_link.add_argument('--target', required=True)
31
+ p_link.add_argument('--type', required=True, dest='link_type')
32
+ p_link.add_argument('--context', default=None)
33
+
34
+ # search
35
+ p_search = sub.add_parser('search', help='Full-text search')
36
+ p_search.add_argument('query', help='Search query')
37
+ p_search.add_argument('--limit', type=int, default=20)
38
+ p_search.add_argument('--status', default=None)
39
+ p_search.add_argument('--tags', default=None, help='Comma-separated AND filter')
40
+
41
+ # query
42
+ p_query = sub.add_parser('query', help='Run a SELECT query')
43
+ p_query.add_argument('sql', help='SQL query (SELECT only)')
44
+ p_query.add_argument('--json', action='store_true', dest='as_json')
45
+
46
+ # build
47
+ p_build = sub.add_parser('build', help='Build graph and search index')
48
+ p_build.add_argument('--out', default=None, help='Output directory (default: <vault>/.schist/data/)')
49
+
50
+ # context
51
+ p_context = sub.add_parser('context', help='Print vault context summary')
52
+ p_context.add_argument('--depth', choices=['minimal', 'standard', 'full'], default='standard')
53
+
54
+ # schema
55
+ p_schema = sub.add_parser('schema', help='Print or validate schema')
56
+ p_schema.add_argument('--validate', action='store_true')
57
+
58
+ # init
59
+ p_init = sub.add_parser('init', help='Initialize a vault (standalone, hub, or spoke)')
60
+ p_init.add_argument('path', nargs='?', default=None,
61
+ help='(standalone) Path to new vault (default: current dir)')
62
+ p_init.add_argument('--spoke', action='store_true', help='Initialize as spoke vault')
63
+ p_init.add_argument('--hub', help='(spoke) Hub repository URL')
64
+ p_init.add_argument('--scope', help='(spoke) Scope to sync (directory path)')
65
+ p_init.add_argument('--identity', default=os.environ.get('SCHIST_IDENTITY'),
66
+ help='(spoke/standalone) Identity name (or set SCHIST_IDENTITY)')
67
+ p_init.add_argument('--hub-path', dest='hub_path',
68
+ help='(hub) Path to the bare repo to create')
69
+ p_init.add_argument('--name', help='(hub/standalone) Vault name for vault.yaml')
70
+ p_init.add_argument('--participant', action='append',
71
+ help='(hub) Participant name (repeatable)')
72
+
73
+ # sync
74
+ p_sync = sub.add_parser('sync', help='Sync spoke vault with hub')
75
+ sync_sub = p_sync.add_subparsers(dest='sync_action')
76
+ sync_sub.add_parser('pull', help='Pull updates from hub')
77
+ sync_sub.add_parser('push', help='Push local changes to hub')
78
+
79
+ args = parser.parse_args()
80
+
81
+ if not args.command:
82
+ parser.print_help()
83
+ sys.exit(1)
84
+
85
+ # init: all modes (hub, spoke, standalone) routed through one helper so
86
+ # the conflict matrix lives in one place.
87
+ if args.command == 'init':
88
+ sync._dispatch_init(args)
89
+ sys.exit(0)
90
+
91
+ vault_path = args.vault
92
+ if not vault_path:
93
+ print('Error: --vault required or set SCHIST_VAULT_PATH', file=sys.stderr)
94
+ sys.exit(1)
95
+
96
+ db_path = args.db or os.path.join(vault_path, '.schist', 'schist.db')
97
+
98
+ # sync sub-dispatch
99
+ if args.command == 'sync':
100
+ if args.sync_action == 'pull':
101
+ sync.sync_pull(args, vault_path, db_path)
102
+ elif args.sync_action == 'push':
103
+ sync.sync_push(args, vault_path, db_path)
104
+ else:
105
+ print('Usage: schist sync {pull|push}', file=sys.stderr)
106
+ sys.exit(1)
107
+ sys.exit(0)
108
+
109
+ dispatch = {
110
+ 'add': commands.add,
111
+ 'link': commands.link,
112
+ 'search': commands.search,
113
+ 'query': commands.query,
114
+ 'build': commands.build,
115
+ 'context': commands.context,
116
+ 'schema': commands.schema,
117
+ }
118
+ dispatch[args.command](args, vault_path, db_path)
119
+
120
+
121
+ if __name__ == '__main__':
122
+ main()