graphcoding 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.
graphcoding/__init__.py CHANGED
@@ -3,4 +3,4 @@
3
3
  Query before you touch code. Design in the graph. Sync as you go.
4
4
  Drift is caught by tooling, not memory.
5
5
  """
6
- __version__ = "0.3.0"
6
+ __version__ = "0.4.0"
graphcoding/cli.py CHANGED
@@ -21,8 +21,9 @@ import sys
21
21
  from . import __version__
22
22
  from .drift import blocking_count, compute_drift, format_report
23
23
  from .scan import scan_repo, trackable
24
- from .store import (DEFAULT_CONFIG, EDGE_TYPES, GRAPH_DIR, NODE_TYPES, Graph,
25
- Node, config_path, find_root, load_config)
24
+ from .store import (DEFAULT_CONFIG, EDGE_TYPE_RE, EDGE_TYPES, GRAPH_DIR,
25
+ NODE_TYPES, Graph, Node, config_path, find_root,
26
+ load_config)
26
27
  from .sync import sync as run_sync
27
28
  from . import hooks as hooks_mod
28
29
 
@@ -109,8 +110,9 @@ def cmd_plan(args) -> None:
109
110
  except ValueError:
110
111
  sys.exit(f"bad --edge '{spec}' (want TYPE:target, e.g. IMPORTS:src/db.py)")
111
112
  etype = etype.upper()
112
- if etype not in EDGE_TYPES:
113
- sys.exit(f"unknown edge type {etype} (one of {', '.join(EDGE_TYPES)})")
113
+ if not EDGE_TYPE_RE.match(etype):
114
+ sys.exit(f"bad edge type {etype} (UPPER_SNAKE word; common: "
115
+ f"{', '.join(EDGE_TYPES)})")
114
116
  node.add_edge(target, etype)
115
117
  existing = g.nodes.get(args.name)
116
118
  if existing and existing.status != "planned" and not args.force:
@@ -136,8 +138,9 @@ def cmd_link(args) -> None:
136
138
  if not src:
137
139
  sys.exit(f"unknown source node {args.source} (plan or scan it first)")
138
140
  etype = args.type.upper()
139
- if etype not in EDGE_TYPES:
140
- sys.exit(f"unknown edge type {etype} (one of {', '.join(EDGE_TYPES)})")
141
+ if not EDGE_TYPE_RE.match(etype):
142
+ sys.exit(f"bad edge type {etype} (UPPER_SNAKE word; common: "
143
+ f"{', '.join(EDGE_TYPES)})")
141
144
  added = src.add_edge(args.target, etype)
142
145
  g.save()
143
146
  note = "" if args.target in g.nodes else " (target not in graph yet — planned work)"
graphcoding/store.py CHANGED
@@ -29,11 +29,17 @@ NODE_TYPES = [
29
29
  "Component", "Hook", "TypeDef", "ServiceDef", "ConfigFile", "Doc",
30
30
  ]
31
31
 
32
+ # Common edge vocabulary — conventions, not a schema. Any UPPER_SNAKE word is
33
+ # a valid edge type (DEPLOYED_IN, PROMOTES_TO, MIRRORS, OWNS, ...). The
34
+ # scanner owns IMPORTS; everything else is human/agent vocabulary.
32
35
  EDGE_TYPES = [
33
36
  "IMPORTS", "CALLS", "CONTAINS", "INHERITS", "IMPLEMENTS",
34
37
  "REFERENCES", "DEPENDS_ON", "RELATED_TO",
38
+ "DEPLOYED_IN", "PROMOTES_TO", "CONFIGURES",
35
39
  ]
36
40
 
41
+ EDGE_TYPE_RE = re.compile(r"^[A-Z][A-Z0-9_]*$")
42
+
37
43
  STATUSES = ["ok", "planned", "needs-analysis", "to-be-deleted"]
38
44
 
39
45
  GRAPH_DIR = ".graphcoding"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphcoding
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Draw the graph of the system you want — then code until the repo matches. Future files and scheduled deletions are graph data; a drift gate blocks commits until code and declared design converge.
5
5
  Author: Mosab Sayyed
6
6
  License: MIT
@@ -0,0 +1,14 @@
1
+ graphcoding/__init__.py,sha256=MMn0Pbniu1mZPj3RAKjaCWKZ7WJLTq_9C70DKDcCjdk,188
2
+ graphcoding/cli.py,sha256=a6zWRG6arGVV0lFUzwxeYoxz4FL84g2vuMaRhLHvnJk,15306
3
+ graphcoding/drift.py,sha256=1_zkh62IfPbX3QCeRhp-L61hl4xv3mkG1ecPfRnklrs,3296
4
+ graphcoding/health.py,sha256=OSWHaDrGpQAJSny7RcYVDDNhvCp6aiJtCYihFtB-qPU,4363
5
+ graphcoding/hooks.py,sha256=wEHJ8INcVMWe-0PpDJ62VyYqUjMiGncSDivqPUBXk-I,2292
6
+ graphcoding/scan.py,sha256=AuMQBeBCwZA-bp59vk07DDuq0iHWvAxWip6IJ4RD6w8,10369
7
+ graphcoding/store.py,sha256=QEVd6otZQKW-VnRZEGEMHATRud7OHGz256IwbhQpseE,8112
8
+ graphcoding/sync.py,sha256=OGSf8VRRLN4eGHF4vW-TZgXhj_ygVzh-bzmn0sB5dw0,3725
9
+ graphcoding-0.4.0.dist-info/licenses/LICENSE,sha256=9VWwPkJqBxrM7dlZAvZWYdGWpopJjb32Rhw2m2ZPTKA,1069
10
+ graphcoding-0.4.0.dist-info/METADATA,sha256=6I1TMCUHkf2aTTQXsrp5OAF6J4IU5CtFYivcSettUqo,15268
11
+ graphcoding-0.4.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
12
+ graphcoding-0.4.0.dist-info/entry_points.txt,sha256=zZ4131jyo5mgfwZZieX7vIknBWpProjLRQMZryBI98w,53
13
+ graphcoding-0.4.0.dist-info/top_level.txt,sha256=WHrV5TVG3R9VZ2QV0fMy0FJBLu2x069m9tjNil6Py-A,12
14
+ graphcoding-0.4.0.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- graphcoding/__init__.py,sha256=2Un0LJlhLKHo0ngdGC_ftGO_44Yj6bfIFTdbTo3cYfk,188
2
- graphcoding/cli.py,sha256=0rcKvNwh-ItRL9qc6IFMXYrtqz0uKPPfUYdyU55tUQI,15184
3
- graphcoding/drift.py,sha256=1_zkh62IfPbX3QCeRhp-L61hl4xv3mkG1ecPfRnklrs,3296
4
- graphcoding/health.py,sha256=OSWHaDrGpQAJSny7RcYVDDNhvCp6aiJtCYihFtB-qPU,4363
5
- graphcoding/hooks.py,sha256=wEHJ8INcVMWe-0PpDJ62VyYqUjMiGncSDivqPUBXk-I,2292
6
- graphcoding/scan.py,sha256=AuMQBeBCwZA-bp59vk07DDuq0iHWvAxWip6IJ4RD6w8,10369
7
- graphcoding/store.py,sha256=bjkve6qwKQSe1K3X90ubN4PgKuFOJPnMvzrYhSOo8is,7796
8
- graphcoding/sync.py,sha256=OGSf8VRRLN4eGHF4vW-TZgXhj_ygVzh-bzmn0sB5dw0,3725
9
- graphcoding-0.3.0.dist-info/licenses/LICENSE,sha256=9VWwPkJqBxrM7dlZAvZWYdGWpopJjb32Rhw2m2ZPTKA,1069
10
- graphcoding-0.3.0.dist-info/METADATA,sha256=LPvvI-shx6HfZaCGvehkuXhV7LC-unLvtMi6qjBcrGs,15268
11
- graphcoding-0.3.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
12
- graphcoding-0.3.0.dist-info/entry_points.txt,sha256=zZ4131jyo5mgfwZZieX7vIknBWpProjLRQMZryBI98w,53
13
- graphcoding-0.3.0.dist-info/top_level.txt,sha256=WHrV5TVG3R9VZ2QV0fMy0FJBLu2x069m9tjNil6Py-A,12
14
- graphcoding-0.3.0.dist-info/RECORD,,