agent-wire-cli 0.2.2__tar.gz → 0.2.4__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.
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/.claude-plugin/plugin.json +1 -1
- agent_wire_cli-0.2.4/.github/dependabot.yml +31 -0
- agent_wire_cli-0.2.4/.github/scripts/mcp_smoke.py +36 -0
- agent_wire_cli-0.2.4/.github/workflows/ci.yml +116 -0
- agent_wire_cli-0.2.4/.github/workflows/codeql.yml +40 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/.github/workflows/release.yml +13 -6
- agent_wire_cli-0.2.4/.github/workflows/security.yml +70 -0
- agent_wire_cli-0.2.4/PKG-INFO +726 -0
- agent_wire_cli-0.2.4/README.md +696 -0
- agent_wire_cli-0.2.4/SECURITY.md +48 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/agents/wire-worker.md +3 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/manifests/cursor_rule.mdc +1 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/manifests/gemini_extension.json +1 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/manifests/hermes_skill.md +2 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/manifests/windsurf_rules.md +1 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/pyproject.toml +5 -3
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/skills/agent-wire/SKILL.md +15 -4
- agent_wire_cli-0.2.4/src/agent_wire/__init__.py +1 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/base.py +7 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/github.py +2 -2
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/reddit.py +4 -3
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/rss.py +3 -4
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/search.py +3 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/web.py +2 -2
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/arxiv_papers.py +7 -2
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/hubs.py +2 -2
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/news.py +2 -2
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/publishing.py +2 -2
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/bilibili.py +4 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/douyin_tiktok.py +10 -3
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/cli.py +25 -2
- agent_wire_cli-0.2.4/src/agent_wire/codemode/__init__.py +1 -0
- agent_wire_cli-0.2.4/src/agent_wire/codemode/api.py +122 -0
- agent_wire_cli-0.2.4/src/agent_wire/codemode/sandbox.py +208 -0
- agent_wire_cli-0.2.4/src/agent_wire/engine/errors.py +9 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/engine/http_pool.py +33 -22
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/engine/stealth_browser.py +16 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/engine/waterfall.py +13 -6
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/firewall/outbound_privacy.py +22 -0
- agent_wire_cli-0.2.4/src/agent_wire/firewall/ssrf_guard.py +123 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/media/audio_transcriber.py +1 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/watch.py +3 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/server.py +219 -60
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/verify/citations.py +15 -2
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_channels_new.py +16 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_citations.py +7 -1
- agent_wire_cli-0.2.4/tests/test_codemode.py +220 -0
- agent_wire_cli-0.2.4/tests/test_codemode_bench.py +75 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_firewall_outbound.py +20 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_server.py +2 -2
- agent_wire_cli-0.2.4/tests/test_ssrf_guard.py +262 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_waterfall_routing.py +10 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/uv.lock +57 -148
- agent_wire_cli-0.2.2/.github/workflows/ci.yml +0 -52
- agent_wire_cli-0.2.2/PKG-INFO +0 -333
- agent_wire_cli-0.2.2/README.md +0 -305
- agent_wire_cli-0.2.2/src/agent_wire/__init__.py +0 -1
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/.claude-plugin/marketplace.json +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/.gitignore +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/.mcp.json +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/LICENSE +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-banner-light.png +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-banner-light.svg +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-banner.png +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-banner.svg +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-logo-transparent.png +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-logo-transparent.svg +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-logo.png +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/assets/agent-wire-logo.svg +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/manifests/antigravity_mcp.json +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/manifests/codex.toml +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/manifests/peridot_local.json +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/__main__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/auth/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/auth/browser_paths.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/auth/cookie_vault.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/auth/rate_limiter.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/cache/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/cache/ring_buffer.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/cache/sqlite_ledger.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/hackernews.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/stackoverflow.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/wikipedia.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/x_twitter.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier1_global/youtube.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/archive_bypass.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/devto.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/fediverse.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/linkedin.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/markets.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/meta_social.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/polymarket.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier2_pro/stocktwits.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/boss_zhipin.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/v2ex.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/wechat.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/xiaohongshu.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/xiaoyuzhou.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/xueqiu.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/channels/tier3_regional/zhihu.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/compression/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/compression/anchor_slicer.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/compression/bm25_slicer.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/compression/dam_formatter.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/compression/url_compactor.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/config.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/engine/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/engine/challenge.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/firewall/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/firewall/inbound_shield.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/installers/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/installers/client_installer.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/media/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/media/subtitle_cleaner.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/models.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/brief.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/briefing.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/cluster.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/engine.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/library.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/planner.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/scoring.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/research/store.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/router.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/src/agent_wire/verify/__init__.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/conftest.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_auth.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_bm25_slicer.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_channels_tier1.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_channels_tier2_3.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_compression.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_config.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_firewall_inbound.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_installer.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_models.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_research.py +0 -0
- {agent_wire_cli-0.2.2 → agent_wire_cli-0.2.4}/tests/test_ring_buffer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-wire",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Live web and 31-platform access for agents: token-compressed, privacy-firewalled, injection-shielded. Auto-triggers on links and live questions.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "uncoalesced"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Python dependencies in uv.lock. Security fixes come as separate PRs straight away
|
|
4
|
+
# (Dependabot security updates); this keeps routine upgrades to one weekly batch. Routine
|
|
5
|
+
# upgrades wait 7 days after a release, so a hijacked version is usually pulled before we take it.
|
|
6
|
+
- package-ecosystem: uv
|
|
7
|
+
directory: /
|
|
8
|
+
target-branch: dev
|
|
9
|
+
schedule:
|
|
10
|
+
interval: weekly
|
|
11
|
+
day: monday
|
|
12
|
+
groups:
|
|
13
|
+
python:
|
|
14
|
+
patterns: ["*"]
|
|
15
|
+
update-types: [minor, patch]
|
|
16
|
+
open-pull-requests-limit: 5
|
|
17
|
+
cooldown:
|
|
18
|
+
default-days: 7
|
|
19
|
+
|
|
20
|
+
# Actions are pinned to commit SHAs; this bumps the SHA and the version comment together.
|
|
21
|
+
- package-ecosystem: github-actions
|
|
22
|
+
directory: /
|
|
23
|
+
target-branch: dev
|
|
24
|
+
schedule:
|
|
25
|
+
interval: weekly
|
|
26
|
+
day: monday
|
|
27
|
+
groups:
|
|
28
|
+
actions:
|
|
29
|
+
patterns: ["*"]
|
|
30
|
+
cooldown:
|
|
31
|
+
default-days: 7
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""CI smoke test for an installed agent-wire: start the real stdio MCP server and talk to it.
|
|
2
|
+
|
|
3
|
+
No network: lists tools in both modes, runs a Code Mode script that makes no wire calls, and checks
|
|
4
|
+
that a runaway script comes back as an error instead of hanging the server.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
from fastmcp import Client
|
|
11
|
+
from fastmcp.client.transports import StdioTransport
|
|
12
|
+
|
|
13
|
+
FULL = {"wire_read", "wire_search", "wire_feed", "wire_me", "wire_research", "wire_cite",
|
|
14
|
+
"wire_run", "wire_status"} # fmt: skip
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
async def check(args: list[str], expect: set[str]) -> None:
|
|
18
|
+
transport = StdioTransport(sys.executable, ["-m", "agent_wire", *args])
|
|
19
|
+
async with Client(transport) as c:
|
|
20
|
+
names = {t.name for t in await c.list_tools()}
|
|
21
|
+
assert names == expect, f"{args}: tools {sorted(names)}"
|
|
22
|
+
out = await c.call_tool("wire_run", {"code": "return [1 + 1, typeof wire.read]"})
|
|
23
|
+
text = out.content[0].text
|
|
24
|
+
assert text.startswith("[WIRE | code | 0 calls") and '[2,"function"]' in text, text
|
|
25
|
+
hang = (await c.call_tool("wire_run", {"code": "for (;;) await 0"})).content[0].text
|
|
26
|
+
assert hang.startswith("[WIRE | error | code") and "CPU time limit" in hang, hang
|
|
27
|
+
print(f"ok: wire {' '.join(args)} -> {len(names)} tools")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
async def main() -> None:
|
|
31
|
+
await asyncio.wait_for(check(["serve"], FULL), 120)
|
|
32
|
+
await asyncio.wait_for(check(["serve", "--code-mode"], {"wire_run", "wire_status"}), 120)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ci-${{ github.ref }}
|
|
13
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
lint:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 10
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
21
|
+
with:
|
|
22
|
+
persist-credentials: false
|
|
23
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
24
|
+
- name: Lockfile matches pyproject.toml
|
|
25
|
+
run: uv lock --check
|
|
26
|
+
- name: Install
|
|
27
|
+
run: uv sync --extra dev --locked
|
|
28
|
+
- name: Ruff lint
|
|
29
|
+
run: uv run ruff check src tests .github/scripts
|
|
30
|
+
- name: Ruff format
|
|
31
|
+
run: uv run ruff format --check .
|
|
32
|
+
- name: No temp-dir writes in the package
|
|
33
|
+
run: "! grep -rnE 'tempfile|/tmp' src/"
|
|
34
|
+
|
|
35
|
+
test:
|
|
36
|
+
strategy:
|
|
37
|
+
fail-fast: false
|
|
38
|
+
matrix:
|
|
39
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
40
|
+
python: ["3.11", "3.14"]
|
|
41
|
+
include:
|
|
42
|
+
- {os: ubuntu-latest, python: "3.12"}
|
|
43
|
+
- {os: ubuntu-latest, python: "3.13"}
|
|
44
|
+
runs-on: ${{ matrix.os }}
|
|
45
|
+
timeout-minutes: 20
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
48
|
+
with:
|
|
49
|
+
persist-credentials: false
|
|
50
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
51
|
+
with:
|
|
52
|
+
python-version: ${{ matrix.python }}
|
|
53
|
+
- name: Install
|
|
54
|
+
run: uv sync --extra dev --locked
|
|
55
|
+
- name: Test (offline; network calls are faked)
|
|
56
|
+
run: uv run pytest -q
|
|
57
|
+
|
|
58
|
+
build:
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
timeout-minutes: 10
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
63
|
+
with:
|
|
64
|
+
persist-credentials: false
|
|
65
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
66
|
+
- name: Build sdist and wheel
|
|
67
|
+
run: uv build
|
|
68
|
+
- name: Package metadata renders on PyPI
|
|
69
|
+
run: uvx twine check --strict dist/*
|
|
70
|
+
- name: Wheel bundles the skill, rules and sandbox, at the pyproject version
|
|
71
|
+
run: |
|
|
72
|
+
python - <<'EOF'
|
|
73
|
+
import glob, re, zipfile
|
|
74
|
+
version = re.search(r'^version = "(.+)"', open("pyproject.toml").read(), re.M)[1]
|
|
75
|
+
whl = glob.glob("dist/*.whl")[0]
|
|
76
|
+
assert f"-{version}-" in whl, (whl, version)
|
|
77
|
+
names = zipfile.ZipFile(whl).namelist()
|
|
78
|
+
for need in ("agent_wire/assets/SKILL.md", "agent_wire/assets/wire-worker.md",
|
|
79
|
+
"agent_wire/research/engine.py", "agent_wire/codemode/sandbox.py",
|
|
80
|
+
"agent_wire/codemode/api.py"):
|
|
81
|
+
assert need in names, need
|
|
82
|
+
print("ok", whl, len(names), "files")
|
|
83
|
+
EOF
|
|
84
|
+
|
|
85
|
+
# Install the built wheel the way users do (no repo, no dev deps) and drive the real MCP server.
|
|
86
|
+
smoke:
|
|
87
|
+
needs: build
|
|
88
|
+
strategy:
|
|
89
|
+
fail-fast: false
|
|
90
|
+
matrix:
|
|
91
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
92
|
+
python: ["3.11", "3.14"]
|
|
93
|
+
runs-on: ${{ matrix.os }}
|
|
94
|
+
timeout-minutes: 15
|
|
95
|
+
steps:
|
|
96
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
97
|
+
with:
|
|
98
|
+
persist-credentials: false
|
|
99
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
100
|
+
with:
|
|
101
|
+
python-version: ${{ matrix.python }}
|
|
102
|
+
- name: Build wheel
|
|
103
|
+
run: uv build --wheel
|
|
104
|
+
- name: CLI runs from the wheel
|
|
105
|
+
shell: bash
|
|
106
|
+
run: |
|
|
107
|
+
whl=$(ls dist/*.whl)
|
|
108
|
+
uvx --python ${{ matrix.python }} --from "$whl" agent-wire version
|
|
109
|
+
out=$(uvx --python ${{ matrix.python }} --from "$whl" wire run -e "return 6 * 7")
|
|
110
|
+
echo "$out"
|
|
111
|
+
grep -q '^42$' <<<"$out"
|
|
112
|
+
- name: MCP server over stdio (both modes)
|
|
113
|
+
shell: bash
|
|
114
|
+
run: >-
|
|
115
|
+
uv run --isolated --no-project --python ${{ matrix.python }}
|
|
116
|
+
--with "$(ls dist/*.whl)" python .github/scripts/mcp_smoke.py
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: codeql
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: "41 5 * * 1"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: codeql-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
analyze:
|
|
20
|
+
strategy:
|
|
21
|
+
fail-fast: false
|
|
22
|
+
matrix:
|
|
23
|
+
language: [python, actions]
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
timeout-minutes: 30
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
security-events: write # upload results to the Security tab
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
31
|
+
with:
|
|
32
|
+
persist-credentials: false
|
|
33
|
+
- uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
|
|
34
|
+
with:
|
|
35
|
+
languages: ${{ matrix.language }}
|
|
36
|
+
build-mode: none
|
|
37
|
+
queries: security-extended
|
|
38
|
+
- uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
|
|
39
|
+
with:
|
|
40
|
+
category: /language:${{ matrix.language }}
|
|
@@ -13,9 +13,14 @@ permissions:
|
|
|
13
13
|
jobs:
|
|
14
14
|
build:
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
|
+
timeout-minutes: 20
|
|
16
17
|
steps:
|
|
17
|
-
- uses: actions/checkout@
|
|
18
|
-
|
|
18
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
19
|
+
with:
|
|
20
|
+
persist-credentials: false
|
|
21
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
22
|
+
with:
|
|
23
|
+
enable-cache: false # never build a release from a cache another run could have written
|
|
19
24
|
- name: Tag matches the package version
|
|
20
25
|
run: |
|
|
21
26
|
v=$(grep -m1 '^version' pyproject.toml | cut -d'"' -f2)
|
|
@@ -23,7 +28,8 @@ jobs:
|
|
|
23
28
|
- run: uv sync --extra dev --locked
|
|
24
29
|
- run: uv run pytest -q
|
|
25
30
|
- run: uv build
|
|
26
|
-
-
|
|
31
|
+
- run: uvx twine check --strict dist/*
|
|
32
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
27
33
|
with:
|
|
28
34
|
name: dist
|
|
29
35
|
path: dist/
|
|
@@ -31,12 +37,13 @@ jobs:
|
|
|
31
37
|
publish:
|
|
32
38
|
needs: build
|
|
33
39
|
runs-on: ubuntu-latest
|
|
40
|
+
timeout-minutes: 10
|
|
34
41
|
environment: pypi
|
|
35
42
|
permissions:
|
|
36
|
-
id-token: write
|
|
43
|
+
id-token: write # PyPI trusted publishing
|
|
37
44
|
steps:
|
|
38
|
-
- uses: actions/download-artifact@
|
|
45
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
39
46
|
with:
|
|
40
47
|
name: dist
|
|
41
48
|
path: dist/
|
|
42
|
-
- uses: pypa/gh-action-pypi-publish@
|
|
49
|
+
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: security
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
schedule:
|
|
8
|
+
- cron: "17 6 * * 1" # Mondays: new advisories land against an unchanged lockfile
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: security-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
# Known CVEs in every locked dependency, including the optional extras.
|
|
20
|
+
pip-audit:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
timeout-minutes: 10
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
25
|
+
with:
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
28
|
+
- name: Export the lockfile
|
|
29
|
+
run: uv export --frozen --no-hashes --all-extras --no-emit-project -o requirements-audit.txt
|
|
30
|
+
- name: pip-audit
|
|
31
|
+
run: uvx pip-audit==2.10.1 -r requirements-audit.txt --progress-spinner off --desc
|
|
32
|
+
|
|
33
|
+
# Python security lint: medium severity and up fails the job.
|
|
34
|
+
bandit:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
timeout-minutes: 10
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
39
|
+
with:
|
|
40
|
+
persist-credentials: false
|
|
41
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
42
|
+
- name: bandit
|
|
43
|
+
run: uvx bandit==1.9.4 -r src -ll
|
|
44
|
+
|
|
45
|
+
# The workflows themselves: unpinned actions, credential leaks, template injection.
|
|
46
|
+
zizmor:
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
timeout-minutes: 10
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
51
|
+
with:
|
|
52
|
+
persist-credentials: false
|
|
53
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
54
|
+
- name: zizmor
|
|
55
|
+
run: uvx zizmor==1.31.1 --format plain .github/workflows
|
|
56
|
+
env:
|
|
57
|
+
GH_TOKEN: ${{ github.token }}
|
|
58
|
+
|
|
59
|
+
# Dependencies a pull request adds or upgrades, checked against GitHub's advisory database.
|
|
60
|
+
dependency-review:
|
|
61
|
+
if: github.event_name == 'pull_request'
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
timeout-minutes: 10
|
|
64
|
+
steps:
|
|
65
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
66
|
+
with:
|
|
67
|
+
persist-credentials: false
|
|
68
|
+
- uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
|
|
69
|
+
with:
|
|
70
|
+
fail-on-severity: moderate
|