fix: enforce source notices and restore Query About branding (#14)
* chore(standards): enforce owned C# copyright headers Add the repository's existing James Maes/MIT notice to127owned C# files and correct one SPDX marker. Preserve all94existing copyright lines and all vendor/generated material. Enforce future headers with native IDE0073 under the existing warnings-as-errors build; sort only three adjacent import pairs. Roslyn tokens and original suffixes prove the comment-only edits; separate import multiset/remaining-text proofs cover the import corrections. Release solution and layout host build with zero warnings/errors. A deliberate missing header fails the build, restoration passes, and the targeted header formatter verification passes. No runtime behavior or workflow changes. Co-Authored-By: Codex (GPT-6) <noreply@openai.com> Signed-off-by: James Maes <james@kof22.com> * fix(dev): enforce virtual agent origin and version boundaries Supply the exact configured Origin for unsafe cookie-authenticated requests, reject foreign or credential-bearing targets before sending headers, and preserve redirect refusal. Validate canonical stable three-part printing versions and compare components without numeric rounding. The two regressions fail before the fix; all seven Node tests pass afterward. The owned loopback fixture proves missing and foreign Origin refusal and zero foreign credential requests. Add the dependency-free tests to tooling CI using the protocol repository's pinned Node setup. Actionlint and zizmor pass; no production app or physical printer operations. Co-Authored-By: Codex (GPT-6) <noreply@openai.com> Signed-off-by: James Maes <james@kof22.com> * chore(standards): preserve owned-source copyright notices Add accurate repository copyright and license comments to 49 owned source/build/configuration files. Preserve existing holders, upstream wrappers, legal payloads and schema/data exemptions. Exact inverse-byte reconstruction and applicable parser/token/AST checks prove comment-only changes; existing relevant regressions pass. Co-Authored-By: Codex (GPT-6) <noreply@openai.com> Signed-off-by: James Maes <james@kof22.com> * chore: enforce owned source copyright notices Check real leading comments against explicit repository provenance and retain existing native style gates. Co-Authored-By: Codex GPT-6 <noreply@openai.com> Signed-off-by: James Maes <james@kof22.com> * feat: show Query and QRun links in About Bundle the official mascot and keep customer identity, credits and native navigation accessible with long names in both themes. Co-Authored-By: Codex GPT-6 <noreply@openai.com> Signed-off-by: James Maes <james@kof22.com> --------- Signed-off-by: James Maes <james@kof22.com> Co-authored-by: Codex (GPT-6) <noreply@openai.com>
This commit is contained in:
1 parent
e5846df715
commit
3c894733d1
197 files changed
+1822
-13
No files matched your search
@@ -29,6 +29,10 @@ trim_trailing_whitespace = false
|
||||
end_of_line = crlf
|
||||
|
||||
[*.cs]
|
||||
# Repository-owned C# sources retain the MIT notice in LICENSE; enforced by the existing build.
|
||||
file_header_template = Copyright (c) 2026 James Maes\nSPDX-License-Identifier: MIT
|
||||
dotnet_diagnostic.IDE0073.severity = warning
|
||||
|
||||
#### Formatting (IDE0055 makes every rule below a build error) ####
|
||||
dotnet_diagnostic.IDE0055.severity = warning
|
||||
dotnet_sort_system_directives_first = true
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Bug report
|
||||
description: Something is broken
|
||||
labels: [bug]
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Report a security vulnerability
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: Feature request
|
||||
description: Suggest an improvement
|
||||
labels: [enhancement]
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Dependabot for a KofTwentyTwo repository: copy to .github/dependabot.yml and keep
|
||||
# the ecosystems the repository uses. Updates are grouped weekly. A 7-day cooldown
|
||||
# lets the community catch a compromised release before it reaches us; security
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Categories for GitHub's auto-generated release notes (uses issue/PR labels).
|
||||
changelog:
|
||||
exclude:
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Reject missing/malformed CodeQL evidence before enforcing the severity gate."""
|
||||
import json
|
||||
import math
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Require scanner evidence for every resolved NuGet lock-file dependency."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Check leading notices in explicitly owned, Git-tracked source families."""
|
||||
|
||||
import fnmatch
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
def selected(name: str, policy: dict[str, Any]) -> bool:
|
||||
"""Select owned paths, honoring documented exact/pattern exclusions first."""
|
||||
if any(fnmatch.fnmatchcase(name, item["pattern"]) for item in policy["exclusions"]):
|
||||
return False
|
||||
return any(fnmatch.fnmatchcase(name, pattern) for pattern in policy["includes"])
|
||||
|
||||
|
||||
def leading_comments(text: str, style: str) -> str:
|
||||
"""Read comments only, preserving required interpreter/XML directive ordering."""
|
||||
text = text.removeprefix("\ufeff")
|
||||
if text.startswith("<?xml"):
|
||||
declaration = re.match(r"<\?xml[^?]*\?>", text)
|
||||
if style != "xml" or declaration is None:
|
||||
raise ValueError("Invalid XML declaration")
|
||||
text = text[declaration.end():]
|
||||
elif text.startswith("#!"):
|
||||
if style not in ("hash", "powershell", "slash"):
|
||||
raise ValueError("Unexpected interpreter directive")
|
||||
text = text.partition("\n")[2]
|
||||
while re.match(r"#Requires\b", text, re.IGNORECASE):
|
||||
if style != "powershell":
|
||||
raise ValueError("Unexpected PowerShell directive")
|
||||
text = text.partition("\n")[2]
|
||||
comments = []
|
||||
while text.strip():
|
||||
text = text.lstrip()
|
||||
if text.startswith("<?xml") or re.match(r"#!|#Requires\b", text, re.IGNORECASE):
|
||||
raise ValueError("Required declaration must precede the notice")
|
||||
if style in ("hash", "powershell") and text.startswith("#"):
|
||||
line, _, text = text.partition("\n")
|
||||
comments.append(line[1:])
|
||||
elif style == "slash" and text.startswith("//"):
|
||||
line, _, text = text.partition("\n")
|
||||
comments.append(line[2:])
|
||||
elif ((style == "slash" and text.startswith("/*"))
|
||||
or (style == "xml" and text.startswith("<!--"))
|
||||
or (style == "powershell" and text.startswith("<#"))):
|
||||
opening, closing = {"slash": ("/*", "*/"), "xml": ("<!--", "-->"), "powershell": ("<#", "#>")}[style]
|
||||
body, separator, rest = text[len(opening):].partition(closing)
|
||||
if not separator:
|
||||
raise ValueError("Unterminated leading comment")
|
||||
comments.append(body)
|
||||
text = rest
|
||||
else:
|
||||
break
|
||||
return "\n".join(re.sub(r"^\s*[*~]\s?", "", line).strip() for line in "\n".join(comments).splitlines())
|
||||
|
||||
|
||||
def check_notice(name: str, text: str, policy: dict[str, Any]) -> None:
|
||||
"""Require an approved holder/license pair in real leading comment syntax."""
|
||||
suffix = Path(name).suffix
|
||||
style = policy["styles"].get(suffix)
|
||||
if Path(name).name.startswith("Dockerfile."):
|
||||
style = "hash"
|
||||
if style is None:
|
||||
raise ValueError("Selected path has no configured comment syntax")
|
||||
comments = leading_comments(text, style)
|
||||
approved = [item for item in policy["notices"] if any(fnmatch.fnmatchcase(name, pattern) for pattern in item["paths"])]
|
||||
for notice in approved:
|
||||
holder = re.escape(notice["holder"])
|
||||
copyright_pattern = rf"(?m)^Copyright\s+(?:\([cC]\)\s*)?\d{{4}}(?:[-–]\d{{4}})?\.?\s+{holder}(?:\s+\(KofTwentyTwo\))?\.?(?:\s+Licensed under the MIT License \(see LICENSE\)\.)?$"
|
||||
if re.search(copyright_pattern, comments) is None:
|
||||
continue
|
||||
spdx = re.findall(r"(?m)^SPDX-License-Identifier:\s*(\S+)\s*$", comments)
|
||||
if spdx and any(value != notice["license"] for value in spdx):
|
||||
continue
|
||||
apache = all(phrase in comments for phrase in (
|
||||
"Licensed under the Apache License, Version 2.0",
|
||||
"you may not use this file except in compliance with the License.",
|
||||
"https://www.apache.org/licenses/LICENSE-2.0",
|
||||
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND",
|
||||
"limitations under the License.",
|
||||
))
|
||||
if suffix == ".java" and not apache:
|
||||
continue
|
||||
if notice["license"] in spdx or (notice["license"] == "Apache-2.0" and apache):
|
||||
return
|
||||
raise ValueError("Missing or mismatched leading copyright/license notice")
|
||||
|
||||
|
||||
def check_repository(root: Path, policy: dict[str, Any]) -> int:
|
||||
"""Check tracked sources without scanning build outputs or executing source."""
|
||||
tracked = subprocess.run(["git", "-C", str(root), "ls-files", "-z"], check=True, capture_output=True).stdout.decode("utf-8").split("\u0000")
|
||||
failures = []
|
||||
count = 0
|
||||
for name in tracked:
|
||||
if not name or not selected(name, policy):
|
||||
continue
|
||||
count += 1
|
||||
try:
|
||||
check_notice(name, (root / name).read_text(encoding="utf-8-sig"), policy)
|
||||
except (ValueError, OSError) as error:
|
||||
failures.append(f"{name}: {error}")
|
||||
if count == 0:
|
||||
raise ValueError("No owned source files selected")
|
||||
if failures:
|
||||
raise ValueError("\n".join(failures))
|
||||
return count
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""Load the repository-specific reviewed scope and fail CI on a bad notice."""
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
policy = json.loads((root / ".github/source-headers.json").read_text(encoding="utf-8"))
|
||||
count = check_repository(root, policy)
|
||||
print(f"Leading source notices verified: {count} tracked files")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except (ValueError, OSError, subprocess.CalledProcessError) as error:
|
||||
print(str(error), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Exercise the exact CI guards using synthetic evidence only."""
|
||||
import contextlib
|
||||
import copy
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""Exercise notice parsing, provenance, scope and real Git inventory rejection."""
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
SPEC = importlib.util.spec_from_file_location("headers", Path(__file__).with_name("check-source-headers.py"))
|
||||
assert SPEC is not None and SPEC.loader is not None
|
||||
HEADERS = importlib.util.module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(HEADERS)
|
||||
POLICY = json.loads(Path(__file__).parents[1].joinpath("source-headers.json").read_text(encoding="utf-8"))
|
||||
MIT = "Copyright (c) 2026 James Maes\nSPDX-License-Identifier: MIT"
|
||||
APACHE = """Copyright (C) 2021-2025. Kingsrook, LLC
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License."""
|
||||
|
||||
|
||||
def fixture_policy(holder: str = "James Maes", license_id: str = "MIT") -> dict[str, Any]:
|
||||
"""Use the production styles with a small explicit owned fixture scope."""
|
||||
return {"includes": ["src/*"], "exclusions": [], "styles": POLICY["styles"],
|
||||
"notices": [{"holder": holder, "license": license_id, "paths": ["src/*"]}]}
|
||||
|
||||
|
||||
class HeaderTests(unittest.TestCase):
|
||||
"""Ensure policy failures cannot pass through text-only copyright searches."""
|
||||
|
||||
def test_each_real_comment_syntax(self) -> None:
|
||||
"""Recognize hash, slash, block and XML notices in their own languages."""
|
||||
for name, text in (
|
||||
("src/a.py", "# " + MIT.replace("\n", "\n# ") + "\nprint(1)"),
|
||||
("src/a.cs", "// " + MIT.replace("\n", "\n// ") + "\nclass A {}"),
|
||||
("src/a.mjs", "/*\n * " + MIT.replace("\n", "\n * ") + "\n */\nexport {};"),
|
||||
("src/a.xml", "<!--\n" + MIT + "\n-->\n<root/>"),
|
||||
("src/a.ps1", "<#\n" + MIT + "\n#>\nWrite-Output 1"),
|
||||
):
|
||||
with self.subTest(name=name):
|
||||
HEADERS.check_notice(name, text, fixture_policy())
|
||||
|
||||
def test_required_first_lines_and_bom(self) -> None:
|
||||
"""Accept shebangs, PowerShell requirements and XML declarations first."""
|
||||
for name, prefix, body in (
|
||||
("src/a.sh", "#!/bin/sh\n", "# " + MIT.replace("\n", "\n# ")),
|
||||
("src/a.ps1", "#Requires -Version 7.4\n", "# " + MIT.replace("\n", "\n# ")),
|
||||
("src/a.xml", "<?xml version=\"1.0\"?>\n", "<!--" + MIT + "--><root/>"),
|
||||
("src/a.mjs", "#!/usr/bin/env node\n", "/*" + MIT + "*/"),
|
||||
):
|
||||
with self.subTest(name=name):
|
||||
HEADERS.check_notice(name, "\ufeff" + prefix + body, fixture_policy())
|
||||
|
||||
def test_misordered_required_first_lines_fail(self) -> None:
|
||||
"""A notice must not displace an interpreter or XML declaration."""
|
||||
for name, text in (
|
||||
("src/a.sh", "# " + MIT.replace("\n", "\n# ") + "\n#!/bin/sh"),
|
||||
("src/a.ps1", "# " + MIT.replace("\n", "\n# ") + "\n#Requires -Version 7.4"),
|
||||
("src/a.xml", "<!--" + MIT + "--><?xml version=\"1.0\"?><root/>"),
|
||||
):
|
||||
with self.subTest(name=name), self.assertRaises(ValueError):
|
||||
HEADERS.check_notice(name, text, fixture_policy())
|
||||
|
||||
def test_code_strings_and_late_comments_do_not_count(self) -> None:
|
||||
"""Reject docstrings and comments after executable declarations."""
|
||||
for text in ("notice = \"" + MIT.replace("\n", "\\n") + "\"",
|
||||
"\"\"\"" + MIT + "\"\"\"", "import os\n# " + MIT.replace("\n", "\n# ")):
|
||||
with self.subTest(text=text), self.assertRaises(ValueError):
|
||||
HEADERS.check_notice("src/a.py", text, fixture_policy())
|
||||
|
||||
def test_wrong_syntax_and_unterminated_comments_fail(self) -> None:
|
||||
"""Notice text alone is insufficient without a complete language comment."""
|
||||
for text in ("# " + MIT, "/*" + MIT, "string text = \"" + MIT + "\";"):
|
||||
with self.subTest(text=text), self.assertRaises(ValueError):
|
||||
HEADERS.check_notice("src/a.cs", text, fixture_policy())
|
||||
with self.assertRaises(ValueError):
|
||||
HEADERS.check_notice("src/a.py", "<#" + MIT + "#>", fixture_policy())
|
||||
|
||||
def test_wrong_holder_or_license_and_conflicting_spdx_fail(self) -> None:
|
||||
"""Do not conflate repository licenses or accept conflicting identifiers."""
|
||||
for text in (MIT.replace("James Maes", "Someone Else"), MIT.replace("MIT", "Apache-2.0"),
|
||||
MIT + "\nSPDX-License-Identifier: Apache-2.0", MIT.splitlines()[0]):
|
||||
with self.subTest(text=text), self.assertRaises(ValueError):
|
||||
HEADERS.check_notice("src/a.cs", "/*" + text + "*/", fixture_policy())
|
||||
|
||||
def test_complete_legacy_apache_without_spdx(self) -> None:
|
||||
"""Retain valid legacy year ranges and complete Apache notices."""
|
||||
policy = fixture_policy("Kingsrook, LLC", "Apache-2.0")
|
||||
HEADERS.check_notice("src/A.java", "/*" + APACHE + "*/\nclass A {}", policy)
|
||||
HEADERS.check_notice("src/a.xml", "<!--" + APACHE + "--><root/>", policy)
|
||||
|
||||
def test_java_requires_full_apache_block(self) -> None:
|
||||
"""An abbreviated SPDX-only Java notice cannot replace scoped convention."""
|
||||
policy = fixture_policy("Kingsrook, LLC", "Apache-2.0")
|
||||
for notice in ("Copyright 2026 Kingsrook, LLC\nSPDX-License-Identifier: Apache-2.0",
|
||||
APACHE.replace("limitations under the License.", "")):
|
||||
with self.subTest(notice=notice), self.assertRaises(ValueError):
|
||||
HEADERS.check_notice("src/A.java", "/*" + notice + "*/", policy)
|
||||
|
||||
def test_virtual_agent_provenance_is_path_scoped(self) -> None:
|
||||
"""Only the owned virtual-agent family may use its existing QRun.IO holder."""
|
||||
policy = fixture_policy()
|
||||
policy["notices"].append({"holder": "QRun.IO, Inc.", "license": "MIT", "paths": ["tools/virtual-agent/*"]})
|
||||
text = "/*Copyright 2026 QRun.IO, Inc. Licensed under the MIT License (see LICENSE).\nSPDX-License-Identifier: MIT*/"
|
||||
HEADERS.check_notice("tools/virtual-agent/a.mjs", text, policy)
|
||||
with self.assertRaises(ValueError):
|
||||
HEADERS.check_notice("src/a.mjs", text, policy)
|
||||
|
||||
def test_current_scope_and_documented_exclusions(self) -> None:
|
||||
"""New scripts enter the guard; data, generated and upstream files do not."""
|
||||
self.assertTrue(HEADERS.selected(".github/scripts/new-tool.py", POLICY))
|
||||
self.assertTrue(HEADERS.selected(".github/workflows/new-check.yml", POLICY))
|
||||
for name in (".mvn/wrapper/MavenWrapperDownloader.java", "mvnw", "schemas/new.json",
|
||||
"src/main/resources/openapi/new.yaml", "src/test/resources/openapi/old.yaml",
|
||||
"src/generated/Example.cs", "src/Example/obj/Generated.cs", "packages.lock.json"):
|
||||
with self.subTest(name=name):
|
||||
self.assertFalse(HEADERS.selected(name, POLICY))
|
||||
self.assertTrue(all(item["reason"].strip() for item in POLICY["exclusions"]))
|
||||
|
||||
def test_guard_sources_match_this_repository_provenance(self) -> None:
|
||||
"""Check copied guard files against local policy even before Git staging."""
|
||||
for filename in ("check-source-headers.py", "test-source-headers.py"):
|
||||
path = Path(__file__).with_name(filename)
|
||||
name = ".github/scripts/" + filename
|
||||
self.assertTrue(HEADERS.selected(name, POLICY))
|
||||
HEADERS.check_notice(name, path.read_text(encoding="utf-8"), POLICY)
|
||||
|
||||
def test_real_git_inventory_rejects_missing_tracked_header(self) -> None:
|
||||
"""A tracked new source fails while untracked generated output is ignored."""
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
subprocess.run(["git", "init", "-q", str(root)], check=True)
|
||||
root.joinpath("src").mkdir()
|
||||
source = root / "src/a.py"
|
||||
source.write_text("print(1)", encoding="utf-8")
|
||||
subprocess.run(["git", "-C", str(root), "add", "--", "src/a.py"], check=True)
|
||||
with self.assertRaisesRegex(ValueError, "src/a.py"):
|
||||
HEADERS.check_repository(root, fixture_policy())
|
||||
source.write_text("# " + MIT.replace("\n", "\n# ") + "\nprint(1)", encoding="utf-8")
|
||||
root.joinpath("src/untracked.py").write_text("print(2)", encoding="utf-8")
|
||||
self.assertEqual(1, HEADERS.check_repository(root, fixture_policy()))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"description": "Scope of the reviewed 2026-11-01 owned-source notice pass. Python fnmatch patterns match slash-containing relative paths. Native C# IDE0073 and full Java Apache conventions remain in force.",
|
||||
"includes": [
|
||||
".github/*.yml",
|
||||
".github/*.yaml",
|
||||
".github/scripts/*.py",
|
||||
".pre-commit-config.yaml",
|
||||
"Directory.Build.props",
|
||||
"Directory.Packages.props",
|
||||
"PSScriptAnalyzerSettings.psd1",
|
||||
"build/*.ps1",
|
||||
"installer/*.props",
|
||||
"installer/*.wxs",
|
||||
"installer/*.wixproj",
|
||||
"src/*.cs",
|
||||
"src/*.xaml",
|
||||
"src/*.csproj",
|
||||
"tests/*.cs",
|
||||
"tests/*.csproj",
|
||||
"tests/*.ps1",
|
||||
"tools/virtual-agent/*.mjs"
|
||||
],
|
||||
"exclusions": [
|
||||
{
|
||||
"pattern": "*.json",
|
||||
"reason": "Schema, fixtures, manifests and lock data: repository LICENSE/NOTICE, no comments."
|
||||
},
|
||||
{
|
||||
"pattern": "*.lock",
|
||||
"reason": "Dependency lock data, not owned executable source."
|
||||
},
|
||||
{
|
||||
"pattern": "*/generated/*",
|
||||
"reason": "Explicit generated-code directory."
|
||||
},
|
||||
{
|
||||
"pattern": "*/bin/*",
|
||||
"reason": "Generated build output."
|
||||
},
|
||||
{
|
||||
"pattern": "*/obj/*",
|
||||
"reason": "Generated build output."
|
||||
},
|
||||
{
|
||||
"pattern": "*/node_modules/*",
|
||||
"reason": "Third-party dependency output."
|
||||
},
|
||||
{
|
||||
"pattern": ".mvn/*",
|
||||
"reason": "Upstream Maven wrapper provenance."
|
||||
},
|
||||
{
|
||||
"pattern": "mvnw*",
|
||||
"reason": "Upstream Maven wrapper provenance."
|
||||
},
|
||||
{
|
||||
"pattern": "Assets/Legal/*",
|
||||
"reason": "Byte-exact third-party legal files."
|
||||
},
|
||||
{
|
||||
"pattern": "src/main/resources/*",
|
||||
"reason": "Bundled font/legal assets and OpenAPI schema data."
|
||||
},
|
||||
{
|
||||
"pattern": "src/test/resources/openapi/*",
|
||||
"reason": "Historical contract schema fixtures."
|
||||
},
|
||||
{
|
||||
"pattern": "*.slnx",
|
||||
"reason": "Solution metadata outside the completed source-header pass; root LICENSE/NOTICE applies."
|
||||
},
|
||||
{
|
||||
"pattern": "*.manifest",
|
||||
"reason": "Application activation metadata outside this pass; root LICENSE/NOTICE applies."
|
||||
},
|
||||
{
|
||||
"pattern": "*.runsettings",
|
||||
"reason": "Test runner metadata outside this pass; root LICENSE/NOTICE applies."
|
||||
},
|
||||
{
|
||||
"pattern": ".editorconfig",
|
||||
"reason": "Style configuration outside this pass; root LICENSE/NOTICE applies."
|
||||
}
|
||||
],
|
||||
"styles": {
|
||||
".py": "hash",
|
||||
".ps1": "powershell",
|
||||
".psd1": "powershell",
|
||||
".sh": "hash",
|
||||
".yml": "hash",
|
||||
".yaml": "hash",
|
||||
".cs": "slash",
|
||||
".java": "slash",
|
||||
".mjs": "slash",
|
||||
".js": "slash",
|
||||
".xml": "xml",
|
||||
".props": "xml",
|
||||
".csproj": "xml",
|
||||
".wxs": "xml",
|
||||
".wixproj": "xml",
|
||||
".xaml": "xml"
|
||||
},
|
||||
"notices": [
|
||||
{
|
||||
"paths": [
|
||||
".github/*",
|
||||
".pre-commit-config.yaml",
|
||||
"Directory.*.props",
|
||||
"PSScriptAnalyzerSettings.psd1",
|
||||
"build/*",
|
||||
"installer/*",
|
||||
"src/*",
|
||||
"tests/*"
|
||||
],
|
||||
"license": "MIT",
|
||||
"holder": "James Maes"
|
||||
},
|
||||
{
|
||||
"paths": [
|
||||
"tools/virtual-agent/*"
|
||||
],
|
||||
"license": "MIT",
|
||||
"holder": "QRun.IO, Inc."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: ci
|
||||
|
||||
on:
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Local copy of KofTwentyTwo/standards at fdf5ed029603c938615a32b1beca3628b8787945 (v0.1.2).
|
||||
# Pins, inputs and analysis checks preserved; report validation now fails closed.
|
||||
# Static analysis (K22-CI-22): CodeQL with the security-extended suite, failing on
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# CodeQL static analysis (K22-CI-22): security-extended queries for C# (a manual x64
|
||||
# build of the solution) and for the workflows themselves, blocking high severity.
|
||||
name: codeql
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Pull request gates (K22-CI-01): Conventional Commit title, DCO sign-off, and
|
||||
# dependency review, from the shared KofTwentyTwo/standards workflow pinned by SHA
|
||||
# (K22-CI-11). Dependabot's github-actions ecosystem keeps the pin current.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
name: prerelease
|
||||
|
||||
on:
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# OpenSSF Scorecard (K22-CI-24). Scorecard's publishing API only accepts results
|
||||
# from a workflow shaped exactly like this one: a single job, read-only top-level
|
||||
# permissions, no top-level env or defaults, and only the allowed steps.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# K22-CODE-SH: check repository tooling before merges and releases.
|
||||
name: scripts
|
||||
|
||||
@@ -10,6 +13,29 @@ on:
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
virtual-agent:
|
||||
name: virtual-agent
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||
with:
|
||||
node-version: '24'
|
||||
package-manager-cache: false
|
||||
- name: Verify owned source notices and rejection paths
|
||||
run: |
|
||||
python3 .github/scripts/test-source-headers.py
|
||||
python3 .github/scripts/check-source-headers.py
|
||||
- name: Verify virtual-agent protocol and HTTP boundaries
|
||||
run: node --test tools/virtual-agent/test/virtual-agent.test.mjs
|
||||
|
||||
powershell:
|
||||
name: powershell
|
||||
runs-on: windows-latest
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Local copy of KofTwentyTwo/standards at fdf5ed029603c938615a32b1beca3628b8787945 (v0.1.2).
|
||||
# Scanner pins/checks retained; NuGet inventory and OSV evidence now fail closed.
|
||||
# Security scanning (K22-CI-20, K22-CI-21, K22-CI-23): secrets over full history,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Security scans (K22-CI-20, K22-CI-21, K22-CI-23): gitleaks over full history,
|
||||
# Trivy + OSV-Scanner over the lock files, zizmor + actionlint over the workflows.
|
||||
# Runs on every pull request, every push to main, and weekly.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# KofTwentyTwo pre-commit configuration. Works with pre-commit and prek.
|
||||
# Copy to the repository root as .pre-commit-config.yaml, then install both hook
|
||||
# types once per clone:
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Project>
|
||||
|
||||
<!-- KofTwentyTwo .NET quality gate (standards: K22-CODE-CS, from
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Project>
|
||||
|
||||
<!-- Central package management (K22-CODE-CS-08): every version lives here, so
|
||||
|
||||
@@ -26,3 +26,7 @@ redistribution or end-user protection obligation.
|
||||
|
||||
The QQQ framework, qbit-printing and qqq-print-protocol are separate repositories;
|
||||
this notice does not change their licensing.
|
||||
|
||||
The About dialog bundles Query, the QQQ and QRun.IO dog mascot, supplied by
|
||||
QRun.IO. The unmodified artwork and provenance are in Assets/Query in the
|
||||
application payload and src/Qqq.PrintAgent/Assets/Query in this repository.
|
||||
@@ -1,3 +1,6 @@
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# KofTwentyTwo PowerShell analysis (K22-CODE-SH-05). CI runs:
|
||||
# ./build/Analyze-Scripts.ps1 (serial rule execution avoids upstream metadata races)
|
||||
# and `Invoke-Formatter` with the same settings for layout. PowerShell supports the
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $ScriptsDirectory = $PSScriptRoot
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Fails when any named assembly is below the required line coverage.
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidatePattern('^\d+\.\d+\.\d+$')]
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Regenerates the original cloud/printer mark and Windows icon sizes using WPF.
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[Parameter(Mandatory)] [string] $MsiPath,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string] $RepositoryRoot = (Split-Path $PSScriptRoot -Parent),
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#Requires -Version 7.4
|
||||
# Copyright (c) 2026 James Maes
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
[CmdletBinding()]
|
||||
param([string] $ProtocolFixtures)
|
||||
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# Session state — 2026-11-01
|
||||
|
||||
## Query in About — 2026-11-01
|
||||
|
||||
The shared AppKit About dialog now places Query and its public links in a compact
|
||||
two-column section just after the brand header. The original header logo/text
|
||||
are reparented into an Auto/Star Grid so long customer names wrap without
|
||||
clipping; identity, version, license and credits remain supplied by AppKit.
|
||||
The PNG is bundled unmodified with provenance on a 128-pixel white card.
|
||||
|
||||
The Release gate passes 426 tests (145 Core, 281 Windows/CLI), with zero build
|
||||
warnings/errors. The isolated native host passed image decoding, rendered
|
||||
contrast, initial mascot/link/name visibility, scrolling, keyboard focus and
|
||||
Close checks in both themes with a long synthetic customer name at observed
|
||||
125% DPI; full dialog captures verify the refinement. The private publish output contains
|
||||
the exact PNG, provenance and required WinUI resources. These About changes are
|
||||
not yet released or installed; the native host uses synthetic service responses.
|
||||
|
||||
## Published and installed 0.3.2 — 2026-11-01
|
||||
|
||||
[0.3.2-rc.1](https://github.com/QRun-IO/qqq-print-agent/releases/tag/v0.3.2-rc.1)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# C# source header checkpoint
|
||||
|
||||
The 2026-11-01 review of baseline `268f951b6728b0e69fedaf46769785c3f5ae55f4`
|
||||
identified 127 of 221 tracked, repository-owned C# files without a copyright
|
||||
header. Those files now carry the existing `Copyright (c) 2026 James Maes` and
|
||||
`SPDX-License-Identifier: MIT` notice from this repository's LICENSE. Existing
|
||||
copyright notices were preserved; one existing SPDX marker's casing was corrected.
|
||||
Vendor notices and generated files were not rewritten.
|
||||
|
||||
This addresses KofTwentyTwo K22-CODE-24, which recommends source license headers
|
||||
outside Java. The native .NET IDE0073 analyzer now enforces this repository's
|
||||
header through `.editorconfig` and the existing warnings-as-errors build. No
|
||||
workflow, dependency or application behavior was changed. Three existing pairs
|
||||
of namespace imports were also reordered to satisfy the targeted formatter.
|
||||
|
||||
Validation:
|
||||
|
||||
- All 221 tracked C# files have the canonical header.
|
||||
- Roslyn token kind, original token text and value text are identical for all
|
||||
128 header/marker edits, before the separate import corrections. Each of the 127 additions also preserves the original
|
||||
source text exactly after the prepended comment. This is source-token
|
||||
equivalence, not a claim of byte-identical PDBs or assemblies.
|
||||
- Release solution build passed with zero warnings and errors.
|
||||
- The separate layout-test host also compiled with zero warnings and errors;
|
||||
it was not launched.
|
||||
- A deliberate missing-header case failed with IDE0073; restoring the exact
|
||||
source made the build pass. No application or printer operations were run.
|
||||
- `git diff --check` passed.
|
||||
|
||||
The read-only `dotnet format style --diagnostics IDE0073 --verify-no-changes`
|
||||
command also checks imports. It initially reported three existing import-order
|
||||
differences in `AgentRuntime.Controls.cs`, `AgentRuntime.RealtimeStatus.cs`, and
|
||||
`PrinterWorkerIsolationTests.cs`. Each correction swaps only two adjacent,
|
||||
ordinary namespace imports. A separate comparison confirms the same import
|
||||
multiset and identical remaining source text. The targeted command then exited
|
||||
successfully; it emitted a workspace-loading warning. This filtered check does
|
||||
not claim full formatter coverage. The full solution was rebuilt after the
|
||||
import corrections.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Owned source notice check
|
||||
|
||||
Run these commands from the repository root with the existing Python 3 interpreter:
|
||||
|
||||
```text
|
||||
python3 .github/scripts/test-source-headers.py
|
||||
python3 .github/scripts/check-source-headers.py
|
||||
```
|
||||
|
||||
The standard-library checker enforces the scope of the reviewed 2026-11-01 header pass, not an estate-wide licensing or formatting audit. `.github/source-headers.json` names the owned source/config path families, comment syntax, accepted holder/license pairs and explicit exclusion reasons. Python `fnmatch` patterns match slash-containing relative Git paths; new files in those families are covered after they are tracked. Empty selections fail. The checker does not scan untracked build output or modify files.
|
||||
|
||||
Only leading language comments count. Copyright text in a string, Python docstring or comment after code is rejected. UTF-8 BOMs, initial shebangs, PowerShell `#Requires` directives and XML declarations are handled before the notice. These declarations cannot be displaced beneath a new notice. PowerShell block comments are recognized only for PowerShell files. Existing years and holders are not rewritten. Complete canonical Apache notices are valid without redundant SPDX; Java still requires the full Apache block. A contradictory SPDX identifier fails.
|
||||
|
||||
JSON/schema/fixture/lock data, explicit generated output directories, vendor legal assets and upstream Maven wrappers are excluded with reasons in the policy. Solution/activation/test-runner metadata and `.editorconfig` remain outside this completed pass; their applicable root LICENSE/NOTICE remains authoritative. No broad claim about third-party licensing follows from this check. New owned file types or provenance must be reviewed before changing the allowlist; do not add blanket exclusions to make a failure disappear.
|
||||
|
||||
The implementation and its negative tests are intentionally maintained copies across the three printing repositories, with each repository's own copyright/license header and independently reviewed scope. They do not fetch policy or execute source. CI invokes them in existing jobs using the runner's available Python, with no new package or workflow context. Existing native C# IDE0073 and Java Checkstyle conventions remain unchanged.
|
||||
This client accepts James Maes / MIT in its reviewed source/build/config families and preserves QRun.IO, Inc. / MIT solely in tools/virtual-agent. The existing scripts / virtual-agent job runs the guard.
|
||||
@@ -1,5 +1,13 @@
|
||||
# TODO
|
||||
|
||||
## Query in About
|
||||
|
||||
- [x] Place the official mascot and dogfooding/Query links directly below the
|
||||
shared About header, preserving customer logos, identity and credits.
|
||||
- [x] Verify both native themes, initial image/link visibility, unclipped names and
|
||||
Close; pass the 426-test Release gate and exact publish-payload asset check.
|
||||
- [ ] Package, publish and verify the About change in an installed follow-up.
|
||||
|
||||
## Companion layout, live transport status and startup follow-up
|
||||
|
||||
- [x] Install the attested published 0.3.1 MSI; verify all three exact component versions, automatic WebSocket restoration and preserved local receipts, pairing and profiles.
|
||||
|
||||
@@ -113,3 +113,13 @@ Direct MSI and branded installation enforce this invariant before using persiste
|
||||
Unreadable session ciphertext is quarantined only on explicit sign-out or after fresh sign-in and authoritative binding succeed. Unreadable device proof remains in place until explicit enrollment replaces it; old journal scopes and local printer exposure are retained. Recovery never invents device authority or retries old print submissions. A missing readable session cannot be remotely revoked by local sign-out; the UI reports the separate QQQ revocation requirement. Background traffic remains fail closed.
|
||||
|
||||
Replacement pairing requires an explicit local setup choice and fresh standard QQQ authentication. Its persisted unbound identity prevents restoration from presenting old, revoked device proof. New claims remain gated until successful enrollment, binding and control synchronization. Default sign-in still requires the saved pairing's authoritative binding. Failed setup preserves old configuration; successful replacement changes journal scope without replaying prior-device work.
|
||||
|
||||
### Virtual development agent HTTP boundary
|
||||
|
||||
The virtual agent's native HTTP request helper rejects foreign origins before
|
||||
attaching session or device credentials, refuses redirects, and sends the exact
|
||||
configured Origin on unsafe cookie-authenticated requests. This preserves the
|
||||
server's missing/foreign-Origin rejection. Discovery accepts canonical stable
|
||||
three-part printing versions in major 2, matching the protocol fixtures.
|
||||
Synthetic loopback HTTP tests cover these boundaries; they do not establish
|
||||
production authentication, durable spooling or physical printing acceptance.
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Project>
|
||||
<!-- MSI authoring is not a C# compilation; do not inherit runtime analyzers. -->
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||
<Package Name="QQQ Print Agent" Manufacturer="QRun-IO" Version="$(ProductVersion)"
|
||||
UpgradeCode="D761CD03-F616-4C98-9A94-9F590A36E449" Scope="perMachine" InstallerVersion="500">
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Project Sdk="WixToolset.Sdk/6.0.2">
|
||||
<PropertyGroup>
|
||||
<OutputType>Package</OutputType>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!-- The scriptable head over the same Core as the window. Ships as a self-contained
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Net.WebSockets;
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Authentication;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Net.WebSockets;
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Authentication;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
public sealed record DeviceControlCommand(string CommandId, string RequestId, string Action, string CreatedAt, string ExpiresAt, string? JobId = null);
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
public sealed record DeviceControlPoll(int ControlVersion, string ServerTime, int PollIntervalSeconds, DeviceDesiredState DesiredState, IReadOnlyList<DeviceControlCommand> Commands);
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
public sealed record DeviceControlReceipt(string ReceiptId, string Outcome, string CompletedAt, string? Message = null);
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
/// <summary>Owns a verified staging file and prevents replacement until the native worker finishes.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
/// <summary>Consumes a verified file while its owner retains the read-only lease; no document travels in a control message.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
public sealed partial class PrintApiClient
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Authentication;
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
public sealed record PrintWorkerOptions
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text.Json;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
/// <summary>Suggested diagnostic defaults; the operator must still verify installed stock and resolution.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<!-- Everything that can be tested without a window lives here (architecture: "the
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Transport;
|
||||
|
||||
/// <summary>Application payload bytes only: no headers, framing, TLS, credentials or document contents.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Transport;
|
||||
|
||||
public sealed record ApplicationTrafficSnapshot(long UploadedBytes, long DownloadedBytes, double UploadBytesPerSecond, double DownloadBytesPerSecond, DateTimeOffset TotalsSinceUtc);
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Net;
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Transport;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Core.Transport;
|
||||
|
||||
/// <summary>Counts completed payload reads or writes without buffering or retaining their contents.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Copyright (c) 2026 James Maes
|
||||
SPDX-License-Identifier: MIT
|
||||
-->
|
||||
|
||||
<Project Sdk="Microsoft.NET.Sdk.Worker">
|
||||
<PropertyGroup><TargetFramework>net10.0-windows10.0.19041.0</TargetFramework><OutputType>Exe</OutputType></PropertyGroup>
|
||||
<ItemGroup><PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" /></ItemGroup>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Authentication;
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
/// <summary>Safe companion status, with no cookie, password or device proof.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
public static class AgentControlLabels
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Authentication;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Globalization;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
public sealed partial class AgentRuntime
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
using Qqq.PrintAgent.Core.Authentication;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Authentication;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Text.Json;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Net.WebSockets;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Channels;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
using System.Threading.Channels;
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Threading.Channels;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Authentication;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using Qqq.PrintAgent.Core.Transport;
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using Qqq.PrintAgent.Core.Authentication;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Globalization;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Globalization;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Text.Json;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
using System.Text.Json;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Qqq.PrintAgent.Core.Printing;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
/// <summary>Local observations of the cloud transport. Totals span this service lifetime, including reconnects.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-license-Identifier: MIT
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
/// <summary>Retained local evidence for a job, independent of physical output confirmation.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
public sealed record JobEventSnapshot(string EventId, string Status, string RecordedAt, string? Message, string? SpoolerJobId, bool Delivered);
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
/// <summary>Shared visible job labels used by the companion and server-side local sorting.</summary>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
public sealed record JobPage(IReadOnlyList<JobSnapshot> Jobs, int TotalCount, int Offset, int PageSize, bool ServerQueueLimited = false);
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2026 James Maes
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
namespace Qqq.PrintAgent.Windows;
|
||||
|
||||
/// <summary>Queries durable local history; search matches the start of a job ID, title or printer name.</summary>
|
||||
|
||||
Loaded 100 of 197 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user