sourcecode 5.5.5__py3-none-any.whl → 5.6.1__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.

Potentially problematic release.


This version of sourcecode might be problematic. Click here for more details.

sourcecode/__init__.py CHANGED
@@ -4,4 +4,4 @@ ASK Engine is the product. ``ask`` is the canonical CLI command; ``sourcecode``
4
4
  the legacy compatibility alias and the Python/PyPI package name. See
5
5
  docs/PRODUCT_IDENTITY.md (normative)."""
6
6
 
7
- __version__ = "5.5.5"
7
+ __version__ = "5.6.1"
@@ -0,0 +1,47 @@
1
+ ASK Engine Proprietary License
2
+ Version 1.0, effective 2026-08-13
3
+
4
+ Copyright (c) 2026 Dominique Haroun. All rights reserved.
5
+
6
+ 1. Scope
7
+
8
+ This license applies to ASK Engine version 5.6.1 and later, including its source
9
+ code, documentation, and distributed artifacts (the "Software"). It does not
10
+ alter the license of versions 5.5.6 and earlier, which were distributed under
11
+ the Apache License, Version 2.0. Grants made for those earlier versions remain
12
+ governed by their published license terms.
13
+
14
+ 2. No Implied Grant
15
+
16
+ Except under a separate written agreement signed by Dominique Haroun, no right
17
+ or license is granted to use, copy, modify, distribute, sublicense, sell,
18
+ reverse engineer, or create derivative works of the Software. Possession of a
19
+ copy, access to a repository, or access to a distributed artifact does not
20
+ create an implied license.
21
+
22
+ 3. Third-Party Materials
23
+
24
+ Third-party dependencies and materials included with the Software remain subject
25
+ to their own license terms. This license does not supersede those terms.
26
+
27
+ 4. Trademarks
28
+
29
+ "ASK Engine", "ASK", and associated marks are identifiers of the Software.
30
+ No trademark license is granted except as required to identify an unmodified,
31
+ lawfully obtained copy of the Software.
32
+
33
+ 5. No Warranty
34
+
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE,
37
+ AND NON-INFRINGEMENT. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE COPYRIGHT
38
+ HOLDER SHALL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING
39
+ FROM OR IN CONNECTION WITH THE SOFTWARE.
40
+
41
+ 6. Contact
42
+
43
+ Commercial, evaluation, redistribution, and contribution terms require a
44
+ written agreement with Dominique Haroun.
45
+
46
+ This license text is an operational policy draft and must be reviewed by
47
+ qualified counsel before distribution to third parties.
@@ -0,0 +1,8 @@
1
+ ASK Engine
2
+ Copyright (c) 2026 Dominique Haroun. All rights reserved.
3
+
4
+ ASK Engine and its source code were originally created and developed by
5
+ Dominique Haroun.
6
+
7
+ This NOTICE applies to ASK Engine 5.6.1 and later. Earlier releases may carry
8
+ different license terms; see the license distributed with the applicable release.
@@ -136,7 +136,7 @@ pipx install sourcecode # isolated install, no venv needed
136
136
 
137
137
  # Verify
138
138
  ask version
139
- # ask 5.5.5
139
+ # ask 5.6.1
140
140
  ```
141
141
 
142
142
  Requires Python 3.9+.
@@ -157,7 +157,10 @@ On success:
157
157
  {"status": "activated", "plan": "pro", "features": ["impact", "review-pr", "fix-bug", "modernize", "generate-tests"]}
158
158
  ```
159
159
 
160
- License is cached in `~/.sourcecode/license.json` and re-validated every 24 hours. Works offline after first activation — network errors keep the cached state.
160
+ License is cached in `~/.ask/license.json` and re-validated every 24 hours.
161
+ The legacy `~/.sourcecode/license.json` location remains readable for existing
162
+ installations. Works offline after first activation — network errors keep the
163
+ cached state.
161
164
 
162
165
  ---
163
166
 
sourcecode/cli.py CHANGED
@@ -1392,6 +1392,23 @@ def _analysis_budget(command: str) -> dict[str, Any]:
1392
1392
  }
1393
1393
 
1394
1394
 
1395
+ def _migrate_check_output_hint(*, compact: bool, min_severity: str) -> str:
1396
+ """Build the output-size hint from the flags the caller already used."""
1397
+ ways_out: list[str] = []
1398
+ if not compact:
1399
+ ways_out.append("--compact (bounded decision summary, same report)")
1400
+ if min_severity != "high":
1401
+ ways_out.append("--min-severity high to drop low-severity findings")
1402
+ ways_out.append("--output FILE to save to disk")
1403
+ ways_out.append("--force to bypass this guard")
1404
+ prefix = (
1405
+ "No smaller inline variant is available with the current flags; "
1406
+ if compact and min_severity == "high"
1407
+ else "Use "
1408
+ )
1409
+ return prefix + ", ".join(ways_out) + "."
1410
+
1411
+
1395
1412
  def _budget_evidence(command: str, path: "Optional[Path]") -> "tuple[Optional[str], Optional[str]]":
1396
1413
  """(measured anchors for this command, size of this repository) — or Nones.
1397
1414
 
@@ -1439,6 +1456,8 @@ def _enforce_analysis_budget(
1439
1456
  return
1440
1457
  source = budget.get("configured_source")
1441
1458
  from sourcecode.phased_run import budget_provenance, budget_warning
1459
+ if not getattr(sys.stderr, "isatty", lambda: False)():
1460
+ return
1442
1461
 
1443
1462
  if float(configured) >= recommended:
1444
1463
  # C3-83: over the floor there is no advice to give, and there is still a
@@ -6311,9 +6330,8 @@ def impact_cmd(
6311
6330
 
6312
6331
  _enforce_format("impact", format)
6313
6332
 
6314
- from sourcecode.repository_ir import (
6315
- build_repo_ir, find_java_files, compute_blast_radius,
6316
- )
6333
+ from sourcecode.repository_ir import find_java_files, compute_blast_radius
6334
+ from sourcecode.context_graph import ContextGraph
6317
6335
  from sourcecode.output_budget import BUDGET_IMPACT
6318
6336
 
6319
6337
  # Legacy-compat: old syntax was `impact <path> <target>`.
@@ -6366,9 +6384,16 @@ def impact_cmd(
6366
6384
  return
6367
6385
 
6368
6386
  _prog = Progress()
6369
- _prog.start(f"building IR ({len(file_list)} files) for impact analysis")
6387
+ _prog.start(f"building CIR ({len(file_list)} files) for impact analysis")
6370
6388
  try:
6371
- ir = build_repo_ir(file_list, root)
6389
+ # `impact-chain` resolves callers from the canonical IR, whose typed body
6390
+ # facts contribute method-level call edges. Reading the legacy parse-only
6391
+ # IR here made `impact` miss static calls (including locator accessors).
6392
+ from sourcecode import context_cache as _ctxcache
6393
+ try:
6394
+ cir = _ctxcache.shared_cir(root, file_list, progress=_work_sink(_prog))
6395
+ except Exception:
6396
+ cir = ContextGraph.build(file_list, root, progress=_work_sink(_prog)).cir
6372
6397
  finally:
6373
6398
  _prog.finish()
6374
6399
 
@@ -6379,7 +6404,7 @@ def impact_cmd(
6379
6404
  # skipped the budget when writing to a file (C2-2).
6380
6405
  _to_file = output_path is not None
6381
6406
  result = compute_blast_radius(
6382
- ir, target, max_depth=depth, list_limit=0 if _to_file else None, root=root
6407
+ cir._raw_ir, target, max_depth=depth, list_limit=0 if _to_file else None, root=root
6383
6408
  )
6384
6409
  result = _apply_budget(result, BUDGET_IMPACT, label="impact", output_path=output_path)
6385
6410
  if _misread and result.get("resolution") == "not_found":
@@ -9244,6 +9269,7 @@ def spring_audit_cmd(
9244
9269
  _ris_sa(target, data)
9245
9270
  except Exception:
9246
9271
  pass
9272
+ output = _serialize_dict(data, format)
9247
9273
  finally:
9248
9274
  # C3-54: `done` must not claim the answer exists before it does. The
9249
9275
  # field log showed `[ask] done (6.8m)` printed, then the process torn
@@ -9259,21 +9285,6 @@ def spring_audit_cmd(
9259
9285
  )
9260
9286
  elif format == "github-comment":
9261
9287
  output = _render_spring_audit_github_comment(combined, min_severity)
9262
- else:
9263
- _full_data = combined.to_dict()
9264
- _bounded_default = (
9265
- not compact and output_path is None and format == "json" and not table
9266
- and len(_json.dumps(_full_data, ensure_ascii=False).encode("utf-8")) > 50_000
9267
- )
9268
- data = combined.to_compact_dict() if compact or _bounded_default else _full_data
9269
- if _bounded_default:
9270
- data.pop("mode", None)
9271
- data["default_output"] = "bounded"
9272
- data.pop("compact_note", None)
9273
- data["stdout_budget_note"] = (
9274
- "Capped by the stdout payload budget; use --output <file> for the complete report."
9275
- )
9276
- output = _serialize_dict(data, format)
9277
9288
 
9278
9289
  # F-AV: our own readers ask for the count under either spelling — the break
9279
9290
  # is meant for a consumer that never asked whether the run finished.
@@ -11191,11 +11202,7 @@ def migrate_check_cmd(
11191
11202
  "OUTPUT_TOO_LARGE",
11192
11203
  f"Estimated output is ~{_mig_tokens_est // 1000}K tokens — too large for "
11193
11204
  "most LLM context windows.",
11194
- hint=(
11195
- "Use --compact (bounded decision summary, same report), "
11196
- "--min-severity high to drop low-severity findings, "
11197
- "--output FILE to save to disk, or --force to bypass this guard."
11198
- ),
11205
+ hint=_migrate_check_output_hint(compact=compact, min_severity=min_severity),
11199
11206
  expected="Output under 50K estimated tokens.",
11200
11207
  )
11201
11208
  raise typer.Exit(1)
@@ -12695,17 +12702,18 @@ def version_cmd(
12695
12702
  copy: bool = _copy_option(),
12696
12703
  output_path: Optional[Path] = _output_option(),
12697
12704
  ) -> None:
12698
- """Show version and exit.
12705
+ """Show version, attribution, license and build provenance.
12699
12706
 
12700
12707
  Outputs human-readable text on interactive terminals.
12701
12708
  Outputs structured JSON on non-TTY (MCP, pipes, scripts):
12702
12709
  {"cli_version": "1.33.11", "mcp_schema_version": "1.33.11",
12703
- "compatibility_schema_version": "1.0"}
12710
+ "compatibility_schema_version": "1.0", "provenance": {...}}
12704
12711
  """
12705
12712
  from sourcecode.release_info import advisory_line, build_status
12713
+ from sourcecode.product_info import COPYRIGHT, PRODUCT, TAGLINE, build_provenance
12706
12714
 
12707
12715
  if getattr(sys.stdout, "isatty", lambda: False)():
12708
- _lines = [f"ask {__version__}"]
12716
+ _lines = [f"{PRODUCT} {__version__}", TAGLINE, COPYRIGHT]
12709
12717
  # C4-12: the field audits builds that are days old and many releases
12710
12718
  # behind, and nothing said so. Printed only when it applies — an advisory
12711
12719
  # on every run is one nobody reads.
@@ -12732,6 +12740,7 @@ def version_cmd(
12732
12740
  # Same list `ask schema` prints, so the two surfaces cannot disagree
12733
12741
  # about what this release publishes.
12734
12742
  "registries": ["facts-v1"],
12743
+ "provenance": build_provenance(),
12735
12744
  }, ensure_ascii=_json_ensure_ascii()), copy, output_path)
12736
12745
 
12737
12746
 
@@ -14234,12 +14243,20 @@ def cache_status_cmd(
14234
14243
  if "budget_bytes" in _store:
14235
14244
  _budget_mb = _store.get("budget_mb")
14236
14245
  _env = _store.get("budget_env")
14246
+ _over_by = _store.get("over_budget_by_mb")
14247
+ _current_mb = _store.get("current_mb")
14237
14248
  if _store.get("budget_bytes"):
14238
- _over = " — OVER, the next write evicts" if _store.get("over_budget") else ""
14239
- _answer.say(
14240
- f"{'':<13}budget {_budget_mb} MB, {_store.get('policy')} "
14241
- f"(${_env}){_over}"
14242
- )
14249
+ if _store.get("over_budget"):
14250
+ _answer.say(
14251
+ f"{'':<13}budget {_budget_mb} MB, {_store.get('policy')} "
14252
+ f"(${_env}); current {_current_mb} MB, over by {_over_by} MB "
14253
+ "— the next write evicts"
14254
+ )
14255
+ else:
14256
+ _answer.say(
14257
+ f"{'':<13}budget {_budget_mb} MB, {_store.get('policy')} "
14258
+ f"(${_env})"
14259
+ )
14243
14260
  else:
14244
14261
  _answer.say(f"{'':<13}{_store.get('policy')} (${_env})")
14245
14262
  # RIS section
sourcecode/parse_cache.py CHANGED
@@ -440,6 +440,11 @@ def store_stats() -> "dict[str, object]":
440
440
  **_budget,
441
441
  "over_budget": bool(_limit) and total > _limit,
442
442
  }
443
+ if _limit:
444
+ out["over_budget_by_mb"] = round(
445
+ max(0, total - _limit) / (1024 * 1024), 2
446
+ )
447
+ out["current_mb"] = round(total / (1024 * 1024), 2)
443
448
  _stale = [g for g in generations if not g["current"]]
444
449
  if _stale:
445
450
  out["stale_entries"] = sum(int(g["entries"]) for g in _stale)
@@ -183,6 +183,8 @@ def is_test_fixture_module_path(path: str) -> bool:
183
183
  bare = part.rstrip("/")
184
184
  if bare in _TEST_MODULE_SEGMENTS:
185
185
  return True
186
+ if bare.endswith(("-test", "-tests", "-it", "-itest", "-itests")):
187
+ return True
186
188
  if bare.endswith(_TEST_INFRA_SUFFIXES):
187
189
  return True
188
190
  toks = bare.replace("_", "-").split("-")
sourcecode/phased_run.py CHANGED
@@ -41,6 +41,7 @@ from __future__ import annotations
41
41
  import hashlib
42
42
  import json
43
43
  import os
44
+ import tempfile
44
45
  import time
45
46
  from dataclasses import dataclass, field
46
47
  from pathlib import Path
@@ -71,7 +72,7 @@ def partials_dir(root: Path) -> Path:
71
72
  except Exception:
72
73
  key_source = str(Path(root).absolute())
73
74
  key = hashlib.sha256(key_source.encode("utf-8", errors="replace")).hexdigest()[:16]
74
- return Path.home() / ".sourcecode" / "partials" / key
75
+ return Path(tempfile.gettempdir()) / "sourcecode" / "partials" / key
75
76
 
76
77
 
77
78
  @dataclass
@@ -0,0 +1,22 @@
1
+ """Product identity and build provenance for official ASK Engine artifacts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+
7
+ PRODUCT = "ASK Engine"
8
+ TAGLINE = "Actionable Software Knowledge Engine"
9
+ COPYRIGHT = "Copyright (c) 2026 Dominique Haroun. All rights reserved."
10
+ PUBLISHER = "Dominique Haroun"
11
+ LICENSE_ID = "LicenseRef-ASK-Proprietary"
12
+
13
+
14
+ def build_provenance() -> dict[str, str]:
15
+ """Return build facts without discovering state from the user's repository."""
16
+ return {
17
+ "product": PRODUCT,
18
+ "publisher": PUBLISHER,
19
+ "license": LICENSE_ID,
20
+ "distribution": os.environ.get("ASK_DISTRIBUTION", "official"),
21
+ "build_commit": os.environ.get("ASK_BUILD_COMMIT", "unrecorded"),
22
+ }
@@ -3833,8 +3833,6 @@ def _route_annotation_name(sym: SymbolRecord) -> str:
3833
3833
  def _enclosing_class(fqn: str) -> str:
3834
3834
  if "#" in fqn:
3835
3835
  return fqn.split("#")[0]
3836
- if "." in fqn:
3837
- return fqn.rsplit(".", 1)[0]
3838
3836
  return fqn
3839
3837
 
3840
3838
 
@@ -7122,6 +7120,46 @@ def extract_java_endpoints(
7122
7120
  f"still expose an HTTP surface — verify manually before concluding the "
7123
7121
  f"service has no public API."
7124
7122
  )
7123
+
7124
+ result["coverage"] = {
7125
+ "detected_styles": {
7126
+ "spring_mvc_annotations": sum(1 for e in endpoints if e.get("source") == "annotation"),
7127
+ "xml_mapped": sum(1 for e in endpoints if e.get("source") == "xml_mapped"),
7128
+ "router_dsl": sum(1 for e in endpoints if e.get("source") == "router_dsl"),
7129
+ "openapi_spec": len(_spec_endpoints),
7130
+ "webflux_functional": len(_fn_route_files),
7131
+ "jax_rs": sum(1 for r in routes if r.get("framework") == "jax_rs"),
7132
+ "webscripts": _nonspring["webscripts"],
7133
+ "servlets": _nonspring["servlets"],
7134
+ },
7135
+ "supported_styles": {
7136
+ "spring_mvc_annotations": True,
7137
+ "xml_mapped": True,
7138
+ "router_dsl": True,
7139
+ "openapi_spec": True,
7140
+ "jax_rs": True,
7141
+ "webflux_functional": False,
7142
+ "webscripts": False,
7143
+ "servlets": False,
7144
+ },
7145
+ "gaps": [
7146
+ *(
7147
+ [f"webflux_functional: {len(_fn_route_files)} files"]
7148
+ if _fn_route_count
7149
+ else []
7150
+ ),
7151
+ *(
7152
+ [f"webscripts: {_nonspring['webscripts']} files"]
7153
+ if _nonspring["webscripts"]
7154
+ else []
7155
+ ),
7156
+ *(
7157
+ [f"servlets: {_nonspring['servlets']} declarations"]
7158
+ if _nonspring["servlets"]
7159
+ else []
7160
+ ),
7161
+ ],
7162
+ }
7125
7163
  return result
7126
7164
 
7127
7165
 
@@ -88,42 +88,53 @@ def _from_web_xml(xml_path: Path, relative: str) -> "tuple[list[ServletMapping],
88
88
  text = xml_path.read_text(encoding="utf-8", errors="replace")
89
89
  root = ET.fromstring(text)
90
90
  except Exception:
91
- return [], 0
91
+ # Legacy descriptors can contain constructs ElementTree rejects. Keep the
92
+ # lexical fallback below, including its omission census; returning here
93
+ # made an undeclared live mapping look as though it had never existed.
94
+ root = None
92
95
  classes: "dict[str, str]" = {}
93
- for elem in root.iter():
94
- if _local(elem.tag) != "servlet":
95
- continue
96
- name = _child_text(elem, "servlet-name")
97
- klass = _child_text(elem, "servlet-class")
98
- if name:
99
- classes[name] = klass
96
+ if root is not None:
97
+ for elem in root.iter():
98
+ if _local(elem.tag) != "servlet":
99
+ continue
100
+ name = _child_text(elem, "servlet-name")
101
+ klass = _child_text(elem, "servlet-class")
102
+ if name:
103
+ classes[name] = klass
100
104
  out: "list[ServletMapping]" = []
101
105
  undeclared_servlet_mappings = 0
102
- for elem in root.iter():
103
- if _local(elem.tag) != "servlet-mapping":
104
- continue
105
- name = _child_text(elem, "servlet-name")
106
- if not name or name not in classes:
107
- undeclared_servlet_mappings += sum(
108
- 1 for child in elem.iter()
109
- if _local(child.tag) == "url-pattern" and (child.text or "").strip()
110
- )
111
- continue
112
- for child in elem.iter():
113
- if _local(child.tag) != "url-pattern" or not (child.text or "").strip():
106
+ if root is not None:
107
+ for elem in root.iter():
108
+ if _local(elem.tag) != "servlet-mapping":
114
109
  continue
115
- out.append(ServletMapping(
116
- url_pattern=child.text.strip(),
117
- servlet_name=name,
118
- servlet_class=classes.get(name, ""),
119
- source_file=relative,
120
- source="web.xml",
121
- ))
110
+ name = _child_text(elem, "servlet-name")
111
+ if not name or name not in classes:
112
+ undeclared_servlet_mappings += sum(
113
+ 1 for child in elem.iter()
114
+ if _local(child.tag) == "url-pattern" and (child.text or "").strip()
115
+ )
116
+ continue
117
+ for child in elem.iter():
118
+ if _local(child.tag) != "url-pattern" or not (child.text or "").strip():
119
+ continue
120
+ out.append(ServletMapping(
121
+ url_pattern=child.text.strip(),
122
+ servlet_name=name,
123
+ servlet_class=classes.get(name, ""),
124
+ source_file=relative,
125
+ source="web.xml",
126
+ ))
122
127
  # Keep a tolerant lexical fallback for descriptors containing legacy XML
123
128
  # constructs that ElementTree rejects or partially normalizes. Comments are
124
129
  # removed first so commented deployment examples never become live routes.
125
130
  try:
126
131
  active = re.sub(r"<!--.*?-->", "", text, flags=re.DOTALL)
132
+ if root is None:
133
+ for block in re.findall(r"<servlet\b[^>]*>(.*?)</servlet>", active, re.DOTALL | re.IGNORECASE):
134
+ name_match = re.search(r"<servlet-name\b[^>]*>\s*([^<]+?)\s*</servlet-name>", block, re.DOTALL | re.IGNORECASE)
135
+ class_match = re.search(r"<servlet-class\b[^>]*>\s*([^<]+?)\s*</servlet-class>", block, re.DOTALL | re.IGNORECASE)
136
+ if name_match:
137
+ classes[name_match.group(1).strip()] = class_match.group(1).strip() if class_match else ""
127
138
  for block in re.findall(r"<servlet-mapping\b[^>]*>(.*?)</servlet-mapping>", active, re.DOTALL | re.IGNORECASE):
128
139
  name_match = re.search(r"<servlet-name\b[^>]*>\s*([^<]+?)\s*</servlet-name>", block, re.DOTALL | re.IGNORECASE)
129
140
  pattern_match = re.search(r"<url-pattern\b[^>]*>\s*([^<]+?)\s*</url-pattern>", block, re.DOTALL | re.IGNORECASE)
@@ -131,6 +142,8 @@ def _from_web_xml(xml_path: Path, relative: str) -> "tuple[list[ServletMapping],
131
142
  continue
132
143
  servlet_name = name_match.group(1).strip() if name_match else ""
133
144
  if not servlet_name or servlet_name not in classes:
145
+ if root is None:
146
+ undeclared_servlet_mappings += 1
134
147
  continue
135
148
  candidate = ServletMapping(
136
149
  url_pattern=pattern_match.group(1).strip(),
sourcecode/timeline.py CHANGED
@@ -211,7 +211,12 @@ class Sample:
211
211
 
212
212
  def _git(repo: Path, *args: str) -> subprocess.CompletedProcess:
213
213
  return subprocess.run(
214
- ["git", "-C", str(repo), *args], capture_output=True, text=True, check=False,
214
+ ["git", "-C", str(repo), "-c", "i18n.logOutputEncoding=utf-8", *args],
215
+ capture_output=True,
216
+ text=True,
217
+ encoding="utf-8",
218
+ errors="replace",
219
+ check=False,
215
220
  )
216
221
 
217
222
 
@@ -1,13 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 5.5.5
3
+ Version: 5.6.1
4
4
  Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
5
+ Project-URL: Homepage, https://github.com/HarounDominique/sourcecode
6
+ Project-URL: Repository, https://github.com/HarounDominique/sourcecode
7
+ Author: Dominique Haroun
8
+ License: Proprietary; see LICENSE
5
9
  License-File: LICENSE
10
+ License-File: NOTICE
6
11
  Keywords: agents,ai,codebase,context,developer-tools,llm
7
12
  Classifier: Development Status :: 4 - Beta
8
13
  Classifier: Environment :: Console
9
14
  Classifier: Intended Audience :: Developers
10
- Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: License :: Other/Proprietary License
11
16
  Classifier: Operating System :: OS Independent
12
17
  Classifier: Programming Language :: Python :: 3
13
18
  Classifier: Programming Language :: Python :: 3.9
@@ -42,9 +47,13 @@ Description-Content-Type: text/markdown
42
47
 
43
48
  **Context · Impact · Migration · Architecture · Review — everything from one structural model.**
44
49
 
45
- ![Version](https://img.shields.io/badge/version-5.5.5-blue)
50
+ ![Version](https://img.shields.io/badge/version-5.6.1-blue)
46
51
  ![Python](https://img.shields.io/badge/python-3.9%2B-green)
47
52
 
53
+ Copyright (c) 2026 Dominique Haroun. All rights reserved. ASK Engine 5.6.1 and
54
+ later are proprietary; see [LICENSE](LICENSE) and [NOTICE](NOTICE). Releases up
55
+ to and including 5.5.6 remain governed by their published Apache-2.0 terms.
56
+
48
57
  > **ASK Engine** is the product. The CLI command is **`ask`**. The legacy **`sourcecode`**
49
58
  > command still works as a deprecated alias (it prints a one-line notice and forwards to
50
59
  > `ask`) and remains the Python/PyPI package name for now. The authoritative version is
@@ -126,7 +135,7 @@ brew tap haroundominique/sourcecode && brew install sourcecode
126
135
  # pip / pipx
127
136
  pipx install sourcecode # or: pip install sourcecode
128
137
 
129
- ask version # ask 5.5.5 — and, on a build that has aged,
138
+ ask version # ask 5.6.1 — and, on a build that has aged,
130
139
  # how many releases have probably shipped since
131
140
  ```
132
141
 
@@ -1,4 +1,4 @@
1
- sourcecode/__init__.py,sha256=LWoy6uySGMfIcuMSAGcCF4LHEF2d_DbNo4PrVl8kous,308
1
+ sourcecode/__init__.py,sha256=isL2psS-4yFbO0_giM54o6BMdZ6ngvWNjtLwYGTC0DU,308
2
2
  sourcecode/adaptive_scanner.py,sha256=yJBKjNpkY6bpueYJ2YnRezen3sYZDecEt7WaaNWdqug,9466
3
3
  sourcecode/archetype.py,sha256=CZvRLpkHot_D8D3JFQVorr-EHDJyh0BbS7RnSTqBigM,40499
4
4
  sourcecode/architectural_baseline.py,sha256=4GiMVBLJVHvRKSWQGf2ZVurI1-R0qk5pmaevgvGSgVA,26325
@@ -19,7 +19,7 @@ sourcecode/chain_rules.py,sha256=Bi6UHfgd-GxWswmnHRcPz5jdbAuqka3Zkz_P-MTvqhw,127
19
19
  sourcecode/change_plan.py,sha256=aX1mp2XnlDN-8R2BcTiu8HlkDwQ_4fN1ZLckj0VMXHM,9945
20
20
  sourcecode/cir_graphs.py,sha256=9G0HHj1kw2325IDyzo2OpX73BNswEckecf4MZUXB4JM,12078
21
21
  sourcecode/classifier.py,sha256=JBzPwSSrDG-tUHAbcKB678HRbjLpD-ohzbzzO62mgpo,20114
22
- sourcecode/cli.py,sha256=Lq6Kbunzj01R5pbcDbrF8lMslaTpc4JbrLyVozCsstA,650907
22
+ sourcecode/cli.py,sha256=8cb4PXoIGsffcZL2ftqGuvK_G9zjU-BXLpTgvAtoTtA,651962
23
23
  sourcecode/client_calls.py,sha256=5_sBfFVXi6RgGiyWrlJKH4x4EF21do6gKlAOuFCKAoA,17709
24
24
  sourcecode/code_notes_analyzer.py,sha256=EJemNCNc9Dn-1RZYu-aNbK0ELzmsyC4s6FdHi3XyNEI,9392
25
25
  sourcecode/compare.py,sha256=2GdDy0qkDSgmkkpgvoCHitoLj3mt30EeFgJ8PGEXJng,14712
@@ -82,17 +82,18 @@ sourcecode/openrewrite_recipe.py,sha256=4dyY5twRB6Xew-G9Zy5FafNZwlMU1S7DnRa2FqPk
82
82
  sourcecode/output_budget.py,sha256=GxoFnbwk0dvqScgmMRPZHj7m-zRIoHLwUKplrH0u89s,13872
83
83
  sourcecode/output_encoding.py,sha256=OxiZQtr7uWBDUtblNQviNHsTH1Xo9AZEpsegPlQWKFk,2139
84
84
  sourcecode/parallel.py,sha256=T9N-I8rtr43eXx2ZmKcmj2e62v6wsEKE9Y7zGNZ62TU,10224
85
- sourcecode/parse_cache.py,sha256=TpIoSeNUba4Aoaz5o5SmgAc0Tz02OKq1Du4Hw7HyJfg,22560
85
+ sourcecode/parse_cache.py,sha256=0pY2rcPZGhno1oPvdM0fAJt5h0i4uAGpyc0IJcvSaIg,22741
86
86
  sourcecode/partial_contract.py,sha256=x_N_0bF3mpNNjXd7JFB1zr6LSIroo2zN5GCz14GXvXQ,3510
87
87
  sourcecode/path_admission.py,sha256=OGNSoluhVh8YYOBZBnACUrkmH4Tp_yxjGLifkcsxQpo,5838
88
- sourcecode/path_filters.py,sha256=LmTYq735orssKTIuxTX1mE1FHAXF7dVEJEse35xE1RA,12371
88
+ sourcecode/path_filters.py,sha256=mjrfdW5ydS2EUfEVKp1lhbfVZGIX7uLaA5RWjveE1SI,12470
89
89
  sourcecode/perf.py,sha256=QsFeacezwUu9T6RMpV4-cmyn98sbF2nWbWgarKxvNAk,35285
90
- sourcecode/phased_run.py,sha256=cFd0Lxfc8XL-XkCVCCzcjd9bZbtgkJkGZAHfmJ6dBJ4,16542
90
+ sourcecode/phased_run.py,sha256=8nbA1-UZ39WR8m9wR9T2Sx2RuhoEzpY0-iXcok7FEsw,16573
91
91
  sourcecode/pipe_contract.py,sha256=PML0Er5d8uDyec4OrdUXuyqHbGPUYndjeaKUjkFz2u4,8369
92
92
  sourcecode/posture.py,sha256=7d3zM4ExrSXVKrWNTlXQ0fUQNqDdl1LOuKwRVaXdRss,76574
93
93
  sourcecode/pr_comment_renderer.py,sha256=239PmJdf95av_ZW236C7_tvq_ahECeuF9AZxrheJ4OQ,15573
94
94
  sourcecode/pr_impact.py,sha256=KyVBvHCCbgByKA_wqTbO1dSkfi05GEudIAuH4CyDPK4,27395
95
95
  sourcecode/prepare_context.py,sha256=ntB2MSScHtYRKRm9SansA0FrklMnXZmE9_yRXqXk0qc,239264
96
+ sourcecode/product_info.py,sha256=0zjZEutL7iDdp9aVyIumIrNyNn9VWYFc2lIytSbjBP4,727
96
97
  sourcecode/progress.py,sha256=A4hNoCRgmHofilbIXMoR4vlvoF4gupefTUCuYmceI_E,20547
97
98
  sourcecode/provenance.py,sha256=gLbsLv0gze7k7ChM4i5M3MwKfFPzs8wzM72rUd2C5sM,7342
98
99
  sourcecode/ranking_engine.py,sha256=ZAucq_YX2KkWUuAZf4P0lhtQ_38vEFnUhuGtSZd1S0E,12970
@@ -106,7 +107,7 @@ sourcecode/relevance_scorer.py,sha256=0AgEt4KrV73nioMqBgjhGjtY7L2C7L7cSyKtj3IKcr
106
107
  sourcecode/remedies.py,sha256=V2_cD4pLq8bKRkzF-3RGFoiu1xWYZS384WDVp1MrlZw,10225
107
108
  sourcecode/rename_refactor.py,sha256=h6dNFlB9aZ_3q6heeHBkgXQeXaT03nvPSsYH6P8qxFg,12965
108
109
  sourcecode/repo_classifier.py,sha256=FG1vaWKdWXsWdl-S8hjVMiTqcwgaRXkDyvK4rPcOGtQ,22681
109
- sourcecode/repository_ir.py,sha256=nSStGh9z8uHSTj92IJp85Y1J8NDGqlY59KtEsgHThqY,388812
110
+ sourcecode/repository_ir.py,sha256=gkQLnWsUuw8shQRj7iAHM1_dEYu057hrn7GzX6ZYm9g,390225
110
111
  sourcecode/ris.py,sha256=Xbx34dkJI_uXil9xsgw-fA_Apcm4nbnTjQgFm66dP1g,27489
111
112
  sourcecode/risk.py,sha256=u2V7nG5yGW8VV4sFDSgFkZqdI6ltmilWhlQwlIH7d2o,82660
112
113
  sourcecode/rule_catalog.py,sha256=pTkgkQZ1u7atB3fkQJ9BPWo8lNiamvEuRN7MtRgle0c,5263
@@ -125,7 +126,7 @@ sourcecode/semantic_impact_engine.py,sha256=t09IirGC3JjQDy33JZd1_WKzQVKXkoNl3-XE
125
126
  sourcecode/semantic_integration_engine.py,sha256=7a0WqAInOv39f0Yr_94TYo_JP_8QpeI9KGaknpzAyQU,18899
126
127
  sourcecode/semantic_services.py,sha256=nbUuPv-F01USTt_9CHT8iy_ucCIw3fz4W3Aquea_pd4,10782
127
128
  sourcecode/serializer.py,sha256=cK4I3WzX0H-oBPbqzBsUBRux5GcYmH_yPDQwxvkf8yQ,141598
128
- sourcecode/servlet_surface.py,sha256=1ZB76G5PrIGqmRAO8rEd20SMYoexZ5t01v82HtHLSXo,12481
129
+ sourcecode/servlet_surface.py,sha256=CeiebkxLXKojUQxIf7HV7tdQAwLM32ggDUwBnVQIjdo,13499
129
130
  sourcecode/source_text.py,sha256=R52gmSljz7L6YVPbixv5W-LOZ5eKUVvSUP3S-QH_IWc,9047
130
131
  sourcecode/spring_event_topology.py,sha256=5_ON_21Le5zbG-1GRc5GLIi5HJfy_QjcXLVPC5WeUGQ,18055
131
132
  sourcecode/spring_findings.py,sha256=cW6NiQAFUM9mDYPitJr6MrQg--YBI41LxrSEMI9aeIQ,25272
@@ -142,7 +143,7 @@ sourcecode/target_admission.py,sha256=wFZ4pzlxhiF6Q6s2lEAZEzcCfj1Y6xNvujjt8MdO0Q
142
143
  sourcecode/test_gap_ranking.py,sha256=hl-tTyQUXZGJycG1b6npbLeE_DaVHaOsvPwG9qqC5y8,15711
143
144
  sourcecode/test_sources.py,sha256=KM88qbMfLDmUV5X2nA83LjYz8A2ipj4A_2u2FhZx8gc,9440
144
145
  sourcecode/text_input.py,sha256=3pL8DxR_DMI3ece-B70DnppvrEaLh4R17Pp8dK9G_hc,3596
145
- sourcecode/timeline.py,sha256=fU8UiHgf0qO2OsT-xe77tWeRJgp6ov55ZyXqnEGmd_E,17590
146
+ sourcecode/timeline.py,sha256=mIEzaIylhtu2PBoqqz2iI4K_OxZf8fx9-Lf-Zj6QFXM,17704
146
147
  sourcecode/token_estimate.py,sha256=G-ivzIJfVq5TLQN04dC0WK4LZJjWVYL54Ebcxe4fJ7M,9268
147
148
  sourcecode/tree_utils.py,sha256=8GAkIfQAsvtEudIeW1l4ooH_oRtrWR8cpJQJsEa_Pfw,2093
148
149
  sourcecode/type_usage_surface.py,sha256=51IrKRQoIoRnlsiDjHnqpJBn2rc6E59aRhgS0HTzAF0,4428
@@ -214,9 +215,12 @@ sourcecode/telemetry/events.py,sha256=4_yeO58U-Cwc1Qb27VB0_EjhmroY0k91n3_VGxeALB
214
215
  sourcecode/telemetry/filters.py,sha256=RzxauTz8HliO4BllQnXEXc7zTeqdCZi5MgqGEDuW7OQ,6570
215
216
  sourcecode/telemetry/transport.py,sha256=4gGHsq0WeY9VywEZXA3vUxykfiYnw9uuqfjAAec7F8o,1681
216
217
  sourcecode/_docs/DEFECT-LEDGER.md,sha256=5SxWnKt6p5ZRmx-WsFhIlMfe7-e5fLF0QRa9lAmzYug,499071
217
- sourcecode/_docs/USER_GUIDE.md,sha256=ykjudytfe1VLgGJQAcs36wkXsEO3N-QJY2js1cJc7y0,79837
218
- sourcecode-5.5.5.dist-info/METADATA,sha256=bMkQLLoD1zYBemJ5ZJpHyy9xIurRVdVOTCP20jSLN6I,47104
219
- sourcecode-5.5.5.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
220
- sourcecode-5.5.5.dist-info/entry_points.txt,sha256=-JEAdChrK5We51kZcb7OaDcyil-dHBjBPL-NhuO-QY8,89
221
- sourcecode-5.5.5.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
222
- sourcecode-5.5.5.dist-info/RECORD,,
218
+ sourcecode/_docs/LICENSE,sha256=23-fk61oSWGVmkWyka-FIM0rhAPM2hcYHnsaridL8Uo,1859
219
+ sourcecode/_docs/NOTICE,sha256=Br-AA8Y3iJo1WXa5uP8QBpzqI5nDu3iGLbFyvDt3BOs,321
220
+ sourcecode/_docs/USER_GUIDE.md,sha256=cfLC_id1-9LfNKWmofrPsDs4dY3QlF4PzGAn3ByW_Io,79924
221
+ sourcecode-5.6.1.dist-info/METADATA,sha256=o11UMKvI7DHL337qHQ8W3_AY2TIdWeU4TMFZLSfSlSE,47546
222
+ sourcecode-5.6.1.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
223
+ sourcecode-5.6.1.dist-info/entry_points.txt,sha256=-JEAdChrK5We51kZcb7OaDcyil-dHBjBPL-NhuO-QY8,89
224
+ sourcecode-5.6.1.dist-info/licenses/LICENSE,sha256=23-fk61oSWGVmkWyka-FIM0rhAPM2hcYHnsaridL8Uo,1859
225
+ sourcecode-5.6.1.dist-info/licenses/NOTICE,sha256=Br-AA8Y3iJo1WXa5uP8QBpzqI5nDu3iGLbFyvDt3BOs,321
226
+ sourcecode-5.6.1.dist-info/RECORD,,
@@ -0,0 +1,47 @@
1
+ ASK Engine Proprietary License
2
+ Version 1.0, effective 2026-08-13
3
+
4
+ Copyright (c) 2026 Dominique Haroun. All rights reserved.
5
+
6
+ 1. Scope
7
+
8
+ This license applies to ASK Engine version 5.6.1 and later, including its source
9
+ code, documentation, and distributed artifacts (the "Software"). It does not
10
+ alter the license of versions 5.5.6 and earlier, which were distributed under
11
+ the Apache License, Version 2.0. Grants made for those earlier versions remain
12
+ governed by their published license terms.
13
+
14
+ 2. No Implied Grant
15
+
16
+ Except under a separate written agreement signed by Dominique Haroun, no right
17
+ or license is granted to use, copy, modify, distribute, sublicense, sell,
18
+ reverse engineer, or create derivative works of the Software. Possession of a
19
+ copy, access to a repository, or access to a distributed artifact does not
20
+ create an implied license.
21
+
22
+ 3. Third-Party Materials
23
+
24
+ Third-party dependencies and materials included with the Software remain subject
25
+ to their own license terms. This license does not supersede those terms.
26
+
27
+ 4. Trademarks
28
+
29
+ "ASK Engine", "ASK", and associated marks are identifiers of the Software.
30
+ No trademark license is granted except as required to identify an unmodified,
31
+ lawfully obtained copy of the Software.
32
+
33
+ 5. No Warranty
34
+
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE,
37
+ AND NON-INFRINGEMENT. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE COPYRIGHT
38
+ HOLDER SHALL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING
39
+ FROM OR IN CONNECTION WITH THE SOFTWARE.
40
+
41
+ 6. Contact
42
+
43
+ Commercial, evaluation, redistribution, and contribution terms require a
44
+ written agreement with Dominique Haroun.
45
+
46
+ This license text is an operational policy draft and must be reviewed by
47
+ qualified counsel before distribution to third parties.
@@ -0,0 +1,8 @@
1
+ ASK Engine
2
+ Copyright (c) 2026 Dominique Haroun. All rights reserved.
3
+
4
+ ASK Engine and its source code were originally created and developed by
5
+ Dominique Haroun.
6
+
7
+ This NOTICE applies to ASK Engine 5.6.1 and later. Earlier releases may carry
8
+ different license terms; see the license distributed with the applicable release.
@@ -1,186 +0,0 @@
1
- Apache License
2
- Version 2.0, January 2004
3
- http://www.apache.org/licenses/
4
-
5
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
-
7
- 1. Definitions.
8
-
9
- "License" shall mean the terms and conditions for use, reproduction,
10
- and distribution as defined by Sections 1 through 9 of this document.
11
-
12
- "Licensor" shall mean the copyright owner or entity authorized by
13
- the copyright owner that is granting the License.
14
-
15
- "Legal Entity" shall mean the union of the acting entity and all
16
- other entities that control, are controlled by, or are under common
17
- control with that entity. For the purposes of this definition,
18
- "control" means (i) the power, direct or indirect, to cause the
19
- direction or management of such entity, whether by contract or
20
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
- outstanding shares, or (iii) beneficial ownership of such entity.
22
-
23
- "You" (or "Your") shall mean an individual or Legal Entity
24
- exercising permissions granted by this License.
25
-
26
- "Source" form shall mean the preferred form for making modifications,
27
- including but not limited to software source code, documentation
28
- source, and configuration files.
29
-
30
- "Object" form shall mean any form resulting from mechanical
31
- transformation or translation of a Source form, including but
32
- not limited to compiled object code, generated documentation,
33
- and conversions to other formats.
34
-
35
- "Work" shall mean the work of authorship made available under
36
- the License, as indicated by a copyright notice that is included in
37
- or attached to the work (an example is provided in the Appendix below).
38
-
39
- "Derivative Works" shall mean any work, whether in Source or Object
40
- form, that is based on (or derived from) the Work and for which the
41
- editorial revisions, annotations, elaborations, or other transformations
42
- represent, as a whole, an original work of authorship. For the purposes
43
- of this License, Derivative Works shall not include works that remain
44
- separable from, or merely link (or bind by name) to the interfaces of,
45
- the Work and Derivative Works thereof.
46
-
47
- "Contribution" shall mean, as submitted to the Licensor for inclusion
48
- in the Work by the copyright owner or by an individual or Legal Entity
49
- authorized to submit on behalf of the copyright owner. For the purposes
50
- of this definition, "submit" means any form of electronic, verbal, or
51
- written communication sent to the Licensor or its representatives,
52
- including but not limited to communication on electronic mailing lists,
53
- source code control systems, and issue tracking systems that are managed
54
- by, or on behalf of, the Licensor for the purpose of discussing and
55
- improving the Work, but excluding communication that is conspicuously
56
- marked or designated in writing by the copyright owner as "Not a
57
- Contribution."
58
-
59
- "Contributor" shall mean Licensor and any Legal Entity on behalf of
60
- whom a Contribution has been received by the Licensor and included
61
- within the Work.
62
-
63
- 2. Grant of Copyright License. Subject to the terms and conditions of
64
- this License, each Contributor hereby grants to You a perpetual,
65
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
66
- copyright license to reproduce, prepare Derivative Works of,
67
- publicly display, publicly perform, sublicense, and distribute the
68
- Work and such Derivative Works in Source or Object form.
69
-
70
- 3. Grant of Patent License. Subject to the terms and conditions of
71
- this License, each Contributor hereby grants to You a perpetual,
72
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
73
- (except as stated in this section) patent license to make, have made,
74
- use, offer to sell, sell, import, and otherwise transfer the Work,
75
- where such license applies only to those patent claims licensable
76
- by such Contributor that are necessarily infringed by their
77
- Contribution(s) alone or by the combination of their Contribution(s)
78
- with the Work to which such Contribution(s) was submitted. If You
79
- institute patent litigation against any entity (including a cross-claim
80
- or counterclaim in a lawsuit) alleging that the Work or any Contributor
81
- Contribution constitutes direct or contributory patent infringement,
82
- then any patent rights granted to You under this License for that Work
83
- shall terminate as of the date such litigation is filed.
84
-
85
- 4. Redistribution. You may reproduce and distribute copies of the
86
- Work or Derivative Works thereof in any medium, with or without
87
- modifications, and in Source or Object form, provided that You
88
- meet the following conditions:
89
-
90
- (a) You must give any other recipients of the Work or Derivative
91
- Works a copy of this License; and
92
-
93
- (b) You must cause any modified files to carry prominent notices
94
- stating that You changed the files; and
95
-
96
- (c) You must retain, in the Source form of any Derivative Works
97
- that You distribute, all copyright, patent, trademark, and
98
- attribution notices from the Source form of the Work,
99
- excluding those notices that do not pertain to any part of
100
- the Derivative Works; and
101
-
102
- (d) If the Work includes a "NOTICE" text file as part of its
103
- distribution, You must include a readable copy of the
104
- attribution notices contained within such NOTICE file, in
105
- at least one of the following places: within a NOTICE text
106
- file distributed as part of the Derivative Works; within
107
- the Source form or documentation, if provided along with the
108
- Derivative Works; or, within a display generated by the
109
- Derivative Works, if and wherever such third-party notices
110
- normally appear. The contents of the NOTICE file are for
111
- informational purposes only and do not modify the License.
112
- You may add Your own attribution notices within Derivative
113
- Works that You distribute, alongside or in addition to the
114
- NOTICE text from the Work, provided that such additional
115
- attribution notices cannot be construed as modifying the License.
116
-
117
- You may add Your own license statement for Your modifications and
118
- may provide additional grant of rights to use, copy, modify, merge,
119
- publish, distribute, sublicense, and/or sell copies of the
120
- Derivative Works, as separate terms and conditions for their use,
121
- reproduction, and distribution, or alongside or as supplement to
122
- any license terms for such Derivative Works as a whole, provided
123
- Your use, reproduction, and distribution of the Work otherwise
124
- complies with the conditions stated in this License.
125
-
126
- 5. Submission of Contributions. Unless You explicitly state otherwise,
127
- any Contribution intentionally submitted for inclusion in the Work
128
- by You to the Licensor shall be under the terms and conditions of
129
- this License, without any additional terms or conditions.
130
- Notwithstanding the above, nothing herein shall supersede or modify
131
- the terms of any separate license agreement you may have executed
132
- with Licensor regarding such Contributions.
133
-
134
- 6. Trademarks. This License does not grant permission to use the trade
135
- names, trademarks, service marks, or product names of the Licensor,
136
- except as required for reasonable and customary use in describing the
137
- origin of the Work and reproducing the content of the NOTICE file.
138
-
139
- 7. Disclaimer of Warranty. Unless required by applicable law or
140
- agreed to in writing, Licensor provides the Work (and each
141
- Contributor provides its Contributions) on an "AS IS" BASIS,
142
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
143
- implied, including, without limitation, any warranties or conditions
144
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
145
- PARTICULAR PURPOSE. You are solely responsible for determining the
146
- appropriateness of using or reproducing the Work and assume any
147
- risks associated with Your exercise of permissions under this License.
148
-
149
- 8. Limitation of Liability. In no event and under no legal theory,
150
- whether in tort (including negligence), contract, or otherwise,
151
- unless required by applicable law (such as deliberate and grossly
152
- negligent acts) or agreed to in writing, shall any Contributor be
153
- liable to You for damages, including any direct, indirect, special,
154
- incidental, or exemplary damages of any character arising as a
155
- result of this License or out of the use or inability to use the
156
- Work (including but not limited to damages for loss of goodwill,
157
- work stoppage, computer failure or malfunction, or all other
158
- commercial damages or losses), even if such Contributor has been
159
- advised of the possibility of such damages.
160
-
161
- 9. Accepting Warranty or Liability. While redistributing the Work or
162
- Derivative Works thereof, You may choose to offer, and charge a fee
163
- for, acceptance of support, warranty, indemnity, or other liability
164
- obligations and/or rights consistent with this License. However, in
165
- accepting such obligations, You may offer such obligations only on
166
- Your own behalf and on Your sole responsibility, not on behalf of
167
- any other Contributor, and only if You agree to indemnify, defend,
168
- and hold each Contributor harmless for any liability incurred by,
169
- or claims asserted against, such Contributor by reason of your
170
- accepting any warranty or additional liability.
171
-
172
- END OF TERMS AND CONDITIONS
173
-
174
- Copyright 2024 sourcecode contributors
175
-
176
- Licensed under the Apache License, Version 2.0 (the "License");
177
- you may not use this file except in compliance with the License.
178
- You may obtain a copy of the License at
179
-
180
- http://www.apache.org/licenses/LICENSE-2.0
181
-
182
- Unless required by applicable law or agreed to in writing, software
183
- distributed under the License is distributed on an "AS IS" BASIS,
184
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
185
- See the License for the specific language governing permissions and
186
- limitations under the License.