grok-gadgets-linux-sdk 0.1.0a5__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.
- grok_gadgets_linux_sdk-0.1.0a5/.github/CODEOWNERS +2 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/ISSUE_TEMPLATE/bug.yml +43 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/ISSUE_TEMPLATE/compatibility.yml +18 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/ISSUE_TEMPLATE/config.yml +8 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/ISSUE_TEMPLATE/documentation.yml +24 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/ISSUE_TEMPLATE/feature.yml +24 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/ISSUE_TEMPLATE/hardware.yml +31 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/dependabot.yml +21 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/pull_request_template.md +21 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/workflows/checks.yml +80 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/workflows/pr-target.yml +25 -0
- grok_gadgets_linux_sdk-0.1.0a5/.github/workflows/release.yml +102 -0
- grok_gadgets_linux_sdk-0.1.0a5/.gitignore +43 -0
- grok_gadgets_linux_sdk-0.1.0a5/AGENTS.md +17 -0
- grok_gadgets_linux_sdk-0.1.0a5/CHANGELOG.md +68 -0
- grok_gadgets_linux_sdk-0.1.0a5/CODE_OF_CONDUCT.md +15 -0
- grok_gadgets_linux_sdk-0.1.0a5/CONTRIBUTING.md +91 -0
- grok_gadgets_linux_sdk-0.1.0a5/LICENSE +202 -0
- grok_gadgets_linux_sdk-0.1.0a5/NOTICE +4 -0
- grok_gadgets_linux_sdk-0.1.0a5/PKG-INFO +174 -0
- grok_gadgets_linux_sdk-0.1.0a5/README.md +146 -0
- grok_gadgets_linux_sdk-0.1.0a5/SECURITY.md +44 -0
- grok_gadgets_linux_sdk-0.1.0a5/SUPPORT.md +18 -0
- grok_gadgets_linux_sdk-0.1.0a5/docs/development.md +201 -0
- grok_gadgets_linux_sdk-0.1.0a5/docs/operation.md +182 -0
- grok_gadgets_linux_sdk-0.1.0a5/docs/release.md +41 -0
- grok_gadgets_linux_sdk-0.1.0a5/docs/verification/hardening.md +57 -0
- grok_gadgets_linux_sdk-0.1.0a5/docs/verification/launch-docs.md +57 -0
- grok_gadgets_linux_sdk-0.1.0a5/docs/verification.md +42 -0
- grok_gadgets_linux_sdk-0.1.0a5/examples/grok-gadget.service +21 -0
- grok_gadgets_linux_sdk-0.1.0a5/planning/artifacts.json +20 -0
- grok_gadgets_linux_sdk-0.1.0a5/planning/issues.json +567 -0
- grok_gadgets_linux_sdk-0.1.0a5/planning/linux-evidence.json +61 -0
- grok_gadgets_linux_sdk-0.1.0a5/planning/publication.json +7 -0
- grok_gadgets_linux_sdk-0.1.0a5/pyproject.toml +51 -0
- grok_gadgets_linux_sdk-0.1.0a5/scripts/check_onboarding.py +112 -0
- grok_gadgets_linux_sdk-0.1.0a5/scripts/check_readme_quickstart.py +168 -0
- grok_gadgets_linux_sdk-0.1.0a5/scripts/check_ste.py +59 -0
- grok_gadgets_linux_sdk-0.1.0a5/scripts/linux_acceptance.py +43 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/__init__.py +6 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/agent.py +203 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/cli.py +293 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/contracts.py +89 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/dev.py +175 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/device.py +276 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/examples.py +20 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/gadget.py +120 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/protocol/0.1.0/README.md +119 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/protocol/0.1.0/device-request.schema.json +260 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/protocol/0.1.0/device-response.schema.json +81 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/protocol/0.1.0/fixtures/device-transcript.json +70 -0
- grok_gadgets_linux_sdk-0.1.0a5/src/grok_gadgets_linux/protocol/source.json +12 -0
- grok_gadgets_linux_sdk-0.1.0a5/tests/fake_gateway.py +76 -0
- grok_gadgets_linux_sdk-0.1.0a5/tests/test_agent.py +463 -0
- grok_gadgets_linux_sdk-0.1.0a5/tests/test_cli.py +387 -0
- grok_gadgets_linux_sdk-0.1.0a5/tests/test_dev.py +120 -0
- grok_gadgets_linux_sdk-0.1.0a5/tests/test_device.py +320 -0
- grok_gadgets_linux_sdk-0.1.0a5/tests/test_gadget.py +200 -0
- grok_gadgets_linux_sdk-0.1.0a5/uv.lock +802 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: A reproducible failure, with redacted evidence
|
|
3
|
+
labels:
|
|
4
|
+
- bug
|
|
5
|
+
body:
|
|
6
|
+
- type: input
|
|
7
|
+
id: version
|
|
8
|
+
attributes:
|
|
9
|
+
label: Version or full source commit
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: input
|
|
13
|
+
id: host
|
|
14
|
+
attributes:
|
|
15
|
+
label: Component, OS and runtime
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: dropdown
|
|
19
|
+
id: evidence
|
|
20
|
+
attributes:
|
|
21
|
+
label: Test environment
|
|
22
|
+
options:
|
|
23
|
+
- Browser simulation
|
|
24
|
+
- Local MCP / software device
|
|
25
|
+
- Compiled firmware only
|
|
26
|
+
- Physical hardware
|
|
27
|
+
- Actual Grok client
|
|
28
|
+
- Home Assistant installation
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
- type: textarea
|
|
32
|
+
id: reproduce
|
|
33
|
+
attributes:
|
|
34
|
+
label: Steps, expected behavior and observed result
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
- type: textarea
|
|
38
|
+
id: logs
|
|
39
|
+
attributes:
|
|
40
|
+
label: Redacted logs or evidence
|
|
41
|
+
description: Never include tokens, account details, household names or private endpoints.
|
|
42
|
+
validations:
|
|
43
|
+
required: false
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Compatibility report
|
|
2
|
+
description: Report a reproducible SDK compatibility issue without private home data
|
|
3
|
+
title: "[compatibility] "
|
|
4
|
+
labels: [bug, linux]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: environment
|
|
8
|
+
attributes:
|
|
9
|
+
label: Versions and evidence level
|
|
10
|
+
description: SDK/gateway versions, OS/kernel, transport, simulation or real peripheral; omit tokens and household names.
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: reproduction
|
|
15
|
+
attributes:
|
|
16
|
+
label: Reproduction and expected behavior
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: true
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Questions and build discussion
|
|
4
|
+
url: https://www.reddit.com/r/GrokGadgets/
|
|
5
|
+
about: Questions do not require a full bug form.
|
|
6
|
+
- name: Private security or conduct report
|
|
7
|
+
url: mailto:adidshaft@kyokasuigetsu.xyz
|
|
8
|
+
about: Use the private contact. GitHub private reporting activation is pending.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Documentation improvement
|
|
2
|
+
description: Help make a setup or explanation clearer
|
|
3
|
+
labels:
|
|
4
|
+
- docs
|
|
5
|
+
body:
|
|
6
|
+
- type: input
|
|
7
|
+
id: page
|
|
8
|
+
attributes:
|
|
9
|
+
label: Page or source file
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: confusion
|
|
14
|
+
attributes:
|
|
15
|
+
label: Attempted step and what was confusing
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: suggestion
|
|
20
|
+
attributes:
|
|
21
|
+
label: Suggested improvement
|
|
22
|
+
description: An exact proposal is helpful but optional.
|
|
23
|
+
validations:
|
|
24
|
+
required: false
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Feature proposal
|
|
2
|
+
description: A bounded use case and compatibility impact
|
|
3
|
+
labels:
|
|
4
|
+
- feature
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: usecase
|
|
8
|
+
attributes:
|
|
9
|
+
label: Use case and affected component
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: behavior
|
|
14
|
+
attributes:
|
|
15
|
+
label: Proposed behavior and scope
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: compatibility
|
|
20
|
+
attributes:
|
|
21
|
+
label: Compatibility and evidence needed
|
|
22
|
+
description: Discuss protocol/API changes before implementation.
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Hardware verification report
|
|
2
|
+
description: Actual observations from an identified device
|
|
3
|
+
labels:
|
|
4
|
+
- needs hardware
|
|
5
|
+
body:
|
|
6
|
+
- type: input
|
|
7
|
+
id: model
|
|
8
|
+
attributes:
|
|
9
|
+
label: Exact model and firmware source/hash
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: input
|
|
13
|
+
id: host
|
|
14
|
+
attributes:
|
|
15
|
+
label: Host, runtime and cable/transport
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: steps
|
|
20
|
+
attributes:
|
|
21
|
+
label: Steps and expected/observed results
|
|
22
|
+
description: Separate firmware acknowledgement from physical observation; include disconnect/recovery.
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: evidence
|
|
27
|
+
attributes:
|
|
28
|
+
label: Safe redacted evidence
|
|
29
|
+
description: Do not include private device identifiers or account details.
|
|
30
|
+
validations:
|
|
31
|
+
required: false
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Weekly version updates, grouped per ecosystem, opened as PRs into dev.
|
|
2
|
+
# Security-update PRs ignore target-branch and open against main; retarget them
|
|
3
|
+
# to dev before merging. Triage rules: https://github.com/adidshaft/grok-gadgets/blob/dev/SECURITY.md
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
- package-ecosystem: uv
|
|
7
|
+
directory: /
|
|
8
|
+
target-branch: dev
|
|
9
|
+
schedule:
|
|
10
|
+
interval: weekly
|
|
11
|
+
groups:
|
|
12
|
+
python:
|
|
13
|
+
patterns: ["*"]
|
|
14
|
+
- package-ecosystem: github-actions
|
|
15
|
+
directory: /
|
|
16
|
+
target-branch: dev
|
|
17
|
+
schedule:
|
|
18
|
+
interval: weekly
|
|
19
|
+
groups:
|
|
20
|
+
actions:
|
|
21
|
+
patterns: ["*"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!-- main is the default branch for users, builders and the website. Development and testing integrate on dev. Ordinary contribution PRs target dev; main accepts release and hotfix PRs only. Verify the base branch before submitting. -->
|
|
2
|
+
|
|
3
|
+
## Problem and resulting behavior
|
|
4
|
+
|
|
5
|
+
<!-- Concrete before/after behavior and scope. -->
|
|
6
|
+
|
|
7
|
+
## Issue and changes
|
|
8
|
+
|
|
9
|
+
<!-- Link the issue or stable local ID. Small typo fixes need no new issue. -->
|
|
10
|
+
|
|
11
|
+
## Checks and evidence
|
|
12
|
+
|
|
13
|
+
<!-- Commands and actual results; distinguish simulation, compilation, native Grok and physical observation. -->
|
|
14
|
+
|
|
15
|
+
## Documentation, compatibility and remaining limitations
|
|
16
|
+
|
|
17
|
+
<!-- Pin/schema changes, recovery and unresolved gates. Redact private information. -->
|
|
18
|
+
|
|
19
|
+
## Checklist
|
|
20
|
+
|
|
21
|
+
- [ ] The base is `dev` for an ordinary contribution, or `main` for a release or hotfix.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: Checks
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
pull_request:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: '41 5 * * *'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
concurrency:
|
|
11
|
+
group: checks-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
jobs:
|
|
14
|
+
linux-sdk-checks-matrix:
|
|
15
|
+
name: linux-sdk-checks (${{ matrix.python-version }})
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
timeout-minutes: 20
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
python-version: ['3.11', '3.12', '3.13', '3.14']
|
|
22
|
+
defaults:
|
|
23
|
+
run:
|
|
24
|
+
working-directory: grok-gadgets-linux-sdk
|
|
25
|
+
env:
|
|
26
|
+
# The seven gateway integration tests run against gateway main, never skip.
|
|
27
|
+
GROK_GATEWAY_SOURCE: ${{ github.workspace }}/grok-gadgets-gateway/src
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
30
|
+
with:
|
|
31
|
+
path: grok-gadgets-linux-sdk
|
|
32
|
+
persist-credentials: false
|
|
33
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
34
|
+
with:
|
|
35
|
+
repository: adidshaft/grok-gadgets-gateway
|
|
36
|
+
ref: main
|
|
37
|
+
path: grok-gadgets-gateway
|
|
38
|
+
persist-credentials: false
|
|
39
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
40
|
+
with:
|
|
41
|
+
version: '0.12.3'
|
|
42
|
+
- run: uv sync --frozen --extra gateway --python ${{ matrix.python-version }}
|
|
43
|
+
- run: uv run ruff check .
|
|
44
|
+
- run: uv run ruff format --check .
|
|
45
|
+
- name: Plain language (ASD-STE100 sentence limit)
|
|
46
|
+
run: python3 scripts/check_ste.py README.md CONTRIBUTING.md SUPPORT.md
|
|
47
|
+
- name: Unit and gateway-main integration tests
|
|
48
|
+
run: |
|
|
49
|
+
git -C ../grok-gadgets-gateway log -1 --format='Gateway main %H'
|
|
50
|
+
uv run python -m unittest discover -s tests -v 2>&1 | tee "$RUNNER_TEMP/tests.log"
|
|
51
|
+
if grep -q "skipped 'Set GROK_GATEWAY_SOURCE\|skipped 'Install the \[gateway\]" "$RUNNER_TEMP/tests.log"; then
|
|
52
|
+
echo "Gateway integration tests skipped" >&2; exit 1
|
|
53
|
+
fi
|
|
54
|
+
timeout-minutes: 5
|
|
55
|
+
- run: uv build
|
|
56
|
+
- name: Package metadata renders on PyPI (nothing is uploaded)
|
|
57
|
+
run: uvx --from 'twine==7.0.0' twine check --strict dist/*
|
|
58
|
+
readme-quickstart:
|
|
59
|
+
# The README quick start in a fresh clone (install, my_gadget.py, dev), then a real MCP call.
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
timeout-minutes: 15
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
64
|
+
with:
|
|
65
|
+
persist-credentials: false
|
|
66
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
67
|
+
with:
|
|
68
|
+
version: '0.12.3'
|
|
69
|
+
- run: python3 scripts/check_readme_quickstart.py
|
|
70
|
+
linux-sdk-checks:
|
|
71
|
+
name: linux-sdk-checks
|
|
72
|
+
if: always()
|
|
73
|
+
needs: [linux-sdk-checks-matrix, readme-quickstart]
|
|
74
|
+
runs-on: ubuntu-latest
|
|
75
|
+
steps:
|
|
76
|
+
- name: Require every Python version and the README quick start
|
|
77
|
+
env:
|
|
78
|
+
MATRIX_RESULT: ${{ needs.linux-sdk-checks-matrix.result }}
|
|
79
|
+
QUICKSTART_RESULT: ${{ needs.readme-quickstart.result }}
|
|
80
|
+
run: test "$MATRIX_RESULT" = success && test "$QUICKSTART_RESULT" = success
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: PR target
|
|
2
|
+
# main holds releases only. A PR into main must come from this repository's dev branch
|
|
3
|
+
# (a release) or a hotfix/* branch. Everything else belongs in dev.
|
|
4
|
+
on:
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [main]
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
jobs:
|
|
10
|
+
pr-target:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 5
|
|
13
|
+
steps:
|
|
14
|
+
- name: Release or hotfix branches only
|
|
15
|
+
env:
|
|
16
|
+
HEAD_REF: ${{ github.head_ref }}
|
|
17
|
+
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
|
|
18
|
+
run: |
|
|
19
|
+
if [ "$HEAD_REPO" = "$GITHUB_REPOSITORY" ]; then
|
|
20
|
+
case "$HEAD_REF" in
|
|
21
|
+
dev|hotfix/*) echo "OK: $HEAD_REF may target main."; exit 0 ;;
|
|
22
|
+
esac
|
|
23
|
+
fi
|
|
24
|
+
echo "::error::Pull requests into main are for releases (from dev) and hotfixes (hotfix/* branches) only. Please change the base branch to dev." >&2
|
|
25
|
+
exit 1
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: release packages
|
|
2
|
+
# Started by hand for one tag; nothing runs on push. It builds once, writes SHA256SUMS with
|
|
3
|
+
# plain file names, checks it in a fresh folder, and attaches the files to the tag's GitHub
|
|
4
|
+
# release. With publish_pypi it also uploads to PyPI through trusted publishing (OIDC): no
|
|
5
|
+
# token is stored. The `pypi` environment can require the owner's approval.
|
|
6
|
+
on:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
tag:
|
|
10
|
+
description: Existing release tag, for example v0.1.0-alpha.7
|
|
11
|
+
required: true
|
|
12
|
+
publish_pypi:
|
|
13
|
+
description: Also upload to PyPI
|
|
14
|
+
type: boolean
|
|
15
|
+
default: false
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
concurrency:
|
|
19
|
+
group: release-${{ inputs.tag }}
|
|
20
|
+
cancel-in-progress: false
|
|
21
|
+
jobs:
|
|
22
|
+
build:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
timeout-minutes: 15
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
27
|
+
with:
|
|
28
|
+
ref: refs/tags/${{ inputs.tag }}
|
|
29
|
+
persist-credentials: false
|
|
30
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
31
|
+
with:
|
|
32
|
+
version: '0.12.3'
|
|
33
|
+
- name: Tag matches the package version
|
|
34
|
+
env:
|
|
35
|
+
TAG: ${{ inputs.tag }}
|
|
36
|
+
run: |
|
|
37
|
+
python3 - <<'PY'
|
|
38
|
+
import os, re, tomllib
|
|
39
|
+
version = tomllib.load(open("pyproject.toml", "rb"))["project"]["version"]
|
|
40
|
+
tag = os.environ["TAG"]
|
|
41
|
+
match = re.fullmatch(r"v(\d+\.\d+\.\d+)(?:-(alpha|beta|rc)\.(\d+))?", tag)
|
|
42
|
+
short = {"alpha": "a", "beta": "b", "rc": "rc"}
|
|
43
|
+
expected = match and match[1] + (short[match[2]] + match[3] if match[2] else "")
|
|
44
|
+
if expected != version:
|
|
45
|
+
raise SystemExit(f"Tag {tag} does not match version {version}")
|
|
46
|
+
PY
|
|
47
|
+
- run: uv build --out-dir dist
|
|
48
|
+
- name: Package metadata renders on PyPI
|
|
49
|
+
run: uvx --from 'twine==7.0.0' twine check --strict dist/*
|
|
50
|
+
- name: Write SHA256SUMS with plain file names
|
|
51
|
+
run: |
|
|
52
|
+
mkdir sums
|
|
53
|
+
(cd dist && sha256sum -- *.whl *.tar.gz) > sums/SHA256SUMS
|
|
54
|
+
cat sums/SHA256SUMS
|
|
55
|
+
- name: Check SHA256SUMS in a fresh folder, as a downloader would
|
|
56
|
+
run: |
|
|
57
|
+
mkdir fresh
|
|
58
|
+
cp dist/* sums/SHA256SUMS fresh/
|
|
59
|
+
cd fresh && sha256sum -c SHA256SUMS
|
|
60
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
61
|
+
with:
|
|
62
|
+
name: dist
|
|
63
|
+
path: dist/
|
|
64
|
+
if-no-files-found: error
|
|
65
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
66
|
+
with:
|
|
67
|
+
name: sums
|
|
68
|
+
path: sums/
|
|
69
|
+
if-no-files-found: error
|
|
70
|
+
github-release:
|
|
71
|
+
needs: build
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
timeout-minutes: 10
|
|
74
|
+
permissions:
|
|
75
|
+
contents: write
|
|
76
|
+
steps:
|
|
77
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
78
|
+
with:
|
|
79
|
+
path: assets
|
|
80
|
+
merge-multiple: true
|
|
81
|
+
- name: Attach to the existing release (never replaces an asset)
|
|
82
|
+
env:
|
|
83
|
+
GH_TOKEN: ${{ github.token }}
|
|
84
|
+
GH_REPO: ${{ github.repository }}
|
|
85
|
+
TAG: ${{ inputs.tag }}
|
|
86
|
+
run: gh release upload "$TAG" assets/*
|
|
87
|
+
pypi:
|
|
88
|
+
if: inputs.publish_pypi
|
|
89
|
+
needs: [build, github-release]
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
timeout-minutes: 10
|
|
92
|
+
environment:
|
|
93
|
+
name: pypi
|
|
94
|
+
url: https://pypi.org/project/grok-gadgets-linux-sdk/
|
|
95
|
+
permissions:
|
|
96
|
+
id-token: write
|
|
97
|
+
steps:
|
|
98
|
+
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
99
|
+
with:
|
|
100
|
+
name: dist
|
|
101
|
+
path: dist
|
|
102
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Local configuration and credentials. Commit only reviewed, non-secret examples.
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
!.env.example
|
|
5
|
+
!.env.sample
|
|
6
|
+
!.env.template
|
|
7
|
+
credentials*.json
|
|
8
|
+
!credentials.example.json
|
|
9
|
+
secrets*.json
|
|
10
|
+
secrets*.yaml
|
|
11
|
+
secrets*.yml
|
|
12
|
+
secrets.h
|
|
13
|
+
.secrets/
|
|
14
|
+
*.pem
|
|
15
|
+
*.key
|
|
16
|
+
*.p12
|
|
17
|
+
*.pfx
|
|
18
|
+
my-light.json
|
|
19
|
+
my_gadget.py
|
|
20
|
+
fresh-run.jsonl
|
|
21
|
+
|
|
22
|
+
# Environments, caches and generated output.
|
|
23
|
+
.venv/
|
|
24
|
+
venv/
|
|
25
|
+
__pycache__/
|
|
26
|
+
*.py[cod]
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
.ruff_cache/
|
|
29
|
+
.mypy_cache/
|
|
30
|
+
.coverage*
|
|
31
|
+
htmlcov/
|
|
32
|
+
*.egg-info/
|
|
33
|
+
node_modules/
|
|
34
|
+
dist/
|
|
35
|
+
build/
|
|
36
|
+
.pio/
|
|
37
|
+
/artifacts/
|
|
38
|
+
/reports/
|
|
39
|
+
*.log
|
|
40
|
+
|
|
41
|
+
# Operating-system files.
|
|
42
|
+
.DS_Store
|
|
43
|
+
Thumbs.db
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Repository instructions
|
|
2
|
+
|
|
3
|
+
Own reusable Linux library, agent and examples here. Consume the pinned canonical protocol from the gateway repository's protocol/0.1.0 and communicate breaking changes before adopting them. Prepared upstream: https://github.com/adidshaft/grok-gadgets-gateway. No conflicting schema definitions. Keep host/runtime evidence explicit; macOS does not verify Linux. Use subagents when useful; never Brave/Safari/Passwords. No push/publication/deployment/spending/live devices without authorization.
|
|
4
|
+
|
|
5
|
+
Use main and short feature branches with small tested commits referencing planning/issues.json. Maintain issues and respond when remote publication is authorized. Checks: uv sync --frozen; uv run ruff check .; uv run ruff format --check .; uv run python -m unittest discover -s tests -v; uv build. Never commit credentials or imply execution proves physical effects.
|
|
6
|
+
|
|
7
|
+
Use bounded subagents with explicit file ownership when helpful. Research tasks use the
|
|
8
|
+
strongest available reasoning and cite primary sources. Report any gap before substituting.
|
|
9
|
+
|
|
10
|
+
**Grok Bot only.** The product, its docs, website, examples, tests, commits and branch names
|
|
11
|
+
describe Grok Bot and SpaceXSI technology as the only assistant platform. Do not name,
|
|
12
|
+
recommend or credit other AI assistants, models, chat products, coding agents or editors
|
|
13
|
+
anywhere in the repository. Development tooling stays out of the record.
|
|
14
|
+
|
|
15
|
+
## Ignore rules and publication privacy
|
|
16
|
+
|
|
17
|
+
Keep `.gitignore` current whenever a new tool produces caches, build output, local device configurations, execution logs or credentials. Preserve reviewed sample configuration files and the hub's verified public simulator download. Check new patterns with `git check-ignore`, then review the staged file list before committing. Ignore rules do not remove tracked files or past history; never merge the private pre-publication history back into a public branch. Use the sanitized public checkout and a public or GitHub noreply commit email.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.1.0-alpha.5 — 12 October 2026
|
|
6
|
+
|
|
7
|
+
- `grok-linux-agent --version` prints the SDK version and exits without connecting ([#16](https://github.com/adidshaft/grok-gadgets-linux-sdk/issues/16)).
|
|
8
|
+
- The `gateway` extra and lockfile pin gateway v0.1.0-alpha.7, so the extra names a version that the gateway's own release workflow can publish to PyPI.
|
|
9
|
+
- A hand-started **release packages** workflow builds a tag, writes `SHA256SUMS` with plain file names, checks it in a fresh folder and attaches the files to the release. PyPI upload is a separate opt-in through trusted publishing; no token is stored ([#61](https://github.com/adidshaft/grok-gadgets-linux-sdk/issues/61), hub [#151](https://github.com/adidshaft/grok-gadgets/issues/151)). The package is not on PyPI yet.
|
|
10
|
+
- README adds pip install from the release wheel. Homepage is https://grokgadgets.org/. Docs match the 12 October evidence.
|
|
11
|
+
|
|
12
|
+
## 0.1.0-alpha.4 — 8 October 2026
|
|
13
|
+
|
|
14
|
+
- Pin the gateway extra and lockfile to gateway v0.1.0-alpha.4, which uses `mcp` 2.3.0. The README quick-start check uses the `mcp` 2.x HTTP client.
|
|
15
|
+
- Development tools: `ruff` 0.16.10 and `hatchling` 1.32.4. Code follows the new `ruff` default rules without behavior changes. CI checks packages with `twine` 7.0.0, which reads the Metadata-Version 2.5 that `hatchling` 1.32 writes.
|
|
16
|
+
|
|
17
|
+
## 0.1.0-alpha.3 — 8 October 2026
|
|
18
|
+
|
|
19
|
+
- Security: pin the gateway extra and lockfile to gateway v0.1.0-alpha.3. This moves `mcp` from 1.26.0 to 1.28.1 and closes its high-severity Dependabot alerts.
|
|
20
|
+
- Dependabot opens weekly grouped update PRs into `dev`.
|
|
21
|
+
- CONTRIBUTING starts fork branches from `upstream/dev`. CI also runs the plain-language check on CONTRIBUTING and SUPPORT.
|
|
22
|
+
|
|
23
|
+
## 0.1.0-alpha.2 — 7 October 2026
|
|
24
|
+
|
|
25
|
+
- Pin the gateway extra and lockfile to gateway v0.1.0-alpha.2.
|
|
26
|
+
- Add a runnable Grok Bot rehearsal step to the README quick start.
|
|
27
|
+
|
|
28
|
+
## 0.1.0a1 — 6 October 2026
|
|
29
|
+
|
|
30
|
+
- Pin the gateway dependency to its `v0.1.0-alpha.1` release tag.
|
|
31
|
+
- `grok-linux-agent dev ./my_gadget.py` runs your gadget with an in-process gateway and loopback auto-trust: no tokens to copy. It prints pasteable MCP settings (stdio needs no token at all). Needs the new `[gateway]` extra (`uv sync --extra gateway`; the gateway comes from its GitHub repository until it is on PyPI).
|
|
32
|
+
- `--token-file <path>` reads a private device token and re-reads it on every connection, so `grok-gadgets-gateway enroll <id> --rotate --token-file <path>` needs no agent restart. `--factory-file` accepts a plain gadget file.
|
|
33
|
+
- README: the quick start is one install, one ten-line file and one command.
|
|
34
|
+
- New decorator API: `Gadget(...)` with `@gadget.command("What it does")`. The JSON schema comes from type hints (`bool`, `int`, `float`, `str`, `Literal`, `list`, optional, `Annotated` with `Range`). `Device.capability` keeps working and gains `description=`; `event_capability` too.
|
|
35
|
+
- Capability descriptions reach the assistant (gateway `capability_descriptions`). A TCP hello may be up to 16 KiB; other frames stay 2048 bytes. Protocol README re-pinned from gateway `3e41aec`.
|
|
36
|
+
- Re-pin the protocol 0.1.0 README from gateway `c568c3e` (sections and `late_ack`; wire format unchanged). With `GROK_GATEWAY_SOURCE`, a test checks the copied protocol files match that gateway.
|
|
37
|
+
- A handler that overruns `handler_timeout` now gets a `failed` ACK (`handler_timeout`) and the session stays open; a replay of that command ID reports the same failure.
|
|
38
|
+
- `late_ack` and `unknown_command` replies to an ACK are non-fatal: the agent drops that ACK and keeps polling instead of reconnecting.
|
|
39
|
+
- CI runs the seven gateway integration tests against gateway `main` and fails if they skip. A new job runs the README quick start in fresh clones and calls the gadget over MCP. Both run on push, pull request and nightly.
|
|
40
|
+
|
|
41
|
+
## 0.1.0a1 — unpublished
|
|
42
|
+
|
|
43
|
+
Generic capability SDK and loopback agent with strict pinned contracts, bounded retries,
|
|
44
|
+
safe errors, and explicit trusted-file factories (including annotated dataclasses).
|
|
45
|
+
Installed software acceptance is recorded on macOS arm64 and Linux aarch64 in a pinned
|
|
46
|
+
container. Physical peripherals, real systemd behavior, native Grok/mobile evidence,
|
|
47
|
+
and independent human reproduction remain pending.
|
|
48
|
+
|
|
49
|
+
### Review fixes, 2026-10-05 — unpublished
|
|
50
|
+
|
|
51
|
+
- A reused command ID with changed arguments returns a failed `duplicate_conflict`
|
|
52
|
+
acknowledgement and keeps the session; replays report current state.
|
|
53
|
+
- State is limited so every acknowledgement fits one 2048-byte frame (closes the
|
|
54
|
+
AUDIT-LIN-001 edge); deeply nested replies are `invalid_response`.
|
|
55
|
+
- Custom event names carry `x-grok-gadgets-kind: event`; `history_lost` is reserved.
|
|
56
|
+
- Plain-function handlers run in a worker thread; new `Device.on_shutdown(callback)`.
|
|
57
|
+
- SIGTERM/SIGINT cancel the running handler and run shutdown hooks; one transient
|
|
58
|
+
`unauthorized` after a successful hello is retried; jittered backoff;
|
|
59
|
+
`--max-attempts` and `--retry-forever`; distinct exit codes 2/3/4/5.
|
|
60
|
+
- `GROK_GADGETS_DEVICE_TOKEN` replaces `GROK_DEVICE_TOKEN` (deprecated fallback).
|
|
61
|
+
- Usable systemd user-unit template; CI matrix for Python 3.11–3.14.
|
|
62
|
+
- Plain-language README; corrected evidence labels and security limits.
|
|
63
|
+
|
|
64
|
+
### Launch preparation, 2026-10-05 — unpublished
|
|
65
|
+
|
|
66
|
+
- Add a standalone fresh-wheel custom-device journey, architecture diagram, and runtime/evidence table.
|
|
67
|
+
- Expand contribution/support/conduct/security guidance and prepare `adidshaft` ownership.
|
|
68
|
+
- Preserve SDK runtime, canonical protocol pins, Apache-2.0 license, and notices.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Code of conduct
|
|
2
|
+
|
|
3
|
+
The canonical [Grok Gadgets policy](https://github.com/adidshaft/grok-gadgets/blob/main/CODE_OF_CONDUCT.md)
|
|
4
|
+
applies to SDK issues, pull requests, reviews, and project spaces. The link is a planned
|
|
5
|
+
destination until approved activation; these rules also apply during local preparation.
|
|
6
|
+
|
|
7
|
+
Be respectful, constructive, and inclusive. Critique behavior and code, not people.
|
|
8
|
+
Harassment, threats, discrimination, unwanted contact, and disclosure of someone else's
|
|
9
|
+
private information are unacceptable. Respect stated boundaries and reviewers' time.
|
|
10
|
+
|
|
11
|
+
Report concerns privately to **adidshaft@kyokasuigetsu.xyz**. **@adidshaft** is initially
|
|
12
|
+
responsible; no additional moderation team is implied. Share only what is needed to investigate.
|
|
13
|
+
Responses may include correction, warning, temporary restriction, or removal, proportionate
|
|
14
|
+
to conduct and repetition. Appeal through the same email with the decision and context;
|
|
15
|
+
the maintainer will reconsider it. No confidentiality guarantee or response SLA is invented.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Contributing to the Linux SDK
|
|
2
|
+
|
|
3
|
+
Contribute to the library, agent, examples, tests or documentation without hardware. Device handlers belong here. The gateway owns the canonical protocol and MCP routing.
|
|
4
|
+
|
|
5
|
+
Discuss large features, interface changes and protocol changes before implementation. Submit small typo fixes directly. Use the [writing guide](https://github.com/adidshaft/grok-gadgets/blob/main/docs/contributing/writing-guide.md) for documentation.
|
|
6
|
+
|
|
7
|
+
The hub owns [shared contribution policy](https://github.com/adidshaft/grok-gadgets/blob/main/CONTRIBUTING.md),
|
|
8
|
+
[governance](https://github.com/adidshaft/grok-gadgets/blob/main/GOVERNANCE.md), and
|
|
9
|
+
[roadmap](https://github.com/adidshaft/grok-gadgets/blob/main/ROADMAP.md). Use [GitHub Issues](https://github.com/adidshaft/grok-gadgets-linux-sdk/issues) to track current work. The [local issue ledger](planning/issues.json) records preparation work.
|
|
10
|
+
|
|
11
|
+
## Standalone checks
|
|
12
|
+
|
|
13
|
+
Use Python 3.11 or later and uv. CI runs the same sequence on Python 3.11, 3.12, 3.13 and 3.14. Fork the repository and clone your fork. A fork can hold only `main`, so start your branch from the upstream `dev`:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
git clone https://github.com/YOUR_ACCOUNT/grok-gadgets-linux-sdk.git
|
|
17
|
+
cd grok-gadgets-linux-sdk
|
|
18
|
+
git remote add upstream https://github.com/adidshaft/grok-gadgets-linux-sdk.git
|
|
19
|
+
git fetch upstream dev
|
|
20
|
+
git switch -c docs/LIN-123-clearer-device-example upstream/dev
|
|
21
|
+
uv sync --frozen --extra gateway --python 3.11
|
|
22
|
+
uv run ruff check .
|
|
23
|
+
uv run ruff format --check .
|
|
24
|
+
uv run python -m unittest discover -s tests -v
|
|
25
|
+
uv build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
These checks need no sibling checkout. Without `GROK_GATEWAY_SOURCE`, seven gateway integration tests skip locally. CI never skips them: it runs them against gateway `main` on every push, pull request and night. CI also runs the README quick start in fresh clones with `python3 scripts/check_readme_quickstart.py` (commit first; it clones `HEAD`). Each integration test has a time limit, so a hang is reported as a failure.
|
|
29
|
+
|
|
30
|
+
For runtime or protocol changes, use a reviewed gateway source checkout:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
GROK_GATEWAY_SOURCE=/absolute/path/grok-gadgets-gateway/src uv run python -m unittest discover -s tests -v
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Replace the placeholder with the checkout at the exact agreed commit. Record both SHAs.
|
|
37
|
+
The hub separately tests the coordinated component combination; an isolated SDK success
|
|
38
|
+
does not promote it automatically.
|
|
39
|
+
|
|
40
|
+
For example, factory-loading, or installation guidance changes, also run the fresh-wheel
|
|
41
|
+
onboarding from an empty folder outside the checkout. Put the SDK wheel and sdist and the
|
|
42
|
+
gateway wheel in that folder, then run:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
uv venv --python 3.11 --seed .venv
|
|
46
|
+
.venv/bin/python -m pip install ./grok_gadgets_linux_sdk-0.1.0a1-py3-none-any.whl ./grok_gadgets_gateway-0.1.0a1-py3-none-any.whl
|
|
47
|
+
tar -xzf grok_gadgets_linux_sdk-0.1.0a1.tar.gz
|
|
48
|
+
.venv/bin/python -I grok_gadgets_linux_sdk-0.1.0a1/scripts/check_onboarding.py grok_gadgets_linux_sdk-0.1.0a1/docs/development.md
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
It runs the documented `my_gadget.py` with `--factory-file` against an authenticated
|
|
52
|
+
loopback gateway and prints `"ack": "executed"`. Run the lint/format/unit/build checks
|
|
53
|
+
before committing documentation as well as code. Linux service/peripheral claims need
|
|
54
|
+
their own authorized Linux/hardware observations.
|
|
55
|
+
|
|
56
|
+
## Branches
|
|
57
|
+
|
|
58
|
+
Branch from `dev` and open your PR into `dev` for integration, development and testing; PRs into `dev` are squash-merged when checks pass. `main` is the default branch for users, builders and the website, holds tagged releases, and changes only through release or hotfix PRs. Name branches `<type>/<ISSUE-ID>-<short-slug>`, for example `fix/LIN-021-short-name`. The shared [branch and release policy](https://github.com/adidshaft/grok-gadgets/blob/main/CONTRIBUTING.md#branches-and-releases) covers releases, hotfixes and cross-repository changes.
|
|
59
|
+
|
|
60
|
+
Push the branch to your fork and open the PR into `adidshaft/grok-gadgets-linux-sdk` `dev`. The GitHub PR form selects `main` by default. Change the base branch to `dev`, because the PR-target check rejects other PRs into `main`.
|
|
61
|
+
|
|
62
|
+
## Review and credit
|
|
63
|
+
|
|
64
|
+
Use a short branch from `dev`. Make small tested commits and link the public issue. Explain the behavior before and after the change. Add a regression test when necessary.
|
|
65
|
+
|
|
66
|
+
Record commands, results, runtime and evidence level. Update user guidance. Respond to review and resolve conflicts on your branch. Then repeat affected checks.
|
|
67
|
+
|
|
68
|
+
Handlers must validate arguments and report observed state. Preserve retry, reconnect,
|
|
69
|
+
bounded retention, and safe-error behavior. Protocol changes start upstream and require
|
|
70
|
+
renewed canonical pins/hashes plus hub compatibility evidence; never hand-edit schema copies.
|
|
71
|
+
|
|
72
|
+
The maintainer credits code, documentation, testing, and review. You remain responsible
|
|
73
|
+
for AI-assisted contributions, licenses, and verified test claims. Contributions use
|
|
74
|
+
Apache-2.0; no additional CLA or sign-off is required. Never include credentials or private
|
|
75
|
+
captures. Do not publish, deploy, or operate live peripherals in an unapproved test.
|
|
76
|
+
|
|
77
|
+
See [support](SUPPORT.md), [conduct](CODE_OF_CONDUCT.md), [security](SECURITY.md), and [AGENTS](AGENTS.md).
|
|
78
|
+
|
|
79
|
+
## Ignore rules and publication privacy
|
|
80
|
+
|
|
81
|
+
Update `.gitignore` for new caches, build output, local device configuration, logs and credentials. Keep reviewed sample configuration and the hub’s public simulator download.
|
|
82
|
+
|
|
83
|
+
Check new patterns with `git check-ignore`. Review staged files before each commit. Ignore rules do not remove tracked files or history. Never merge private pre-publication history into a public branch. Use the sanitized public checkout and a public or GitHub noreply commit email.
|
|
84
|
+
|
|
85
|
+
## Documentation style
|
|
86
|
+
|
|
87
|
+
Use ASD-STE100-inspired English. This project does not claim certified compliance.
|
|
88
|
+
Use active verbs, short sentences and one instruction per numbered step.
|
|
89
|
+
Keep technical names, commands and quoted evidence exact. Explain each new technical term.
|
|
90
|
+
Separate current instructions from dated test records. Link to evidence before you claim a test passed.
|
|
91
|
+
Run the repository's plain-language check on each changed guide. It checks sentence length, not the full standard.
|