webarchiver 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- webarchiver-1.2.0/.bumpversion.cfg +16 -0
- webarchiver-1.2.0/.config/spec-dashboard.json +4 -0
- webarchiver-1.2.0/.github/workflows/pages.yml +25 -0
- webarchiver-1.2.0/.github/workflows/pipeline.yml +27 -0
- webarchiver-1.2.0/.github/workflows/scanners.yml +42 -0
- webarchiver-1.2.0/.github/workflows/windows-ci.yml +78 -0
- webarchiver-1.2.0/.pipeline-theme/provenance.json +21 -0
- webarchiver-1.2.0/.pipeline-theme/scripts/sync_mkdocs_theme.py +204 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/README.md +27 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-connector-sdk-logo-v1.png +0 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-terminal-ui-logo-v1.png +0 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-utilities-logo-v1.png +0 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-webui-logo-v1.png +0 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/arbora-logo-v1.png +0 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/epistemic-graph-logo-v1.png +0 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/geniusbot-logo-v1.png +0 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/favicon.svg +13 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/graph-mark.svg +13 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/base.mkdocs.yml +105 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/extra.css +249 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/glossary.md +57 -0
- webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/overrides/main.html +57 -0
- webarchiver-1.2.0/.pre-commit-config.yaml +79 -0
- webarchiver-1.2.0/LICENSE +21 -0
- webarchiver-1.2.0/MANIFEST.in +19 -0
- webarchiver-1.2.0/PKG-INFO +207 -0
- webarchiver-1.2.0/README.md +175 -0
- webarchiver-1.2.0/docker/Dockerfile +31 -0
- webarchiver-1.2.0/docker/debug.Dockerfile +31 -0
- webarchiver-1.2.0/docker/mcp.compose.yml +35 -0
- webarchiver-1.2.0/docker/starship.toml +70 -0
- webarchiver-1.2.0/docs/agent-readiness.json +31 -0
- webarchiver-1.2.0/docs/agent-readiness.schema.json +331 -0
- webarchiver-1.2.0/docs/architecture.md +34 -0
- webarchiver-1.2.0/docs/assets/brands/agent-connector-sdk-logo-v1.png +0 -0
- webarchiver-1.2.0/docs/assets/brands/agent-terminal-ui-logo-v1.png +0 -0
- webarchiver-1.2.0/docs/assets/brands/agent-utilities-logo-v1.png +0 -0
- webarchiver-1.2.0/docs/assets/brands/agent-webui-logo-v1.png +0 -0
- webarchiver-1.2.0/docs/assets/brands/arbora-logo-v1.png +0 -0
- webarchiver-1.2.0/docs/assets/brands/epistemic-graph-logo-v1.png +0 -0
- webarchiver-1.2.0/docs/assets/brands/geniusbot-logo-v1.png +0 -0
- webarchiver-1.2.0/docs/assets/favicon.svg +13 -0
- webarchiver-1.2.0/docs/assets/graph-mark.svg +13 -0
- webarchiver-1.2.0/docs/capabilities/api.json +1 -0
- webarchiver-1.2.0/docs/capabilities/mcp.json +1 -0
- webarchiver-1.2.0/docs/concepts.md +12 -0
- webarchiver-1.2.0/docs/deployment.md +139 -0
- webarchiver-1.2.0/docs/glossary.md +57 -0
- webarchiver-1.2.0/docs/index.md +33 -0
- webarchiver-1.2.0/docs/installation.md +36 -0
- webarchiver-1.2.0/docs/overview.md +21 -0
- webarchiver-1.2.0/docs/platform.md +22 -0
- webarchiver-1.2.0/docs/spec-delivery.md +18 -0
- webarchiver-1.2.0/docs/stylesheets/extra.css +249 -0
- webarchiver-1.2.0/docs/usage.md +36 -0
- webarchiver-1.2.0/mkdocs.yml +27 -0
- webarchiver-1.2.0/pyproject.toml +85 -0
- webarchiver-1.2.0/pytest.ini +11 -0
- webarchiver-1.2.0/scripts/agent_readiness_tck.py +1138 -0
- webarchiver-1.2.0/scripts/bootstrap_environment.py +235 -0
- webarchiver-1.2.0/scripts/bootstrap_sources.py +129 -0
- webarchiver-1.2.0/scripts/check_connector_contract.py +115 -0
- webarchiver-1.2.0/scripts/check_import_safety.py +308 -0
- webarchiver-1.2.0/scripts/check_workspace_source_drift.py +98 -0
- webarchiver-1.2.0/scripts/generate_agent_readiness.py +1531 -0
- webarchiver-1.2.0/scripts/generate_tool_schemas.py +100 -0
- webarchiver-1.2.0/scripts/security_sanitizer.py +279 -0
- webarchiver-1.2.0/scripts/select_python.py +85 -0
- webarchiver-1.2.0/scripts/verify_api_integration.py +78 -0
- webarchiver-1.2.0/scripts/workspace_sources.py +250 -0
- webarchiver-1.2.0/setup.cfg +4 -0
- webarchiver-1.2.0/specs/README.md +11 -0
- webarchiver-1.2.0/specs/web-source/plan.md +29 -0
- webarchiver-1.2.0/specs/web-source/requirements.md +18 -0
- webarchiver-1.2.0/specs/web-source/spec.md +26 -0
- webarchiver-1.2.0/specs/web-source/status.json +143 -0
- webarchiver-1.2.0/specs/web-source/tasks.md +14 -0
- webarchiver-1.2.0/specs/web-source/test-spec.md +16 -0
- webarchiver-1.2.0/tests/__init__.py +0 -0
- webarchiver-1.2.0/tests/conftest.py +76 -0
- webarchiver-1.2.0/tests/fixtures/article.html +31 -0
- webarchiver-1.2.0/tests/test_concept_parity.py +17 -0
- webarchiver-1.2.0/tests/test_conformance.py +39 -0
- webarchiver-1.2.0/tests/test_crawl.py +67 -0
- webarchiver-1.2.0/tests/test_error_authority.py +68 -0
- webarchiver-1.2.0/tests/test_extract.py +157 -0
- webarchiver-1.2.0/tests/test_init_dynamics.py +10 -0
- webarchiver-1.2.0/tests/test_kg_ingest.py +55 -0
- webarchiver-1.2.0/tests/test_served.py +83 -0
- webarchiver-1.2.0/tests/test_startup.py +68 -0
- webarchiver-1.2.0/tests/test_webarchiver_mcp_validation.py +14 -0
- webarchiver-1.2.0/webarchiver/__init__.py +54 -0
- webarchiver-1.2.0/webarchiver/__main__.py +4 -0
- webarchiver-1.2.0/webarchiver/_version.py +3 -0
- webarchiver-1.2.0/webarchiver/api/__init__.py +11 -0
- webarchiver-1.2.0/webarchiver/api/_support.py +19 -0
- webarchiver-1.2.0/webarchiver/api/api_client_system.py +120 -0
- webarchiver-1.2.0/webarchiver/api/browser.py +247 -0
- webarchiver-1.2.0/webarchiver/api/crawl.py +166 -0
- webarchiver-1.2.0/webarchiver/api/extraction.py +130 -0
- webarchiver-1.2.0/webarchiver/api/fetcher.py +186 -0
- webarchiver-1.2.0/webarchiver/api/policy.py +170 -0
- webarchiver-1.2.0/webarchiver/api/web_source.py +87 -0
- webarchiver-1.2.0/webarchiver/auth.py +47 -0
- webarchiver-1.2.0/webarchiver/connector_manifest.yml +89 -0
- webarchiver-1.2.0/webarchiver/connectors/__init__.py +0 -0
- webarchiver-1.2.0/webarchiver/connectors/mcp_source_presets.json +1 -0
- webarchiver-1.2.0/webarchiver/connectors/tool_schema_fingerprints.json +1 -0
- webarchiver-1.2.0/webarchiver/error_authority.py +248 -0
- webarchiver-1.2.0/webarchiver/error_rendering.py +105 -0
- webarchiver-1.2.0/webarchiver/kg_ingest.py +93 -0
- webarchiver-1.2.0/webarchiver/mcp/__init__.py +3 -0
- webarchiver-1.2.0/webarchiver/mcp/mcp_system.py +11 -0
- webarchiver-1.2.0/webarchiver/mcp_config.json +3 -0
- webarchiver-1.2.0/webarchiver/mcp_server.py +62 -0
- webarchiver-1.2.0/webarchiver/ontology/__init__.py +6 -0
- webarchiver-1.2.0/webarchiver/ontology/pack.ttl +48 -0
- webarchiver-1.2.0/webarchiver/ontology/webarchiver.ttl +29 -0
- webarchiver-1.2.0/webarchiver/prompts/__init__.py +0 -0
- webarchiver-1.2.0/webarchiver/prompts/webarchiver_specialist.json +30 -0
- webarchiver-1.2.0/webarchiver/skills/__init__.py +0 -0
- webarchiver-1.2.0/webarchiver/skills/webarchiver-starter/SKILL.md +25 -0
- webarchiver-1.2.0/webarchiver/webarchiver_input_models.py +12 -0
- webarchiver-1.2.0/webarchiver/webarchiver_response_models.py +15 -0
- webarchiver-1.2.0/webarchiver.egg-info/PKG-INFO +207 -0
- webarchiver-1.2.0/webarchiver.egg-info/SOURCES.txt +128 -0
- webarchiver-1.2.0/webarchiver.egg-info/dependency_links.txt +1 -0
- webarchiver-1.2.0/webarchiver.egg-info/entry_points.txt +2 -0
- webarchiver-1.2.0/webarchiver.egg-info/requires.txt +16 -0
- webarchiver-1.2.0/webarchiver.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[bumpversion]
|
|
2
|
+
current_version = 1.2.0
|
|
3
|
+
commit = True
|
|
4
|
+
tag = True
|
|
5
|
+
|
|
6
|
+
[bumpversion:file:pyproject.toml]
|
|
7
|
+
search = version = "{current_version}"
|
|
8
|
+
replace = version = "{new_version}"
|
|
9
|
+
|
|
10
|
+
[bumpversion:file:webarchiver/_version.py]
|
|
11
|
+
search = __version__ = "{current_version}"
|
|
12
|
+
replace = __version__ = "{new_version}"
|
|
13
|
+
|
|
14
|
+
[bumpversion:file(dockerpin):docker/Dockerfile]
|
|
15
|
+
search = webarchiver[mcp]=={current_version}
|
|
16
|
+
replace = webarchiver[mcp]=={new_version}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Deploy GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish-pages:
|
|
13
|
+
uses: Knuckles-Team/pipelines/.github/workflows/pages_pipeline.yml@main
|
|
14
|
+
with:
|
|
15
|
+
content_source: docs
|
|
16
|
+
shared_theme_enabled: true
|
|
17
|
+
agent_readiness_enabled: true
|
|
18
|
+
readiness_input: docs/agent-readiness.json
|
|
19
|
+
readiness_schema: docs/agent-readiness.schema.json
|
|
20
|
+
spec_dashboard_enabled: true
|
|
21
|
+
spec_dashboard_config: .config/spec-dashboard.json
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
pages: write
|
|
25
|
+
id-token: write
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Build|Upload|Release Python Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- 'main'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish-pypi:
|
|
13
|
+
uses: Knuckles-Team/pipelines/.github/workflows/python_pipeline.yml@main
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
secrets:
|
|
17
|
+
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
18
|
+
publish-docker:
|
|
19
|
+
needs: publish-pypi
|
|
20
|
+
uses: Knuckles-Team/pipelines/.github/workflows/container_pipeline.yml@main
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
secrets:
|
|
24
|
+
DOCKER_REGISTRY: ${{ secrets.DOCKER_REGISTRY }}
|
|
25
|
+
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
|
26
|
+
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
27
|
+
DOCKER_REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Connector quality
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
checks:
|
|
14
|
+
# The runner supplies bootstrap Python, uv, pre-commit and approved scanners.
|
|
15
|
+
# Prepare project dependencies separately; never build scanners here.
|
|
16
|
+
runs-on: self-hosted
|
|
17
|
+
env:
|
|
18
|
+
MCP_FLEET_REGISTRATION: 'false'
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
- name: Capture provisioned hook runner
|
|
25
|
+
shell: bash
|
|
26
|
+
run: |
|
|
27
|
+
hook_runner="$(realpath "$(command -v pre-commit)")"
|
|
28
|
+
test -x "$hook_runner"
|
|
29
|
+
echo "CONNECTOR_PRE_COMMIT=$hook_runner" >> "$GITHUB_ENV"
|
|
30
|
+
- name: Select provisioned Python baseline
|
|
31
|
+
run: python scripts/select_python.py
|
|
32
|
+
- name: Prepare frozen project test environment
|
|
33
|
+
run: '"$CONNECTOR_BOOTSTRAP_PYTHON" scripts/bootstrap_environment.py --github'
|
|
34
|
+
- name: Validate hooks
|
|
35
|
+
run: '"$CONNECTOR_PRE_COMMIT" validate-config'
|
|
36
|
+
- name: Commit checks
|
|
37
|
+
run: '"$CONNECTOR_PRE_COMMIT" run --all-files --show-diff-on-failure'
|
|
38
|
+
- name: Push checks and generated connector tests
|
|
39
|
+
env:
|
|
40
|
+
PRE_COMMIT_FROM_REF: ${{ github.event.pull_request.base.sha || github.event.before }}
|
|
41
|
+
PRE_COMMIT_TO_REF: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
42
|
+
run: '"$CONNECTOR_PRE_COMMIT" run --all-files --hook-stage pre-push --show-diff-on-failure'
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: Cross-platform coverage
|
|
2
|
+
|
|
3
|
+
# Report-only (continue-on-error on every step) -- does not touch
|
|
4
|
+
# pipeline.yml/pages.yml. scripts/check_import_safety.py auto-detects this
|
|
5
|
+
# package's import name from pyproject.toml's [project].name, so this file
|
|
6
|
+
# needs no per-package templating. See that script's own docstring for
|
|
7
|
+
# exactly what --simulate-windows does and does not model, and its
|
|
8
|
+
# sys.platform-guard false-positive limitation -- if this package
|
|
9
|
+
# legitimately guards a POSIX-only import behind
|
|
10
|
+
# `sys.platform == "win32"`, add `--exclude <dotted.module.name>` to BOTH
|
|
11
|
+
# this file's windows job below and .pre-commit-config.yaml's
|
|
12
|
+
# check-import-safety hook.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
pull_request:
|
|
16
|
+
paths:
|
|
17
|
+
- 'webarchiver/**'
|
|
18
|
+
- 'scripts/**'
|
|
19
|
+
- 'tests/**'
|
|
20
|
+
- 'pyproject.toml'
|
|
21
|
+
- 'uv.lock'
|
|
22
|
+
- '.github/workflows/windows-ci.yml'
|
|
23
|
+
push:
|
|
24
|
+
branches:
|
|
25
|
+
- 'main'
|
|
26
|
+
|
|
27
|
+
permissions:
|
|
28
|
+
contents: read
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
windows:
|
|
32
|
+
name: Windows coverage (report only, never blocks)
|
|
33
|
+
runs-on: windows-latest
|
|
34
|
+
permissions:
|
|
35
|
+
contents: read
|
|
36
|
+
defaults:
|
|
37
|
+
run:
|
|
38
|
+
shell: bash
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
41
|
+
with:
|
|
42
|
+
persist-credentials: false
|
|
43
|
+
|
|
44
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
45
|
+
with:
|
|
46
|
+
python-version: '3.14'
|
|
47
|
+
|
|
48
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
|
49
|
+
with:
|
|
50
|
+
version: '0.11.7'
|
|
51
|
+
enable-cache: true
|
|
52
|
+
cache-dependency-glob: uv.lock
|
|
53
|
+
|
|
54
|
+
- name: Sync test environment
|
|
55
|
+
id: sync
|
|
56
|
+
continue-on-error: true
|
|
57
|
+
run: |
|
|
58
|
+
uv sync --extra test
|
|
59
|
+
echo "$PWD/.venv/Scripts" >> "$GITHUB_PATH"
|
|
60
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
61
|
+
|
|
62
|
+
- name: Cross-platform import safety (real Windows interpreter)
|
|
63
|
+
if: steps.sync.outcome == 'success'
|
|
64
|
+
continue-on-error: true
|
|
65
|
+
run: python3 scripts/check_import_safety.py
|
|
66
|
+
|
|
67
|
+
- name: Unit tests
|
|
68
|
+
if: steps.sync.outcome == 'success'
|
|
69
|
+
continue-on-error: true
|
|
70
|
+
run: python3 -m pytest tests -q --tb=short --timeout=120
|
|
71
|
+
|
|
72
|
+
- name: Windows coverage summary
|
|
73
|
+
if: always()
|
|
74
|
+
run: |
|
|
75
|
+
echo "## Windows coverage ran in report-only mode" >> "$GITHUB_STEP_SUMMARY"
|
|
76
|
+
echo "Both steps above use continue-on-error: true -- a red step" >> "$GITHUB_STEP_SUMMARY"
|
|
77
|
+
echo "here is a real Windows regression and never blocks the" >> "$GITHUB_STEP_SUMMARY"
|
|
78
|
+
echo "publish pipeline." >> "$GITHUB_STEP_SUMMARY"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": {
|
|
3
|
+
"scripts/sync_mkdocs_theme.py": "bec06ab81fcf5df697b37419324535d2385be2675d34dd093f60190c12c2e390",
|
|
4
|
+
"templates/mkdocs-theme/README.md": "e5484fae67ffa597e6f40747f52b2e321b9b1b31612b6d5a141a2dcf6029f180",
|
|
5
|
+
"templates/mkdocs-theme/assets/brands/agent-connector-sdk-logo-v1.png": "6688810468a77118ee1960ac3872816c6ace4f750a849688d306d7a63132e1b1",
|
|
6
|
+
"templates/mkdocs-theme/assets/brands/agent-terminal-ui-logo-v1.png": "d5e3c011066e2241c09c885f65d9a07c6ff32f4244b00dbe8e7550a3bab20dc8",
|
|
7
|
+
"templates/mkdocs-theme/assets/brands/agent-utilities-logo-v1.png": "923319a3b89fa1fbd14ca14c27cf49d2e2d9f85bc45456e05b788692700f0103",
|
|
8
|
+
"templates/mkdocs-theme/assets/brands/agent-webui-logo-v1.png": "3939a7324f134c520fd544aadd2a37c99abba9db78dd2bf3fd5003ffd62502ff",
|
|
9
|
+
"templates/mkdocs-theme/assets/brands/arbora-logo-v1.png": "bba183368e42927edea91013639311a5d64f5a9910ec2f1bdcc7f4cd32f9d230",
|
|
10
|
+
"templates/mkdocs-theme/assets/brands/epistemic-graph-logo-v1.png": "26671aef2c3b78ecdcca2ad13adfd266cebf8d7e666e614c2d83d166b853d272",
|
|
11
|
+
"templates/mkdocs-theme/assets/brands/geniusbot-logo-v1.png": "c4a17404f234f677496197ac202ca8fb30b136c5a69243811bbfa6e5d5352b28",
|
|
12
|
+
"templates/mkdocs-theme/assets/favicon.svg": "aa606f9668a363bfe533f7d835700c246efaed0b8895cce5fe4398f36c35e7ba",
|
|
13
|
+
"templates/mkdocs-theme/assets/graph-mark.svg": "d0c69cdc06aa51439b6ce04b4c6df4dbf02283329f01122a78e08f286186e25d",
|
|
14
|
+
"templates/mkdocs-theme/base.mkdocs.yml": "5424438de987d1ea222f8ce4467e830f286784d14e35b71c623616c9a6ce87d9",
|
|
15
|
+
"templates/mkdocs-theme/extra.css": "2cc17b7610b67c82895312e7e61cf84587a6fe291bbc154d3c83c59fba2ee843",
|
|
16
|
+
"templates/mkdocs-theme/glossary.md": "f35f337fd8175dfdd274442795558772ae3138bb95fc31d84937f5047bff1f64",
|
|
17
|
+
"templates/mkdocs-theme/overrides/main.html": "766234b5045a5815805bb2ce5223ddd93729f7854abc4b6cdf4fba9c7e0dab3b"
|
|
18
|
+
},
|
|
19
|
+
"repository": "https://github.com/Knuckles-Team/pipelines",
|
|
20
|
+
"revision": "58e9bbc62557f2d4a07438070b1ceebb5864a81f"
|
|
21
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""Synchronize generated ecosystem MkDocs theme files into a consumer repo."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import re
|
|
7
|
+
import sys
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class ThemeFile:
|
|
15
|
+
"""A canonical source file and its generated consumer-relative path."""
|
|
16
|
+
|
|
17
|
+
source: str
|
|
18
|
+
destination: str
|
|
19
|
+
content_relative: bool = True
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
THEME_FILES = (
|
|
23
|
+
ThemeFile("extra.css", "stylesheets/extra.css"),
|
|
24
|
+
ThemeFile("assets/graph-mark.svg", "assets/graph-mark.svg"),
|
|
25
|
+
ThemeFile("assets/favicon.svg", "assets/favicon.svg"),
|
|
26
|
+
ThemeFile(
|
|
27
|
+
"assets/brands/epistemic-graph-logo-v1.png",
|
|
28
|
+
"assets/brands/epistemic-graph-logo-v1.png",
|
|
29
|
+
),
|
|
30
|
+
ThemeFile(
|
|
31
|
+
"assets/brands/agent-utilities-logo-v1.png",
|
|
32
|
+
"assets/brands/agent-utilities-logo-v1.png",
|
|
33
|
+
),
|
|
34
|
+
ThemeFile("assets/brands/arbora-logo-v1.png", "assets/brands/arbora-logo-v1.png"),
|
|
35
|
+
ThemeFile(
|
|
36
|
+
"assets/brands/agent-connector-sdk-logo-v1.png",
|
|
37
|
+
"assets/brands/agent-connector-sdk-logo-v1.png",
|
|
38
|
+
),
|
|
39
|
+
ThemeFile(
|
|
40
|
+
"assets/brands/agent-webui-logo-v1.png",
|
|
41
|
+
"assets/brands/agent-webui-logo-v1.png",
|
|
42
|
+
),
|
|
43
|
+
ThemeFile(
|
|
44
|
+
"assets/brands/geniusbot-logo-v1.png", "assets/brands/geniusbot-logo-v1.png"
|
|
45
|
+
),
|
|
46
|
+
ThemeFile(
|
|
47
|
+
"assets/brands/agent-terminal-ui-logo-v1.png",
|
|
48
|
+
"assets/brands/agent-terminal-ui-logo-v1.png",
|
|
49
|
+
),
|
|
50
|
+
ThemeFile("glossary.md", "glossary.md"),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
RUNTIME_DIAGRAM_URL = (
|
|
55
|
+
"https://raw.githubusercontent.com/Knuckles-Team/epistemic-graph/main/"
|
|
56
|
+
"docs/assets/runtime-architecture.svg"
|
|
57
|
+
)
|
|
58
|
+
# Any reference to the diagram file; the only accepted target is RUNTIME_DIAGRAM_URL.
|
|
59
|
+
RUNTIME_DIAGRAM_REFERENCE = re.compile(r"[^\s\"'()<>]*runtime-architecture\.svg")
|
|
60
|
+
PAGE_SUFFIXES = {".md", ".html", ".yml", ".yaml"}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ThemeSyncError(Exception):
|
|
64
|
+
"""The source, destination, or content-source contract is invalid."""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _safe_relative_path(value: str, label: str) -> Path:
|
|
68
|
+
path = Path(value)
|
|
69
|
+
if (
|
|
70
|
+
path.is_absolute()
|
|
71
|
+
or not path.parts
|
|
72
|
+
or any(part in {".", ".."} for part in path.parts)
|
|
73
|
+
):
|
|
74
|
+
raise ThemeSyncError(f"{label} must be a contained relative path")
|
|
75
|
+
return path
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _contained(root: Path, relative: Path, label: str) -> Path:
|
|
79
|
+
base = root.resolve()
|
|
80
|
+
result = (base / relative).resolve()
|
|
81
|
+
if not result.is_relative_to(base):
|
|
82
|
+
raise ThemeSyncError(f"{label} escapes the repository root")
|
|
83
|
+
return result
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _check_file(destination: Path, expected: bytes, repository: Path) -> str | None:
|
|
87
|
+
"""Describe how ``destination`` diverges from ``expected``, or ``None`` when it matches."""
|
|
88
|
+
try:
|
|
89
|
+
actual = destination.read_bytes()
|
|
90
|
+
except OSError:
|
|
91
|
+
return f"missing generated file: {destination.relative_to(repository)}"
|
|
92
|
+
if actual != expected:
|
|
93
|
+
return f"generated file differs: {destination.relative_to(repository)}"
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _runtime_reference_mismatches(content_root: Path, repository: Path) -> list[str]:
|
|
98
|
+
"""Pages may show the runtime diagram only through the single canonical URL."""
|
|
99
|
+
mismatches: list[str] = []
|
|
100
|
+
if not content_root.is_dir():
|
|
101
|
+
return mismatches
|
|
102
|
+
for page in sorted(content_root.rglob("*")):
|
|
103
|
+
if page.suffix not in PAGE_SUFFIXES or not page.is_file():
|
|
104
|
+
continue
|
|
105
|
+
text = page.read_text(encoding="utf-8", errors="replace")
|
|
106
|
+
if any(
|
|
107
|
+
match.group(0) != RUNTIME_DIAGRAM_URL
|
|
108
|
+
for match in RUNTIME_DIAGRAM_REFERENCE.finditer(text)
|
|
109
|
+
):
|
|
110
|
+
mismatches.append(
|
|
111
|
+
f"runtime diagram must be referenced as {RUNTIME_DIAGRAM_URL}: "
|
|
112
|
+
f"{page.relative_to(repository)}"
|
|
113
|
+
)
|
|
114
|
+
return mismatches
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def sync_theme(
|
|
118
|
+
*,
|
|
119
|
+
source_root: Path,
|
|
120
|
+
repository_root: Path,
|
|
121
|
+
content_source: str,
|
|
122
|
+
mode: Literal["sync", "check"],
|
|
123
|
+
) -> list[str]:
|
|
124
|
+
"""Copy canonical files in ``sync`` mode or return mismatches in ``check`` mode."""
|
|
125
|
+
content_relative = _safe_relative_path(content_source, "content-source")
|
|
126
|
+
repository = repository_root.resolve()
|
|
127
|
+
content_root = _contained(repository, content_relative, "content-source")
|
|
128
|
+
source = (source_root / "templates" / "mkdocs-theme").resolve()
|
|
129
|
+
if not source.is_dir():
|
|
130
|
+
raise ThemeSyncError(f"canonical theme directory does not exist: {source}")
|
|
131
|
+
|
|
132
|
+
mismatches = _sync_files(source, content_root, repository, mode=mode)
|
|
133
|
+
if mode == "check":
|
|
134
|
+
mismatches.extend(_runtime_reference_mismatches(content_root, repository))
|
|
135
|
+
return mismatches
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _sync_files(
|
|
139
|
+
source: Path,
|
|
140
|
+
content_root: Path,
|
|
141
|
+
repository: Path,
|
|
142
|
+
*,
|
|
143
|
+
mode: Literal["sync", "check"],
|
|
144
|
+
) -> list[str]:
|
|
145
|
+
"""Write or compare every theme file and describe each divergence."""
|
|
146
|
+
mismatches: list[str] = []
|
|
147
|
+
for item in THEME_FILES:
|
|
148
|
+
source_file = source / item.source
|
|
149
|
+
if not source_file.is_file():
|
|
150
|
+
raise ThemeSyncError(f"canonical theme file does not exist: {source_file}")
|
|
151
|
+
destination_root = content_root if item.content_relative else repository
|
|
152
|
+
destination = _contained(
|
|
153
|
+
destination_root, Path(item.destination), item.destination
|
|
154
|
+
)
|
|
155
|
+
expected = source_file.read_bytes()
|
|
156
|
+
if mode == "check":
|
|
157
|
+
mismatch = _check_file(destination, expected, repository)
|
|
158
|
+
if mismatch:
|
|
159
|
+
mismatches.append(mismatch)
|
|
160
|
+
continue
|
|
161
|
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
162
|
+
destination.write_bytes(expected)
|
|
163
|
+
return mismatches
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def main(argv: list[str] | None = None) -> int:
|
|
167
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
168
|
+
parser.add_argument("mode", choices=("sync", "check"))
|
|
169
|
+
parser.add_argument(
|
|
170
|
+
"--root", type=Path, default=Path.cwd(), help="consumer repository root"
|
|
171
|
+
)
|
|
172
|
+
parser.add_argument(
|
|
173
|
+
"--content-source",
|
|
174
|
+
default="docs",
|
|
175
|
+
help="consumer MkDocs content directory (normally docs or pages)",
|
|
176
|
+
)
|
|
177
|
+
parser.add_argument(
|
|
178
|
+
"--source-root",
|
|
179
|
+
type=Path,
|
|
180
|
+
default=Path(__file__).resolve().parents[1],
|
|
181
|
+
help="pipelines checkout containing templates/mkdocs-theme",
|
|
182
|
+
)
|
|
183
|
+
args = parser.parse_args(argv)
|
|
184
|
+
try:
|
|
185
|
+
mismatches = sync_theme(
|
|
186
|
+
source_root=args.source_root,
|
|
187
|
+
repository_root=args.root,
|
|
188
|
+
content_source=args.content_source,
|
|
189
|
+
mode=args.mode,
|
|
190
|
+
)
|
|
191
|
+
except (OSError, ThemeSyncError) as exc:
|
|
192
|
+
print(f"shared MkDocs theme: CANNOT RUN: {exc}", file=sys.stderr)
|
|
193
|
+
return 2
|
|
194
|
+
if mismatches:
|
|
195
|
+
print("shared MkDocs theme: generated files are out of sync:", file=sys.stderr)
|
|
196
|
+
for mismatch in mismatches:
|
|
197
|
+
print(f" - {mismatch}", file=sys.stderr)
|
|
198
|
+
return 1
|
|
199
|
+
print(f"shared MkDocs theme: {args.mode} complete")
|
|
200
|
+
return 0
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
if __name__ == "__main__":
|
|
204
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Shared MkDocs theme
|
|
2
|
+
|
|
3
|
+
This folder is the canonical source for the five ecosystem documentation sites. `scripts/sync_mkdocs_theme.py` copies its generated files into a consuming repository and checks that committed copies are byte-identical.
|
|
4
|
+
|
|
5
|
+
## Generated files
|
|
6
|
+
|
|
7
|
+
| Source | Consumer path |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `extra.css` | `<content-source>/stylesheets/extra.css` |
|
|
10
|
+
| `overrides/main.html` | not synced: `custom_dir` serves it from the theme checkout (`.pipeline-theme/templates/mkdocs-theme/overrides`) |
|
|
11
|
+
| `assets/*` | `<content-source>/assets/*` |
|
|
12
|
+
| `glossary.md` | `<content-source>/glossary.md` |
|
|
13
|
+
| `base.mkdocs.yml` | inherited directly from the pinned pipelines checkout |
|
|
14
|
+
|
|
15
|
+
`<content-source>` is the explicitly declared `docs` or `pages` directory. Run `python scripts/sync_mkdocs_theme.py sync --root REPOSITORY --content-source docs` to update files, and the same command with `check` to check exact equality without writing. The Pages workflow checks the committed assets against its immutable workflow checkout before building.
|
|
16
|
+
|
|
17
|
+
## Runtime architecture diagram
|
|
18
|
+
|
|
19
|
+
The runtime architecture diagram is not a theme asset and is never copied into a consumer. There is exactly one file, `docs/assets/runtime-architecture.svg` in Knuckles-Team/epistemic-graph, and every page that shows it references the URL `https://raw.githubusercontent.com/Knuckles-Team/epistemic-graph/main/docs/assets/runtime-architecture.svg`. The `check` mode fails when a page under the content source references `runtime-architecture.svg` by any other path.
|
|
20
|
+
|
|
21
|
+
## MkDocs configuration
|
|
22
|
+
|
|
23
|
+
The repository's `mkdocs.yml` inherits `templates/mkdocs-theme/base.mkdocs.yml` and supplies `extra.ecosystem.current` with its own slug (`agent-webui`, `arbora`, `agent-utilities`, `epistemic-graph`, or `agent-connector-sdk`). It continues to own its site name, URL, content directory, and navigation. For local builds, check out the exact pinned `pipelines` revision into `.pipeline-theme`, run the `sync` command above, then run `mkdocs build --strict`.
|
|
24
|
+
|
|
25
|
+
Use `.site-hero`, `.site-card-grid` / `.site-card`, `.site-ownership__grid` / `.site-ownership__item`, and the ordered `.site-flow` components for landing-page structure. Prefer semantic HTML and retain visible keyboard focus. The common theme uses native `<details>` for the site switcher and does not require custom JavaScript.
|
|
26
|
+
|
|
27
|
+
The root `README.md` remains the short entry point. It keeps its exact ordered headings: Overview, Key capabilities, Documentation, Architecture, Quick start, Contributing, License. Deep reference material belongs in Pages. Public home pages describe the current bundled ecosystem in present tense. They contain no planning, migration, worktree, or future-release status.
|
|
Binary file
|
webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-terminal-ui-logo-v1.png
ADDED
|
Binary file
|
webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-utilities-logo-v1.png
ADDED
|
Binary file
|
webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/agent-webui-logo-v1.png
ADDED
|
Binary file
|
|
Binary file
|
webarchiver-1.2.0/.pipeline-theme/templates/mkdocs-theme/assets/brands/epistemic-graph-logo-v1.png
ADDED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
|
2
|
+
<rect width="64" height="64" rx="14" fill="#f1f5fb"/>
|
|
3
|
+
<g fill="none" stroke="#2a5ca8" stroke-linecap="round" stroke-width="5">
|
|
4
|
+
<path d="M16 18 32 10l16 9v26l-16 9-16-9z"/>
|
|
5
|
+
<path d="m16 18 16 9 16-8M32 27v27M16 45l16-18 16 18"/>
|
|
6
|
+
</g>
|
|
7
|
+
<g fill="#e6a23a" stroke="#f1f5fb" stroke-width="2">
|
|
8
|
+
<circle cx="16" cy="18" r="6"/><circle cx="32" cy="10" r="6"/>
|
|
9
|
+
<circle cx="48" cy="19" r="6"/><circle cx="16" cy="45" r="6"/>
|
|
10
|
+
<circle cx="32" cy="54" r="6"/><circle cx="48" cy="45" r="6"/>
|
|
11
|
+
<circle cx="32" cy="27" r="6"/>
|
|
12
|
+
</g>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title">
|
|
2
|
+
<title id="title">Knuckles-Team graph mark</title>
|
|
3
|
+
<g fill="none" stroke="#2a5ca8" stroke-linecap="round" stroke-width="5">
|
|
4
|
+
<path d="M16 18 32 10l16 9v26l-16 9-16-9z"/>
|
|
5
|
+
<path d="m16 18 16 9 16-8M32 27v27M16 45l16-18 16 18"/>
|
|
6
|
+
</g>
|
|
7
|
+
<g fill="#e6a23a" stroke="#fff" stroke-width="2">
|
|
8
|
+
<circle cx="16" cy="18" r="6"/><circle cx="32" cy="10" r="6"/>
|
|
9
|
+
<circle cx="48" cy="19" r="6"/><circle cx="16" cy="45" r="6"/>
|
|
10
|
+
<circle cx="32" cy="54" r="6"/><circle cx="48" cy="45" r="6"/>
|
|
11
|
+
<circle cx="32" cy="27" r="6"/>
|
|
12
|
+
</g>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Shared GitHub Pages theme for the Knuckles-Team agent ecosystem.
|
|
2
|
+
#
|
|
3
|
+
# A consuming repository's own `mkdocs.yml` inherits this file via mkdocs's
|
|
4
|
+
# native `INHERIT:` key (a recursive dict merge, lists replaced only where the
|
|
5
|
+
# child repository re-declares them -- see `mkdocs.utils.yaml.yaml_load`).
|
|
6
|
+
# The `pages_pipeline.yml` reusable workflow wires the `INHERIT:` line in for
|
|
7
|
+
# every caller that sets `shared_theme_enabled: true`. The repository's own
|
|
8
|
+
# `mkdocs.yml` remains the content manifest; this file supplies the common
|
|
9
|
+
# presentation, while `scripts/sync_mkdocs_theme.py` materializes its generated
|
|
10
|
+
# assets into the caller's docs tree.
|
|
11
|
+
|
|
12
|
+
theme:
|
|
13
|
+
name: material
|
|
14
|
+
custom_dir: .pipeline-theme/templates/mkdocs-theme/overrides
|
|
15
|
+
logo: assets/graph-mark.svg
|
|
16
|
+
favicon: assets/favicon.svg
|
|
17
|
+
icon:
|
|
18
|
+
repo: fontawesome/brands/github
|
|
19
|
+
features:
|
|
20
|
+
- navigation.tabs
|
|
21
|
+
- navigation.tabs.sticky
|
|
22
|
+
- navigation.sections
|
|
23
|
+
- navigation.top
|
|
24
|
+
- navigation.tracking
|
|
25
|
+
- navigation.instant
|
|
26
|
+
- navigation.instant.progress
|
|
27
|
+
- navigation.footer
|
|
28
|
+
- toc.follow
|
|
29
|
+
- search.suggest
|
|
30
|
+
- search.highlight
|
|
31
|
+
- search.share
|
|
32
|
+
- content.code.copy
|
|
33
|
+
- content.code.annotate
|
|
34
|
+
- content.tabs.link
|
|
35
|
+
palette:
|
|
36
|
+
- media: "(prefers-color-scheme: light)"
|
|
37
|
+
scheme: default
|
|
38
|
+
primary: indigo
|
|
39
|
+
accent: indigo
|
|
40
|
+
toggle:
|
|
41
|
+
icon: material/weather-sunny
|
|
42
|
+
name: Switch to dark mode
|
|
43
|
+
- media: "(prefers-color-scheme: dark)"
|
|
44
|
+
scheme: slate
|
|
45
|
+
primary: indigo
|
|
46
|
+
accent: indigo
|
|
47
|
+
toggle:
|
|
48
|
+
icon: material/weather-night
|
|
49
|
+
name: Switch to light mode
|
|
50
|
+
|
|
51
|
+
extra_css:
|
|
52
|
+
- stylesheets/extra.css
|
|
53
|
+
|
|
54
|
+
extra:
|
|
55
|
+
spec_delivery: !ENV [SPEC_DELIVERY_ENABLED, false]
|
|
56
|
+
ecosystem:
|
|
57
|
+
current: ""
|
|
58
|
+
sites:
|
|
59
|
+
- slug: agent-webui
|
|
60
|
+
name: Agent Web UI
|
|
61
|
+
role: operator experience
|
|
62
|
+
url: https://knuckles-team.github.io/agent-webui/
|
|
63
|
+
repository: https://github.com/Knuckles-Team/agent-webui
|
|
64
|
+
- slug: arbora
|
|
65
|
+
name: Arbora
|
|
66
|
+
role: public runtime gateway
|
|
67
|
+
url: https://knuckles-team.github.io/arbora/
|
|
68
|
+
repository: https://github.com/Knuckles-Team/arbora
|
|
69
|
+
- slug: agent-utilities
|
|
70
|
+
name: Agent Utilities
|
|
71
|
+
role: agent control plane
|
|
72
|
+
url: https://knuckles-team.github.io/agent-utilities/
|
|
73
|
+
repository: https://github.com/Knuckles-Team/agent-utilities
|
|
74
|
+
- slug: epistemic-graph
|
|
75
|
+
name: Epistemic Graph
|
|
76
|
+
role: durable multimodal knowledge and reasoning engine
|
|
77
|
+
url: https://knuckles-team.github.io/epistemic-graph/
|
|
78
|
+
repository: https://github.com/Knuckles-Team/epistemic-graph
|
|
79
|
+
- slug: agent-connector-sdk
|
|
80
|
+
name: Agent Connector SDK
|
|
81
|
+
role: governed source integration boundary
|
|
82
|
+
url: https://knuckles-team.github.io/agent-connector-sdk/
|
|
83
|
+
repository: https://github.com/Knuckles-Team/agent-connector-sdk
|
|
84
|
+
- slug: pipelines
|
|
85
|
+
name: Skill Graph
|
|
86
|
+
role: cross-repo concept, component and man-page corpus
|
|
87
|
+
url: https://knuckles-team.github.io/pipelines/
|
|
88
|
+
repository: https://github.com/Knuckles-Team/pipelines
|
|
89
|
+
spec_delivery: false
|
|
90
|
+
|
|
91
|
+
markdown_extensions:
|
|
92
|
+
- admonition
|
|
93
|
+
- attr_list
|
|
94
|
+
- md_in_html
|
|
95
|
+
- tables
|
|
96
|
+
- toc:
|
|
97
|
+
permalink: true
|
|
98
|
+
- pymdownx.details
|
|
99
|
+
- pymdownx.superfences
|
|
100
|
+
- pymdownx.tabbed:
|
|
101
|
+
alternate_style: true
|
|
102
|
+
- pymdownx.highlight:
|
|
103
|
+
anchor_linenums: true
|
|
104
|
+
- pymdownx.inlinehilite
|
|
105
|
+
- pymdownx.snippets
|