ambitgraph 0.5.0__tar.gz → 0.7.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.
Files changed (92) hide show
  1. {ambitgraph-0.5.0/ambitgraph.egg-info → ambitgraph-0.7.0}/PKG-INFO +11 -1
  2. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/README.md +10 -0
  3. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/export.py +117 -5
  4. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/graph.py +1228 -141
  5. ambitgraph-0.7.0/ambit_map/island_layout.py +462 -0
  6. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/islands.py +150 -9
  7. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/langmirror.py +80 -13
  8. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/library.py +474 -119
  9. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/objects.py +78 -27
  10. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/page.py +48 -4
  11. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/registry.py +318 -13
  12. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/serve.py +30 -49
  13. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/theme.py +58 -9
  14. ambitgraph-0.7.0/ambitgraph/__init__.py +39 -0
  15. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/cli.py +10 -0
  16. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/codelib.py +16 -0
  17. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/edges.py +273 -5
  18. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/langs.py +177 -4
  19. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/shell.py +161 -83
  20. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/symbols.py +2441 -30
  21. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/tables.py +6 -3
  22. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/urcode.py +45 -3
  23. {ambitgraph-0.5.0 → ambitgraph-0.7.0/ambitgraph.egg-info}/PKG-INFO +11 -1
  24. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/pyproject.toml +1 -1
  25. ambitgraph-0.5.0/ambit_map/island_layout.py +0 -289
  26. ambitgraph-0.5.0/ambitgraph/__init__.py +0 -6
  27. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/LICENSE +0 -0
  28. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/MANIFEST.in +0 -0
  29. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/__init__.py +0 -0
  30. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/__main__.py +0 -0
  31. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/ambit-map-enrich.md +0 -0
  32. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/ambit-mapllm-contract.md +0 -0
  33. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/cli.py +0 -0
  34. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/daemon.py +0 -0
  35. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/dialects/__init__.py +0 -0
  36. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/dialects/contract.py +0 -0
  37. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/dialects/express_pack.py +0 -0
  38. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/dialects/fastapi_pack.py +0 -0
  39. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/dialects/flask_pack.py +0 -0
  40. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/dialects/nextjs_pack.py +0 -0
  41. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/dialects/supabase_pack.py +0 -0
  42. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/families.py +0 -0
  43. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/judged.py +0 -0
  44. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/kitdemo.py +0 -0
  45. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/load.py +0 -0
  46. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/mapllm.py +0 -0
  47. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/matched.py +0 -0
  48. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/model.py +0 -0
  49. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/orchestrate.py +0 -0
  50. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/paths.py +0 -0
  51. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambit_map/unitpage.py +0 -0
  52. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/WALKTHROUGH.md +0 -0
  53. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/__main__.py +0 -0
  54. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/cockpit.py +0 -0
  55. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/config.py +0 -0
  56. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/console.py +0 -0
  57. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/demo.py +0 -0
  58. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/docs_discovery.py +0 -0
  59. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/doctor.py +0 -0
  60. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/duplication.py +0 -0
  61. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/emit.py +0 -0
  62. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/engine_identity.py +0 -0
  63. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/estimate.py +0 -0
  64. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/eval.py +0 -0
  65. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/feeds.py +0 -0
  66. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/gate.py +0 -0
  67. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/gate_check.py +0 -0
  68. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/gate_server.py +0 -0
  69. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/harvest.py +0 -0
  70. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/inventory.py +0 -0
  71. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/jscalls.py +0 -0
  72. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/mds.py +0 -0
  73. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/merge.py +0 -0
  74. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/merge_jsp.py +0 -0
  75. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/parameterize.py +0 -0
  76. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/pipeline.py +0 -0
  77. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/portal.py +0 -0
  78. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/prompts.py +0 -0
  79. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/pycalls.py +0 -0
  80. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/ratify.py +0 -0
  81. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/report.py +0 -0
  82. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/reports.py +0 -0
  83. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/sample.py +0 -0
  84. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/secretary.py +0 -0
  85. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/stages.py +0 -0
  86. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph/tasks.py +0 -0
  87. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph.egg-info/SOURCES.txt +0 -0
  88. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph.egg-info/dependency_links.txt +0 -0
  89. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph.egg-info/entry_points.txt +0 -0
  90. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph.egg-info/requires.txt +0 -0
  91. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/ambitgraph.egg-info/top_level.txt +0 -0
  92. {ambitgraph-0.5.0 → ambitgraph-0.7.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ambitgraph
3
- Version: 0.5.0
3
+ Version: 0.7.0
4
4
  Summary: Read-only codebase scan: reusable units, families, roles, ownership candidates, duplication.
5
5
  Author: AmbitGraph
6
6
  License: Proprietary
@@ -53,6 +53,16 @@ Your codebase is displayed in your browser as local webpages.
53
53
 
54
54
  It does not make any changes to your codebase.
55
55
 
56
+ ## Update
57
+
58
+ ```
59
+ pip install --upgrade ambitgraph
60
+ ```
61
+
62
+ `python -m ambitgraph --version` (or `ambit --version`) prints the version you have.
63
+
64
+ Updating the tool is not the same as refreshing a map: after your code changes, just run `python -m ambitgraph map <folder>` again.
65
+
56
66
  ## A GRAPH
57
67
 
58
68
  Modules, Classes, Imports, Calls, DB Tables, anything in your code mapped on its connections.
@@ -25,6 +25,16 @@ Your codebase is displayed in your browser as local webpages.
25
25
 
26
26
  It does not make any changes to your codebase.
27
27
 
28
+ ## Update
29
+
30
+ ```
31
+ pip install --upgrade ambitgraph
32
+ ```
33
+
34
+ `python -m ambitgraph --version` (or `ambit --version`) prints the version you have.
35
+
36
+ Updating the tool is not the same as refreshing a map: after your code changes, just run `python -m ambitgraph map <folder>` again.
37
+
28
38
  ## A GRAPH
29
39
 
30
40
  Modules, Classes, Imports, Calls, DB Tables, anything in your code mapped on its connections.
@@ -2,10 +2,13 @@
2
2
 
3
3
  Pure over the model + a writer: `page_rows` is PURE (no I/O, no clock) and
4
4
  `write_export` writes what its `render` callable returns. Imports:
5
- registry, objects, families, graph, library (same package only) plus
6
- `hashlib`, `collections`, `pathlib`, `urllib.parse.quote`. It never imports
7
- `serve` -- `serve` imports IT (U4-F/U4-G), so there is no cycle and
8
- `write_export` is unit-testable against a fake router/renderer (T-36).
5
+ registry, objects, families, graph, library, page (same package only) plus
6
+ `hashlib`, `collections`, `pathlib`, `urllib.parse.quote`. `page` added
7
+ 2026-09-06 for `resolve_overview_state`/`resolve_library_extras` -- `page`
8
+ does not import `export`, so this stays a one-way edge, not a cycle. It
9
+ never imports `serve` -- `serve` imports IT (U4-F/U4-G), so there is no
10
+ cycle and `write_export` is unit-testable against a fake router/renderer
11
+ (T-36).
9
12
  """
10
13
  import collections
11
14
  import json
@@ -18,6 +21,7 @@ from . import objects as ob
18
21
  from . import families as fam
19
22
  from . import graph as gph
20
23
  from . import library as lib
24
+ from . import page as pg
21
25
 
22
26
  GRAPH_EXPORT_CAP = 200 # the brief's cap
23
27
  EXPORT_INDEX = "index.html"
@@ -42,6 +46,25 @@ ENRICH_DOC_NAME = "ambit-map-enrich.md"
42
46
  # generalisation of ambit-map-enrich.md's own producer-portability clause.
43
47
  CONTRACT_DOC_NAME = "ambit-mapllm-contract.md"
44
48
 
49
+ # 2026-09-05 (embed-fragment ruling): a
50
+ # SECOND artifact for the Graph screen, alongside map.html -- canvas and
51
+ # its own interaction only, for a host (Omniscient's UrCode tab) that
52
+ # integrates it as native DOM instead of serving map.html's full page
53
+ # inside an iframe. `embed/<kind>.html` is IDP's own proposed naming,
54
+ # accepted in the ruling. One default-seed fragment for v1 (IDP's own
55
+ # call, 2026-09-05: the dashboard shows THE map, a sha-gated regenerate
56
+ # keeps one fragment cheap and current, and per-seed fragments would
57
+ # multiply for clicks that may never come) -- not every graph_keys() seed
58
+ # page.py:page_rows() also pre-renders.
59
+ EMBED_GRAPH_REL = "embed/graph.html"
60
+ # 2026-09-06 (IDP's ur5 inline-switch wave, "the tile should switch what
61
+ # is displayed below the tiles"): the Whole-map (islands) tab's own
62
+ # fragment, beside embed/graph.html under the SAME ur4 contract.
63
+ EMBED_OVERVIEW_REL = "embed/overview.html"
64
+ # 2026-09-06 (founder live-page review, item 1): the Library home's own
65
+ # fragment, beside embed/graph.html and embed/overview.html.
66
+ EMBED_LIBRARY_REL = "embed/library.html"
67
+
45
68
  Row = collections.namedtuple("Row", "rel route_path raw_query depth")
46
69
 
47
70
  _SLUG_HTML_RE = re.compile(r".+-[0-9a-f]{6}\.html$")
@@ -298,6 +321,85 @@ def write_export(state, out_dir, route, render, now_iso):
298
321
  if row.rel == EXPORT_INDEX:
299
322
  index_text = html
300
323
 
324
+ # 2026-09-05 (embed-fragment ruling): the default-seed graph fragment,
325
+ # written OUTSIDE the row loop above because it is not a `route()`-
326
+ # addressable page -- no reader ever navigates to embed/graph.html
327
+ # directly, an embedder's own build step reads it. seed_id=None reuses
328
+ # render_graph's own always-seeded resolution (the same fallback
329
+ # map.html's own row already relies on via page_rows' index_query), so
330
+ # this can never silently pick a different seed than map.html draws.
331
+ # "" (no real canvas -- a damaged model, or the map_repo's own
332
+ # zero-unit branch) means no file at all, never an empty one an
333
+ # embedder would have to special-case; its own absence is the signal.
334
+ embed_frag = gph.render_graph_embed_fragment(model, dialects=dialects)
335
+ embed_rel = None
336
+ if embed_frag:
337
+ # render_graph_embed_fragment builds its hrefs the SAME way
338
+ # render_graph does (registry.href_seed_unit/href_table, absolute
339
+ # /unit?u=.../table?t=... paths meant for a SERVED map) -- every
340
+ # other exported page gets those rewritten to real static
341
+ # sibling-file paths by objects.document()'s own static_rewrite
342
+ # call, which this fragment never passes through (it skips
343
+ # document() by design, no hero/nav to assemble). Without this,
344
+ # a node click in an embedder's integrated canvas would 404
345
+ # against a route that only exists in served mode -- exactly the
346
+ # "navigate to the export's per-seed page" IDP's own build
347
+ # depends on. depth=1 matches embed/graph.html's own real
348
+ # location, same as graph/<slug>.html's row above.
349
+ embed_ctx = reg.StaticCtx(EMBED_GRAPH_REL.count("/"), graph_slugs, "")
350
+ embed_frag = reg.static_rewrite(embed_frag, embed_ctx)
351
+ # A4: resolve `N noun(s)` markers here too -- objects.document()
352
+ # does this for every real page (customer voice is not a property
353
+ # of how a page was served), but this fragment never passes
354
+ # through document() at all, so nothing else ever will.
355
+ embed_frag = reg.inflect_counts(embed_frag)
356
+ embed_p = out_dir / EMBED_GRAPH_REL
357
+ embed_p.parent.mkdir(parents=True, exist_ok=True)
358
+ embed_p.write_text(embed_frag, encoding="utf-8", newline="\n")
359
+ embed_rel = EMBED_GRAPH_REL
360
+
361
+ # 2026-09-06 (IDP's ur5 inline-switch wave): the SAME embed-fragment
362
+ # shape for the Whole-map (islands) tab, beside embed/graph.html. The
363
+ # flash draws no hrefs at all (opening-view ruling section 4.6, no
364
+ # hit-testing) so static_rewrite/inflect_counts have nothing to touch
365
+ # today -- called anyway, for the same reason the graph fragment
366
+ # calls them unconditionally: this fragment skips objects.document()
367
+ # by design, so nothing else ever will if render_islands_canvas later
368
+ # grows either shape.
369
+ ov_state, ov_layout = pg.resolve_overview_state(model, dialects, state.run_dir)
370
+ overview_frag = gph.render_overview_embed_fragment(ov_layout) if ov_layout else ""
371
+ overview_rel = None
372
+ if overview_frag:
373
+ overview_ctx = reg.StaticCtx(EMBED_OVERVIEW_REL.count("/"), graph_slugs, "")
374
+ overview_frag = reg.static_rewrite(overview_frag, overview_ctx)
375
+ overview_frag = reg.inflect_counts(overview_frag)
376
+ overview_p = out_dir / EMBED_OVERVIEW_REL
377
+ overview_p.parent.mkdir(parents=True, exist_ok=True)
378
+ overview_p.write_text(overview_frag, encoding="utf-8", newline="\n")
379
+ overview_rel = EMBED_OVERVIEW_REL
380
+
381
+ # 2026-09-06 (founder live-page review, item 1): the SAME embed-
382
+ # fragment shape for the Library home, beside embed/graph.html and
383
+ # embed/overview.html. `gap`/`grammarless_table` are the wall-legal
384
+ # seams lib.render_library's own docstring names -- computed here via
385
+ # page.resolve_library_extras, the SAME helper serve.py's own library
386
+ # dispatch now calls, so this can never silently diverge on either
387
+ # fact from the served route's own library.html.
388
+ lib_gap, lib_grammarless = pg.resolve_library_extras(model, dialects)
389
+ library_frag = lib.render_library_embed_fragment(
390
+ model, dialects=dialects, judged=state.judged, envelope=state.envelope,
391
+ gap=lib_gap, grammarless_table=lib_grammarless,
392
+ mapllm_stranger_groups=state.mapllm_stranger_groups)
393
+ library_rel = None
394
+ if library_frag:
395
+ library_ctx = reg.StaticCtx(EMBED_LIBRARY_REL.count("/"), graph_slugs, "")
396
+ library_frag = reg.static_rewrite(library_frag, library_ctx)
397
+ library_frag = reg.inflect_counts(library_frag)
398
+ library_p = out_dir / EMBED_LIBRARY_REL
399
+ library_p.parent.mkdir(parents=True, exist_ok=True)
400
+ library_p.write_text(library_frag, encoding="utf-8", newline="\n")
401
+ library_rel = EMBED_LIBRARY_REL
402
+
301
403
  # W6 D-8/D-10 (THE PACKAGING ITEM): drop ambit-map-enrich.md beside the
302
404
  # export so it is ALWAYS present -- even for a wheel-only install where
303
405
  # a repo checkout's own top-level copy is absent -- the SAME copy-beside
@@ -323,5 +425,15 @@ def write_export(state, out_dir, route, render, now_iso):
323
425
  # again would name it twice in the manifest. C3: the contract doc joins
324
426
  # ENRICH_DOC_NAME here for the identical reason -- an un-manifested copy
325
427
  # would be a stray file the NEXT export cannot recognise as its own.
326
- _write_manifest(out_dir, [row.rel for row in rows] + [ENRICH_DOC_NAME, CONTRACT_DOC_NAME])
428
+ # embed_rel is None (never named) exactly when no file was written --
429
+ # naming an absent path here would make the NEXT export's prune try to
430
+ # unlink a file that was never there.
431
+ extra = [ENRICH_DOC_NAME, CONTRACT_DOC_NAME]
432
+ if embed_rel is not None:
433
+ extra.append(embed_rel)
434
+ if overview_rel is not None:
435
+ extra.append(overview_rel)
436
+ if library_rel is not None:
437
+ extra.append(library_rel)
438
+ _write_manifest(out_dir, [row.rel for row in rows] + extra)
327
439
  return index_text