ambitgraph 0.8.3__tar.gz → 0.8.4__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 (103) hide show
  1. {ambitgraph-0.8.3/ambitgraph.egg-info → ambitgraph-0.8.4}/PKG-INFO +1 -1
  2. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/__init__.py +7 -1
  3. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/graph.js +8 -2
  4. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/library.js +7 -1
  5. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/search.js +6 -1
  6. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/siderail.js +16 -5
  7. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/wholemap.js +13 -2
  8. {ambitgraph-0.8.3 → ambitgraph-0.8.4/ambitgraph.egg-info}/PKG-INFO +1 -1
  9. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/pyproject.toml +1 -1
  10. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/LICENSE +0 -0
  11. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/MANIFEST.in +0 -0
  12. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/README.md +0 -0
  13. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_contracts/__init__.py +0 -0
  14. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_contracts/edge.py +0 -0
  15. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_contracts/envelope.py +0 -0
  16. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_contracts/fields.py +0 -0
  17. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_contracts/grant.py +0 -0
  18. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_contracts/household.py +0 -0
  19. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/__init__.py +0 -0
  20. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/__main__.py +0 -0
  21. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/ambit-map-enrich.md +0 -0
  22. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/ambit-mapllm-contract.md +0 -0
  23. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/cli.py +0 -0
  24. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/daemon.py +0 -0
  25. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/dialects/__init__.py +0 -0
  26. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/dialects/contract.py +0 -0
  27. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/dialects/express_pack.py +0 -0
  28. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/dialects/fastapi_pack.py +0 -0
  29. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/dialects/flask_pack.py +0 -0
  30. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/dialects/nextjs_pack.py +0 -0
  31. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/dialects/supabase_pack.py +0 -0
  32. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/explain.py +0 -0
  33. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/families.py +0 -0
  34. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/langmirror.py +0 -0
  35. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/load.py +0 -0
  36. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/mapllm.py +0 -0
  37. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/model.py +0 -0
  38. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/orchestrate.py +0 -0
  39. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/registry.py +0 -0
  40. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_map/serve.py +0 -0
  41. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_telegraph/__init__.py +0 -0
  42. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_telegraph/cli.py +0 -0
  43. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_telegraph/export.py +0 -0
  44. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_telegraph/ledger.py +0 -0
  45. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_telegraph/responsibility.py +0 -0
  46. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambit_telegraph/store.py +0 -0
  47. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/WALKTHROUGH.md +0 -0
  48. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/__init__.py +0 -0
  49. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/__main__.py +0 -0
  50. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/_delimited.py +0 -0
  51. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/cli.py +0 -0
  52. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/cockpit.py +0 -0
  53. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/codelib.py +0 -0
  54. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/config.py +0 -0
  55. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/console.py +0 -0
  56. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/demo.py +0 -0
  57. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/design_tokens.py +0 -0
  58. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/docs_discovery.py +0 -0
  59. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/doctor.py +0 -0
  60. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/duplication.py +0 -0
  61. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/edges.py +0 -0
  62. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/emit.py +0 -0
  63. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/engine_identity.py +0 -0
  64. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/estimate.py +0 -0
  65. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/eval.py +0 -0
  66. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/feeds.py +0 -0
  67. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/gate.py +0 -0
  68. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/gate_check.py +0 -0
  69. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/gate_server.py +0 -0
  70. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/harvest.py +0 -0
  71. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/inventory.py +0 -0
  72. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/jscalls.py +0 -0
  73. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/langs.py +0 -0
  74. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/mds.py +0 -0
  75. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/merge.py +0 -0
  76. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/merge_jsp.py +0 -0
  77. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/_init_js.py +0 -0
  78. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/filterpanel.js +0 -0
  79. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/next_embed.css +0 -0
  80. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/omniscient_next/standalone.py +0 -0
  81. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/parameterize.py +0 -0
  82. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/pipeline.py +0 -0
  83. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/portal.py +0 -0
  84. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/prompts.py +0 -0
  85. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/pycalls.py +0 -0
  86. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/ratify.py +0 -0
  87. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/report.py +0 -0
  88. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/reports.py +0 -0
  89. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/responsibility.py +0 -0
  90. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/sample.py +0 -0
  91. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/secretary.py +0 -0
  92. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/shell.py +0 -0
  93. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/stages.py +0 -0
  94. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/symbols.py +0 -0
  95. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/tables.py +0 -0
  96. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/tasks.py +0 -0
  97. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph/urcode.py +0 -0
  98. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph.egg-info/SOURCES.txt +0 -0
  99. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph.egg-info/dependency_links.txt +0 -0
  100. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph.egg-info/entry_points.txt +0 -0
  101. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph.egg-info/requires.txt +0 -0
  102. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/ambitgraph.egg-info/top_level.txt +0 -0
  103. {ambitgraph-0.8.3 → ambitgraph-0.8.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ambitgraph
3
- Version: 0.8.3
3
+ Version: 0.8.4
4
4
  Summary: Read-only codebase scan: reusable units, families, roles, ownership candidates, duplication.
5
5
  Author: AmbitGraph
6
6
  License: Proprietary
@@ -140,7 +140,13 @@ def render_screen(run_path: str) -> str:
140
140
  scripts (modules + payload + wiring). The caller (shell.py) owns the
141
141
  absence branch; calling this without data is a build error."""
142
142
  data = build_data(run_path)
143
- payload = json.dumps(data, separators=(",", ":")).replace("</", "<\\/")
143
+ # EVERY `<` becomes an escaped unicode point, not just the ones that open a
144
+ # closing tag. Replacing `</` alone defends against `</script>` and against
145
+ # nothing else: a scanned name containing `<!--` opens a comment inside the
146
+ # script block and swallows the payload after it, and `<script` opens a
147
+ # second one. The escape is invisible to JSON.parse, so the data a reader
148
+ # gets is unchanged -- this is the cockpit's own pattern, not a new one.
149
+ payload = json.dumps(data, separators=(",", ":")).replace("<", "\\u003c")
144
150
  return (
145
151
  '<div class="cp-next-shell">'
146
152
  '<div class="sh-top">'
@@ -153,7 +153,13 @@ class SingleGraph {
153
153
  destroy(){ this.container.innerHTML=""; }
154
154
 
155
155
  /* ---------------- internals ---------------- */
156
- _esc(s){ return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;"); }
156
+ /* All five characters that change how markup is read. This pane writes a
157
+ folder's name into data-expand="...", so an unescaped quote in a directory
158
+ name ends that attribute early and the rest of the name is read as markup.
159
+ The ampersand is replaced FIRST, or a later substitution's own output is
160
+ escaped a second time. */
161
+ _esc(s){ return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;")
162
+ .replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;"); }
157
163
 
158
164
  _neigh(applyFilter=true){
159
165
  // inbound/outbound entries, deduped per file, weights summed
@@ -214,7 +220,7 @@ class SingleGraph {
214
220
  '<div class="sg-e-name"><span class="sg-e-dot" style="background:'+
215
221
  (FC[n.f]||"#8b96a8")+'"></span>'+esc(n.id.split("/").pop())+'</div>'+
216
222
  '<div class="sg-e-path">'+esc(n.id)+'</div>'+
217
- '<div class="sg-e-meta">'+n.d+' links · '+n.in+' inbound · '+n.f+'/</div></div>'; });
223
+ '<div class="sg-e-meta">'+n.d+' links · '+n.in+' inbound · '+esc(n.f)+'/</div></div>'; });
218
224
  h+='</div></div>';
219
225
  this._canvas.innerHTML=h;
220
226
  }
@@ -74,7 +74,13 @@ class LibraryView {
74
74
  if (i >= 0) { this._state = {...this._state, level:"file", file:i}; this._render(); } }
75
75
  home() { this._state = {...this._state, level:"home"}; this._render(); }
76
76
 
77
- _esc(s){ return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;"); }
77
+ /* All five characters that change how markup is read. Two are enough for
78
+ text between tags and are no defence at all for a value placed inside a
79
+ quoted attribute, where one unescaped quote ends the attribute early and
80
+ everything after it is read as markup. The ampersand is replaced FIRST,
81
+ or a later substitution's own output is escaped a second time. */
82
+ _esc(s){ return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;")
83
+ .replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;"); }
78
84
  _cat(key){ return this._CATS.find(c => c[0] === key); }
79
85
 
80
86
  _click(e) {
@@ -61,7 +61,12 @@ class SearchDrop {
61
61
  if (m.syms.length) { return this._data.nodes[m.syms[0][1]].id; }
62
62
  return null;
63
63
  }
64
- _esc(s) { return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;"); }
64
+ /* All five characters that change how markup is read. Two are enough for
65
+ text between tags and are no defence at all for a value placed inside a
66
+ quoted attribute. The ampersand is replaced FIRST, or a later
67
+ substitution's own output is escaped a second time. */
68
+ _esc(s) { return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;")
69
+ .replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"); }
65
70
  _render() {
66
71
  const SEARCH_ROW_CAP = 12;
67
72
  const m = this.matches(this._input.value);
@@ -3,6 +3,17 @@
3
3
  navigation lands (a test pins that retirement). Architecture constraints:
4
4
  one view, one class, all CSS class names prefixed to avoid collisions,
5
5
  and only the documented public surface is used. */
6
+ /* All five characters that change how markup is read. This module had none:
7
+ its labels and notes are file and folder names from the scanned repository
8
+ and they were written straight into innerHTML, so a name decided markup on
9
+ a page that opens by default. The ampersand is replaced FIRST, or a later
10
+ substitution's own output is escaped a second time.
11
+ The name is module-local because every module is concatenated into one
12
+ script and a bare `esc` would collide; one shared escaper replacing all of
13
+ these is the next release's work, not this patch's. */
14
+ function _srEsc(s){ return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;")
15
+ .replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;"); }
16
+
6
17
  /* ============================================================
7
18
  SideRail — the left rail with NESTED quick-nav: entry points
8
19
  nested under Graph, categories under Library, each group
@@ -36,8 +47,8 @@ class SideRail {
36
47
  b.className = "sr-item"; b.tabIndex = 0; b.setAttribute("role", "button");
37
48
  b.innerHTML =
38
49
  (it.children ? "<span class='sr-caret'>▸</span>" : "<span class='sr-caret sr-blank'></span>") +
39
- "<span class='sr-label'>" + it.label + "</span>" +
40
- (it.note ? "<span class='sr-note'>" + it.note + "</span>" : "");
50
+ "<span class='sr-label'>" + _srEsc(it.label) + "</span>" +
51
+ (it.note ? "<span class='sr-note'>" + _srEsc(it.note) + "</span>" : "");
41
52
  const switchTo = () => { if (typeof opts.onSwitch === "function") opts.onSwitch(it.key); };
42
53
  b.querySelector(".sr-label").onclick = switchTo;
43
54
  if (it.note) b.querySelector(".sr-note").onclick = switchTo;
@@ -58,9 +69,9 @@ class SideRail {
58
69
  it.children.forEach(c => {
59
70
  const k = document.createElement("div");
60
71
  k.className = "sr-kid"; k.tabIndex = 0; k.setAttribute("role", "button");
61
- k.innerHTML = (c.color ? "<span class='sr-dot' style='background:"+c.color+"'></span>" : "") +
62
- "<span class='sr-klabel'>" + c.label + "</span>" +
63
- (c.note ? "<span class='sr-note'>" + c.note + "</span>" : "");
72
+ k.innerHTML = (c.color ? "<span class='sr-dot' style='background:"+_srEsc(c.color)+"'></span>" : "") +
73
+ "<span class='sr-klabel'>" + _srEsc(c.label) + "</span>" +
74
+ (c.note ? "<span class='sr-note'>" + _srEsc(c.note) + "</span>" : "");
64
75
  k.onclick = () => c.onClick && c.onClick();
65
76
  k.addEventListener("keydown", e => { if (e.key === "Enter") k.onclick(); });
66
77
  kids.appendChild(k);
@@ -2,6 +2,17 @@
2
2
  implementation and is expected to be retired once the map product view
3
3
  ships (a test pins this until then). Architecture constraints: one view,
4
4
  one class, CSS prefixed to this module, public surface only. */
5
+ /* All five characters that change how markup is read. This module had none:
6
+ the folder legend wrote a scanned folder's name straight into innerHTML, on
7
+ the pane the page opens on, so the name decided markup with no click at all.
8
+ The ampersand is replaced FIRST, or a later substitution's own output is
9
+ escaped a second time.
10
+ The name is module-local because every module is concatenated into one
11
+ script and a bare `esc` would collide; one shared escaper replacing all of
12
+ these is the next release's work, not this patch's. */
13
+ function _wmEsc(s){ return String(s).replace(/&/g,"&amp;").replace(/</g,"&lt;")
14
+ .replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;"); }
15
+
5
16
  /* ============================================================
6
17
  WholeMap — the whole-graph view, as its own module.
7
18
 
@@ -471,8 +482,8 @@ class WholeMap {
471
482
  /* chips — computed from THIS repo's data, never assumed */
472
483
  data.folders.forEach(f=>{ const [name,count]=f;
473
484
  const el=document.createElement("span"); el.className="wm-chip"; el.tabIndex=0;
474
- el.innerHTML="<span class='wm-sw' style='background:"+folderColor[name]+"'></span>"
475
- +name+" "+count;
485
+ el.innerHTML="<span class='wm-sw' style='background:"+_wmEsc(folderColor[name])+"'></span>"
486
+ +_wmEsc(name)+" "+count;
476
487
  el.onclick=()=>{ traced = traced===name? null : name;
477
488
  chipbar.querySelectorAll(".wm-chip").forEach(c=>c.classList.remove("wm-on"));
478
489
  if(traced) el.classList.add("wm-on");
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ambitgraph
3
- Version: 0.8.3
3
+ Version: 0.8.4
4
4
  Summary: Read-only codebase scan: reusable units, families, roles, ownership candidates, duplication.
5
5
  Author: AmbitGraph
6
6
  License: Proprietary
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ambitgraph"
7
- version = "0.8.3"
7
+ version = "0.8.4"
8
8
  description = "Read-only codebase scan: reusable units, families, roles, ownership candidates, duplication."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes