hermes-a365 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. hermes_a365-0.1.1/.gitignore +58 -0
  2. hermes_a365-0.1.1/CHANGELOG.md +154 -0
  3. hermes_a365-0.1.1/LICENSE +21 -0
  4. hermes_a365-0.1.1/PKG-INFO +622 -0
  5. hermes_a365-0.1.1/README.md +595 -0
  6. hermes_a365-0.1.1/SKILL.md +342 -0
  7. hermes_a365-0.1.1/pyproject.toml +84 -0
  8. hermes_a365-0.1.1/references/README.md +31 -0
  9. hermes_a365-0.1.1/src/hermes_a365/__init__.py +3 -0
  10. hermes_a365-0.1.1/src/hermes_a365/_common.py +204 -0
  11. hermes_a365-0.1.1/src/hermes_a365/_data/__init__.py +0 -0
  12. hermes_a365-0.1.1/src/hermes_a365/_data/templates/adaptive-cards/confirmation.json.j2 +29 -0
  13. hermes_a365-0.1.1/src/hermes_a365/_data/templates/adaptive-cards/error.json.j2 +30 -0
  14. hermes_a365-0.1.1/src/hermes_a365/_data/templates/adaptive-cards/greeting.json.j2 +34 -0
  15. hermes_a365-0.1.1/src/hermes_a365/_data/templates/blueprint.json.j2 +19 -0
  16. hermes_a365-0.1.1/src/hermes_a365/_data/templates/consent-url.txt.j2 +13 -0
  17. hermes_a365-0.1.1/src/hermes_a365/_data/templates/instance.env.j2 +16 -0
  18. hermes_a365-0.1.1/src/hermes_a365/a365_config.py +104 -0
  19. hermes_a365-0.1.1/src/hermes_a365/activity_bridge.py +1775 -0
  20. hermes_a365-0.1.1/src/hermes_a365/cleanup.py +600 -0
  21. hermes_a365-0.1.1/src/hermes_a365/cli.py +128 -0
  22. hermes_a365-0.1.1/src/hermes_a365/consent.py +261 -0
  23. hermes_a365-0.1.1/src/hermes_a365/doctor.py +422 -0
  24. hermes_a365-0.1.1/src/hermes_a365/emit_card.py +209 -0
  25. hermes_a365-0.1.1/src/hermes_a365/hermes_responder.py +385 -0
  26. hermes_a365-0.1.1/src/hermes_a365/instance_create.py +328 -0
  27. hermes_a365-0.1.1/src/hermes_a365/keychain.py +407 -0
  28. hermes_a365-0.1.1/src/hermes_a365/license.py +217 -0
  29. hermes_a365-0.1.1/src/hermes_a365/mutator.py +265 -0
  30. hermes_a365-0.1.1/src/hermes_a365/plugin/README.md +112 -0
  31. hermes_a365-0.1.1/src/hermes_a365/plugin/__init__.py +47 -0
  32. hermes_a365-0.1.1/src/hermes_a365/plugin/adapter.py +756 -0
  33. hermes_a365-0.1.1/src/hermes_a365/plugin/cli.py +142 -0
  34. hermes_a365-0.1.1/src/hermes_a365/plugin/conversations.py +213 -0
  35. hermes_a365-0.1.1/src/hermes_a365/plugin/plugin.yaml +17 -0
  36. hermes_a365-0.1.1/src/hermes_a365/publish.py +268 -0
  37. hermes_a365-0.1.1/src/hermes_a365/reconcile_app.py +183 -0
  38. hermes_a365-0.1.1/src/hermes_a365/reconcile_blueprint.py +147 -0
  39. hermes_a365-0.1.1/src/hermes_a365/register.py +687 -0
  40. hermes_a365-0.1.1/src/hermes_a365/render_instance_env.py +112 -0
  41. hermes_a365-0.1.1/src/hermes_a365/status.py +558 -0
  42. hermes_a365-0.1.1/tests/conftest.py +18 -0
  43. hermes_a365-0.1.1/tests/golden/adaptive-cards/confirmation_action_only.json +15 -0
  44. hermes_a365-0.1.1/tests/golden/adaptive-cards/confirmation_with_facts.json +33 -0
  45. hermes_a365-0.1.1/tests/golden/adaptive-cards/error_minimal.json +20 -0
  46. hermes_a365-0.1.1/tests/golden/adaptive-cards/error_with_detail.json +27 -0
  47. hermes_a365-0.1.1/tests/golden/adaptive-cards/greeting_minimal.json +19 -0
  48. hermes_a365-0.1.1/tests/golden/adaptive-cards/greeting_with_commands.json +36 -0
  49. hermes_a365-0.1.1/tests/golden/blueprint/minimal.json +25 -0
  50. hermes_a365-0.1.1/tests/golden/blueprint/with_workiq.json +31 -0
  51. hermes_a365-0.1.1/tests/golden/instance_env/minimal.env +7 -0
  52. hermes_a365-0.1.1/tests/golden/instance_env/with_business_hours.env +10 -0
  53. hermes_a365-0.1.1/tests/golden/license/addon_small_team.txt +15 -0
  54. hermes_a365-0.1.1/tests/golden/license/e7_large_team.txt +16 -0
  55. hermes_a365-0.1.1/tests/test_a365_config.py +138 -0
  56. hermes_a365-0.1.1/tests/test_activity_bridge.py +1555 -0
  57. hermes_a365-0.1.1/tests/test_agent365_plugin.py +1374 -0
  58. hermes_a365-0.1.1/tests/test_cleanup.py +772 -0
  59. hermes_a365-0.1.1/tests/test_common.py +196 -0
  60. hermes_a365-0.1.1/tests/test_consent.py +310 -0
  61. hermes_a365-0.1.1/tests/test_doctor.py +380 -0
  62. hermes_a365-0.1.1/tests/test_emit_card.py +266 -0
  63. hermes_a365-0.1.1/tests/test_hermes_responder.py +322 -0
  64. hermes_a365-0.1.1/tests/test_instance_create.py +264 -0
  65. hermes_a365-0.1.1/tests/test_keychain.py +405 -0
  66. hermes_a365-0.1.1/tests/test_license.py +249 -0
  67. hermes_a365-0.1.1/tests/test_mutator.py +208 -0
  68. hermes_a365-0.1.1/tests/test_publish.py +260 -0
  69. hermes_a365-0.1.1/tests/test_reconcile_app.py +192 -0
  70. hermes_a365-0.1.1/tests/test_reconcile_blueprint.py +136 -0
  71. hermes_a365-0.1.1/tests/test_register.py +724 -0
  72. hermes_a365-0.1.1/tests/test_render_instance_env.py +86 -0
  73. hermes_a365-0.1.1/tests/test_status.py +433 -0
@@ -0,0 +1,58 @@
1
+ # Secrets / local config
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+ *.pem
6
+ *.key
7
+
8
+ # A365 CLI runtime config — `a365.config.json` is operator-edited; the
9
+ # `*.generated.config.json` files emitted by `a365 setup blueprint`
10
+ # contain the agent blueprint client secret in plaintext on platforms
11
+ # where DPAPI is unavailable (macOS, Linux). Never commit.
12
+ #
13
+ # The trailing `*` also catches operator-suffixed snapshots
14
+ # (e.g. `a365.generated.config.json.r5-cleared`, `…json.bak`) so a
15
+ # stray `git add .` can't ship a tenant-shaped artefact.
16
+ a365.config.json*
17
+ a365.generated.config.json*
18
+ *.generated.config.json*
19
+ # Newcomers seed `a365.config.json` from this template — keep it tracked.
20
+ !a365.config.json.example
21
+ # `a365 cleanup -y` writes timestamped backups of the above files.
22
+ a365.config.backup-*.json
23
+ a365.generated.config.backup-*.json
24
+ # `a365 publish --aiteammate` extracts manifest templates + zips them
25
+ # under ./manifest/ as a build artefact (slice 19g, walkthrough finding).
26
+ # Regenerated each publish — keep it out of git.
27
+ manifest/
28
+
29
+ # Python
30
+ __pycache__/
31
+ *.py[cod]
32
+ *$py.class
33
+ *.egg-info/
34
+ .venv/
35
+ venv/
36
+ .pytest_cache/
37
+ .mypy_cache/
38
+ .ruff_cache/
39
+
40
+ # Node (in case templates/scripts pull anything)
41
+ node_modules/
42
+
43
+ # macOS
44
+ .DS_Store
45
+ ._*
46
+
47
+ # Editors
48
+ .vscode/
49
+ .idea/
50
+ *.swp
51
+
52
+ # Build / dist
53
+ dist/
54
+ build/
55
+
56
+ # Local-only working files
57
+ local/
58
+ scratch/
@@ -0,0 +1,154 @@
1
+ # Changelog
2
+
3
+ All notable changes to the `hermes-a365` skill / plugin live here. Format
4
+ follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions
5
+ follow [SemVer](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.1] — 2026-05-11
10
+
11
+ Repackaging-only release: `hermes-a365` is now `pip install`-able from
12
+ PyPI. No behavioural changes; the apply paths, read paths, and Bot
13
+ Framework activity bridge are identical to `v0.1.0`.
14
+
15
+ ### Changed
16
+
17
+ - **Distribution.** Source tree moved to a real `src/hermes_a365/`
18
+ layout. `[tool.uv] package = false` is gone; the wheel is built via
19
+ `hatchling` and published to PyPI. Two install paths now supported:
20
+ - **Standalone CLI:** `pipx install 'hermes-a365[bridge]'` exposes a
21
+ `hermes-a365 <verb>` console script for operators who drive the
22
+ wrappers without spinning up a Hermes gateway.
23
+ - **Gateway plugin:** `~/.hermes/hermes-agent/venv/bin/pip install
24
+ 'hermes-a365[bridge]'`. The Hermes plugin loader auto-discovers
25
+ `agent365` via the `hermes_agent.plugins` entry point — no
26
+ `~/.hermes/plugins/agent365/` directory, no symlink.
27
+ - **Imports.** Every module is now `hermes_a365.<x>`. The
28
+ symlink-walking `Path(__file__).resolve().parent.parent.parent /
29
+ "scripts"` trick in the plugin (`plugins/agent365/{adapter,cli}.py`)
30
+ is retired; the plugin imports `from hermes_a365 import
31
+ activity_bridge` directly.
32
+ - **Templates.** `templates/` is now packaged as `hermes_a365._data/
33
+ templates/` and resolved via `importlib.resources` so lookups work
34
+ for both editable installs and wheels.
35
+ - **Tests.** Bare imports (`from a365_config import …`) rewritten to
36
+ `from hermes_a365.a365_config import …`. `tests/conftest.py` no
37
+ longer pokes `scripts/` onto `sys.path`. 624 tests still passing.
38
+ - **Docs.** README, SKILL.md, and the `references/` runbooks updated
39
+ to drop the symlink instructions and the `uv run python scripts/<x>.py`
40
+ invocation style in favour of `pipx install` + `hermes-a365 <verb>`
41
+ (or `python -m hermes_a365.<x>` for the modules that aren't surfaced
42
+ as CLI subcommands).
43
+
44
+ ## [0.1.0] — 2026-05-08
45
+
46
+ First operator-targeted release. Validated end-to-end against
47
+ Microsoft.Agents.A365.DevTools.Cli **1.1.171** (round-5 walkthrough,
48
+ 2026-05-06) and the secret-null regression-recovery path on **1.1.174**
49
+ (round-6, 2026-05-07).
50
+
51
+ ### Added — apply path (operator-side wrappers)
52
+
53
+ - `hermes a365 register` — orchestrates `a365 setup blueprint` +
54
+ `setup permissions mcp` + `setup permissions bot` with AADSTS-aware
55
+ retry, layer-1 client-secret regression detection, and opt-in
56
+ `--auto-recover-secret` (handles Microsoft#408 on macOS / Linux).
57
+ - `hermes a365 consent` — render admin-consent URL, optionally launch a
58
+ browser, poll `query-entra blueprint-scopes` until consent is granted.
59
+ - `hermes a365 instance create <slug>` — write the per-agent runtime
60
+ `~/.hermes/agents/<slug>/.env` (no cloud step).
61
+ - `hermes a365 publish` — package the AI Teammate manifest zip for
62
+ Microsoft 365 Admin Centre upload.
63
+ - `hermes a365 cleanup` — destructive teardown with `--purge-orphans`
64
+ for blueprint-flow agentic users + agentRegistry instances. AI
65
+ Teammate-flow store-managed instances always 403 on delete (Microsoft
66
+ platform limitation, documented in `references/live-tenant-test.md`).
67
+ - `hermes a365 license` — recommends an A365 license tier given a user
68
+ + agent count and plan.
69
+
70
+ ### Added — read path
71
+
72
+ - `hermes a365 doctor` — read-only environment probe (CLI version, az
73
+ signed-in, pwsh on PATH, network reachability, OS keychain backend).
74
+ - `hermes a365 status [<slug>]` — per-component status report against
75
+ `query-entra` (local config, blueprint scopes, instance scopes, local
76
+ bridge PID).
77
+
78
+ ### Added — runtime
79
+
80
+ - **`agent365` Hermes platform adapter** (`plugins/agent365/`).
81
+ Validated end-to-end against a Frontier-Preview tenant on Microsoft
82
+ Teams 1:1 chat (rounds 3 → 5). Inbound activities go through AAD-v2
83
+ JWT validation, BF idempotency dedupe, and `serviceUrl` host-suffix
84
+ allowlist before reaching the agent loop.
85
+ - **`hermes a365 activity-bridge`** — Bot Framework adapter daemon.
86
+ - `verify` — one-shot diagnostic (config + auth + reachability).
87
+ - `serve` — long-running `/api/messages` webhook (FastAPI + uvicorn
88
+ via the optional `bridge` extras).
89
+ - `update-endpoint` — re-points the agent's messaging endpoint at a
90
+ public tunnel URL.
91
+ - **Three-stage user-FIC token chain** for outbound replies (BF S2S →
92
+ agent FMI delegation → user FIC), plus per-conversation
93
+ durable registry that survives gateway restarts
94
+ (`~/.hermes/agents/<slug>/conversations.json`).
95
+ - **`agents`-channel synthetic-event filter** — drops M365 onboarding
96
+ probes + email-template render activities so they don't waste an
97
+ agent turn (round-5 walkthrough finding).
98
+
99
+ ### Added — CLI surface
100
+
101
+ - `hermes a365 <verb>` is wired via the supported Hermes plugin
102
+ `register_cli_command` API (slice 19x-a, this release). Each verb
103
+ delegates to the matching `scripts/<x>.py` module; running
104
+ `python scripts/<x>.py` continues to work for development.
105
+
106
+ ### Added — references / runbooks
107
+
108
+ - `references/live-tenant-test.md` — end-to-end runbook for a
109
+ Frontier-Preview tenant; flags macOS 26 device-code prompt-volume
110
+ failure mode (~10–12 prompts per `register --apply --m365`).
111
+ - `references/m365-surface-coverage.md` — per-surface coverage matrix.
112
+ - `references/exposing-the-bot-endpoint.md` — operator-side options
113
+ (cloudflared, devtunnels, ngrok, reverse-proxy) — non-prescriptive.
114
+ - `references/a365-cli-reference.md`, `webhook-contract.md`,
115
+ `activity-protocol-shapes.md`, `error-codes.md`,
116
+ `entra-blueprint-properties.md`, `opentelemetry-config.md`,
117
+ `license-cost-table.md`.
118
+
119
+ ### Filed upstream
120
+
121
+ - **microsoft/Agent365-devTools#402** — cosmetic logging fixes when
122
+ Observability-only S2S app-role assignment is the intended state.
123
+ Microsoft confirmed intent + shipped fixes in CLI 1.1.174.
124
+ - **microsoft/Agent365-devTools#408** — `agentBlueprintClientSecret`
125
+ null-on-disk regression on macOS (DPAPI unavailable). Layer 1
126
+ detection + auto-recovery shipped in this release; Layer 2 is the
127
+ upstream fix.
128
+
129
+ ### Known limitations
130
+
131
+ - **M365 Copilot streaming** ([#3](https://github.com/satscryption/Hermes-A365/issues/3))
132
+ not yet implemented — `Agent365Adapter.edit_message` is a no-op and
133
+ `REQUIRES_EDIT_FINALIZE` is unset. Required for Copilot Chat surface.
134
+ - **Proactive replies for >10 s agent thinking**
135
+ ([#4](https://github.com/satscryption/Hermes-A365/issues/4)) — `send()`
136
+ still requires a cached inbound; cron-driven sends do not work yet.
137
+ - **`hermes gateway setup` wizard**
138
+ ([#13](https://github.com/satscryption/Hermes-A365/issues/13)) not yet
139
+ shipped — operators must hand-edit `~/.hermes/config.yaml` and
140
+ `~/.hermes/.env` per the README quickstart.
141
+ - **Invoke activities** (Outlook compose-action, Teams compose
142
+ extensions, search, signin) tracked under
143
+ [#18](https://github.com/satscryption/Hermes-A365/issues/18); umbrella
144
+ not yet implemented.
145
+ - **Plaintext on-disk secret on macOS / Linux.** DPAPI is Windows-only;
146
+ the keychain shim in `scripts/keychain.py` writes the agent blueprint
147
+ client secret to `a365.generated.config.json` with mode `0600`. See
148
+ README "Security model".
149
+ - **AI Teammate-flow agentRegistry entries cannot be deleted** by
150
+ operators (only "blocked" via the M365 Admin Centre). Microsoft
151
+ platform limitation; not a wrapper bug.
152
+
153
+ [Unreleased]: https://github.com/satscryption/Hermes-A365/compare/v0.1.0...HEAD
154
+ [0.1.0]: https://github.com/satscryption/Hermes-A365/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sadiq Jaffer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.