plexus-mesh 0.2.2__tar.gz → 0.3.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.
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/PKG-INFO +6 -2
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/README.md +5 -1
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/pyproject.toml +1 -1
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/__init__.py +1 -1
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus_mesh.egg-info/PKG-INFO +6 -2
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus_mesh.egg-info/SOURCES.txt +2 -0
- plexus_mesh-0.3.0/tests/test_client_package.py +173 -0
- plexus_mesh-0.3.0/tests/test_native_workflow_gate.py +17 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_release_metadata.py +2 -2
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/LICENSE +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/setup.cfg +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/__main__.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/cli.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/graph.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/manifest.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/mcp.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/mesh.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/plan.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/receipt.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/registry.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus/run.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus_mesh.egg-info/dependency_links.txt +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus_mesh.egg-info/entry_points.txt +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus_mesh.egg-info/requires.txt +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/src/plexus_mesh.egg-info/top_level.txt +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_extended_registry.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_flagship_interop_roles.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_mneme_contract.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_plexus_core.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_plexus_cycle9.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_plexus_grounding.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_plexus_manifests.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_plexus_mcp.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_plexus_receipt.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_plexus_render.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_qcr_replay_routing.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_release_install_recipes.py +0 -0
- {plexus_mesh-0.2.2 → plexus_mesh-0.3.0}/tests/test_repo_art.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plexus-mesh
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Declarative capability discovery + auto-wiring for agent toolchains: point it at tool manifests and it wires producer to consumer into an executable pipeline, every discovery edge tagged declared and citing the module its producer names. Discovery does not import or run cited tools; optional explicit probe helpers can launch owned MCP servers. Zero runtime dependencies.
|
|
5
5
|
Author: Zain Dana Harper
|
|
6
6
|
License-Expression: LicenseRef-FSL-1.1-MIT
|
|
@@ -119,7 +119,7 @@ GitHub-only release install for 0.2.1 on native PowerShell:
|
|
|
119
119
|
}
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
`plexus-mesh` is
|
|
122
|
+
`plexus-mesh` 0.2.2 is published on PyPI; install it with `python -m pip install plexus-mesh`. The GitHub wheel recipes above retain the available 0.2.1 GitHub Release assets. A source branch or
|
|
123
123
|
CI run is not a release; install from the GitHub `v0.2.1` assets only after the
|
|
124
124
|
wheel, sdist, and `SHA256SUMS.txt` are attached to that release.
|
|
125
125
|
|
|
@@ -376,3 +376,7 @@ The long form of this belief: [The Unbundling](https://github.com/HarperZ9/flywh
|
|
|
376
376
|
---
|
|
377
377
|
|
|
378
378
|
**[Zentropy Labs](https://github.com/ZentropyLabs-ai)** · order out of entropy. An independent lab building evidence-first tools that leave a re-checkable artifact behind. Built by Zain Dana Harper in Seattle. The full workbench is at [Project Telos](https://harperz9.github.io).
|
|
379
|
+
|
|
380
|
+
## 0.3.0 local client distribution candidate
|
|
381
|
+
|
|
382
|
+
The additional [client package](client-plugin/README.md) includes portable plugin metadata and a Windows x64 MCPB/ZIP build. The source version is 0.3.0; these client packages remain unpublished candidates. Existing release installation commands above retain their released version. Native packages carry their Python runtime. No publisher backend is required.
|
|
@@ -100,7 +100,7 @@ GitHub-only release install for 0.2.1 on native PowerShell:
|
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
`plexus-mesh` is
|
|
103
|
+
`plexus-mesh` 0.2.2 is published on PyPI; install it with `python -m pip install plexus-mesh`. The GitHub wheel recipes above retain the available 0.2.1 GitHub Release assets. A source branch or
|
|
104
104
|
CI run is not a release; install from the GitHub `v0.2.1` assets only after the
|
|
105
105
|
wheel, sdist, and `SHA256SUMS.txt` are attached to that release.
|
|
106
106
|
|
|
@@ -357,3 +357,7 @@ The long form of this belief: [The Unbundling](https://github.com/HarperZ9/flywh
|
|
|
357
357
|
---
|
|
358
358
|
|
|
359
359
|
**[Zentropy Labs](https://github.com/ZentropyLabs-ai)** · order out of entropy. An independent lab building evidence-first tools that leave a re-checkable artifact behind. Built by Zain Dana Harper in Seattle. The full workbench is at [Project Telos](https://harperz9.github.io).
|
|
360
|
+
|
|
361
|
+
## 0.3.0 local client distribution candidate
|
|
362
|
+
|
|
363
|
+
The additional [client package](client-plugin/README.md) includes portable plugin metadata and a Windows x64 MCPB/ZIP build. The source version is 0.3.0; these client packages remain unpublished candidates. Existing release installation commands above retain their released version. Native packages carry their Python runtime. No publisher backend is required.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "plexus-mesh"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Declarative capability discovery + auto-wiring for agent toolchains: point it at tool manifests and it wires producer to consumer into an executable pipeline, every discovery edge tagged declared and citing the module its producer names. Discovery does not import or run cited tools; optional explicit probe helpers can launch owned MCP servers. Zero runtime dependencies."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plexus-mesh
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Declarative capability discovery + auto-wiring for agent toolchains: point it at tool manifests and it wires producer to consumer into an executable pipeline, every discovery edge tagged declared and citing the module its producer names. Discovery does not import or run cited tools; optional explicit probe helpers can launch owned MCP servers. Zero runtime dependencies.
|
|
5
5
|
Author: Zain Dana Harper
|
|
6
6
|
License-Expression: LicenseRef-FSL-1.1-MIT
|
|
@@ -119,7 +119,7 @@ GitHub-only release install for 0.2.1 on native PowerShell:
|
|
|
119
119
|
}
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
`plexus-mesh` is
|
|
122
|
+
`plexus-mesh` 0.2.2 is published on PyPI; install it with `python -m pip install plexus-mesh`. The GitHub wheel recipes above retain the available 0.2.1 GitHub Release assets. A source branch or
|
|
123
123
|
CI run is not a release; install from the GitHub `v0.2.1` assets only after the
|
|
124
124
|
wheel, sdist, and `SHA256SUMS.txt` are attached to that release.
|
|
125
125
|
|
|
@@ -376,3 +376,7 @@ The long form of this belief: [The Unbundling](https://github.com/HarperZ9/flywh
|
|
|
376
376
|
---
|
|
377
377
|
|
|
378
378
|
**[Zentropy Labs](https://github.com/ZentropyLabs-ai)** · order out of entropy. An independent lab building evidence-first tools that leave a re-checkable artifact behind. Built by Zain Dana Harper in Seattle. The full workbench is at [Project Telos](https://harperz9.github.io).
|
|
379
|
+
|
|
380
|
+
## 0.3.0 local client distribution candidate
|
|
381
|
+
|
|
382
|
+
The additional [client package](client-plugin/README.md) includes portable plugin metadata and a Windows x64 MCPB/ZIP build. The source version is 0.3.0; these client packages remain unpublished candidates. Existing release installation commands above retain their released version. Native packages carry their Python runtime. No publisher backend is required.
|
|
@@ -18,9 +18,11 @@ src/plexus_mesh.egg-info/dependency_links.txt
|
|
|
18
18
|
src/plexus_mesh.egg-info/entry_points.txt
|
|
19
19
|
src/plexus_mesh.egg-info/requires.txt
|
|
20
20
|
src/plexus_mesh.egg-info/top_level.txt
|
|
21
|
+
tests/test_client_package.py
|
|
21
22
|
tests/test_extended_registry.py
|
|
22
23
|
tests/test_flagship_interop_roles.py
|
|
23
24
|
tests/test_mneme_contract.py
|
|
25
|
+
tests/test_native_workflow_gate.py
|
|
24
26
|
tests/test_plexus_core.py
|
|
25
27
|
tests/test_plexus_cycle9.py
|
|
26
28
|
tests/test_plexus_grounding.py
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""Client artifact and actual stdio controls, using only synthetic paths."""
|
|
2
|
+
import importlib.util
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
import zipfile
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
13
|
+
TOOL = 'plexus'
|
|
14
|
+
sys.path.insert(0, str(ROOT / 'scripts'))
|
|
15
|
+
from build_client_package import archive, build, entries, manifests, qualify
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def invoke(script, tmp_path, requests, extra_env=None, args=()):
|
|
19
|
+
env = {k: v for k, v in os.environ.items() if k.upper() in {'SYSTEMROOT','WINDIR','TEMP','TMP','SYSTEMDRIVE'}}
|
|
20
|
+
env.update(HOME=str(tmp_path), USERPROFILE=str(tmp_path), LOCALAPPDATA=str(tmp_path), APPDATA=str(tmp_path),
|
|
21
|
+
MNEME_STATE=str(tmp_path / 'synthetic.db'), RELAY_MCP_ROOT=str(tmp_path),
|
|
22
|
+
RELAY_ALLOW_WRITE='1', RELAY_ALLOW_EXEC='1')
|
|
23
|
+
env.update(extra_env or {})
|
|
24
|
+
command = [str(script)] if script.suffix == '.exe' else [sys.executable, '-I', '-S', str(script)]
|
|
25
|
+
return subprocess.run([*command,*args], input=''.join(json.dumps(r)+'\n' for r in requests),
|
|
26
|
+
capture_output=True, text=True, env=env, cwd=tmp_path, timeout=30)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def request(mid, method, **params):
|
|
30
|
+
return {'jsonrpc':'2.0', 'id':mid, 'method':method, 'params':params}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.fixture
|
|
34
|
+
def packaged(tmp_path):
|
|
35
|
+
archive_path = build(tmp_path / 'output')[0]
|
|
36
|
+
target = tmp_path / 'extracted'
|
|
37
|
+
with zipfile.ZipFile(archive_path) as z:
|
|
38
|
+
z.extractall(target)
|
|
39
|
+
return target
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_stdio_identity_and_unknown(packaged, tmp_path):
|
|
43
|
+
p = invoke(packaged / 'server/serve.py', tmp_path, [request(1,'initialize'),
|
|
44
|
+
request(2,'tools/list'), request(3,'tools/call',name=TOOL+'.status',arguments={}),
|
|
45
|
+
request(4,'tools/call',name='destroy_everything',arguments={})])
|
|
46
|
+
assert p.returncode == 0, p.stderr
|
|
47
|
+
rows = [json.loads(s) for s in p.stdout.splitlines()]
|
|
48
|
+
assert rows[0]['result']['serverInfo']['version'] == qualify('dev')[0]
|
|
49
|
+
assert rows[1]['result']['tools']
|
|
50
|
+
assert not rows[2].get('error') and not rows[2]['result'].get('isError')
|
|
51
|
+
assert rows[3].get('error') or rows[3]['result'].get('isError')
|
|
52
|
+
assert not (tmp_path/'synthetic.db').exists()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_bad_launch_argument(packaged, tmp_path):
|
|
56
|
+
p = invoke(packaged/'server/serve.py',tmp_path,[],args=['--grant-all'])
|
|
57
|
+
assert p.returncode != 0 and not p.stdout
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@pytest.mark.skipif(TOOL == 'plexus', reason='Plexus has no mandatory state binding')
|
|
61
|
+
@pytest.mark.parametrize('value',['','relative/path'])
|
|
62
|
+
def test_binding_required(packaged,tmp_path,value):
|
|
63
|
+
key = 'MNEME_STATE' if TOOL == 'mneme' else 'RELAY_MCP_ROOT'
|
|
64
|
+
p = invoke(packaged/'server/serve.py',tmp_path,[],{key:value})
|
|
65
|
+
assert p.returncode != 0 and 'absolute' in p.stderr
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_package_deterministic(tmp_path):
|
|
69
|
+
first=build(tmp_path/'a')[0]; second=build(tmp_path/'b')[0]
|
|
70
|
+
assert first.read_bytes() == second.read_bytes()
|
|
71
|
+
with pytest.raises(FileExistsError):
|
|
72
|
+
build(tmp_path/'a')
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_linked_payload_refused(tmp_path):
|
|
76
|
+
source=tmp_path/'source'; source.mkdir()
|
|
77
|
+
target=tmp_path/'target'; target.mkdir()
|
|
78
|
+
try:
|
|
79
|
+
(source/'link').symlink_to(target,target_is_directory=True)
|
|
80
|
+
except OSError:
|
|
81
|
+
if os.name != 'nt':
|
|
82
|
+
raise
|
|
83
|
+
p=subprocess.run(['cmd','/c','mklink','/J',str(source/'link'),str(target)],capture_output=True)
|
|
84
|
+
assert p.returncode == 0
|
|
85
|
+
with pytest.raises(ValueError,match='linked'):
|
|
86
|
+
entries(source)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_manifest_permissions_and_parity():
|
|
90
|
+
docs=manifests(qualify('dev')[0],True)
|
|
91
|
+
native=json.loads(docs['manifest.json'])
|
|
92
|
+
plugin=json.loads(docs['plugin.json'])
|
|
93
|
+
assert native['version'] == plugin['version']
|
|
94
|
+
assert native['server']['mcp_config']['args'] == []
|
|
95
|
+
assert 'annotations' not in str(docs)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@pytest.mark.skipif(TOOL != 'mneme', reason='Mneme scope')
|
|
99
|
+
def test_memory_write_refused(packaged,tmp_path):
|
|
100
|
+
p=invoke(packaged/'server/serve.py',tmp_path,[request(1,'tools/call',name='mneme.remember',
|
|
101
|
+
arguments={'session':'test','turns':[{'role':'user','text':'synthetic'}]})])
|
|
102
|
+
assert p.returncode == 0
|
|
103
|
+
assert json.loads(p.stdout)['error']
|
|
104
|
+
assert not (tmp_path/'synthetic.db').exists()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@pytest.mark.skipif(TOOL != 'relay', reason='Relay scope')
|
|
108
|
+
def test_relay_environment_cannot_grant(packaged,tmp_path):
|
|
109
|
+
p=invoke(packaged/'server/serve.py',tmp_path,[request(1,'tools/call',name='local_agent_run',
|
|
110
|
+
arguments={'goal':'do not run','root':str(tmp_path),'allow_write':True,'allow_exec':True})])
|
|
111
|
+
assert p.returncode == 0
|
|
112
|
+
row=json.loads(p.stdout)
|
|
113
|
+
assert row['result'].get('isError'),row
|
|
114
|
+
assert 'GRANT' in p.stdout.upper() or 'PERMISSION' in p.stdout.upper() or 'REFUSED' in p.stdout.upper()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@pytest.mark.skipif(TOOL != 'plexus', reason='Plexus scope')
|
|
118
|
+
def test_declarative_discovery(packaged,tmp_path):
|
|
119
|
+
p=invoke(packaged/'server/serve.py',tmp_path,[request(1,'tools/call',name='plexus_discover',arguments={})])
|
|
120
|
+
assert p.returncode == 0
|
|
121
|
+
result=json.loads(json.loads(p.stdout)['result']['content'][0]['text'])
|
|
122
|
+
assert result['organs'] and result['edges']
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_client_root_expansion_is_client_specific():
|
|
126
|
+
docs=manifests(qualify('dev')[0],False)
|
|
127
|
+
assert b'${PLUGIN_ROOT}' in docs['mcp.json']
|
|
128
|
+
assert b'${CLAUDE_PLUGIN_ROOT}' in docs['.mcp.json']
|
|
129
|
+
assert b'${PLUGIN_ROOT}' not in docs['.mcp.json']
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def test_version_drift_refused(tmp_path,monkeypatch):
|
|
133
|
+
import build_client_package as package
|
|
134
|
+
(tmp_path/'pyproject.toml').write_text('[project]\nversion="0.9.0"\n')
|
|
135
|
+
source=tmp_path/'src'/TOOL; source.mkdir(parents=True)
|
|
136
|
+
(source/'__init__.py').write_text('__version__="0.8.0"\n')
|
|
137
|
+
monkeypatch.setattr(package,'ROOT',tmp_path)
|
|
138
|
+
with pytest.raises(ValueError,match='versions differ'):
|
|
139
|
+
package.qualify('dev')
|
|
140
|
+
|
|
141
|
+
@pytest.mark.parametrize('name',['.env','.env.json','state.db','credential.key','secret.token'])
|
|
142
|
+
def test_state_and_credentials_refused_before_archiving(tmp_path,name):
|
|
143
|
+
root=tmp_path/'payload'; root.mkdir()
|
|
144
|
+
(root/name).write_text('synthetic-not-a-secret')
|
|
145
|
+
with pytest.raises(ValueError,match='unsupported package input'):
|
|
146
|
+
entries(root)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def test_unreleased_candidate_cannot_be_packaged_as_release():
|
|
150
|
+
if 'unreleased' in next(line for line in (ROOT/'CHANGELOG.md').read_text().splitlines() if line.startswith('## ')).lower():
|
|
151
|
+
with pytest.raises(ValueError,match='unreleased marker'):
|
|
152
|
+
qualify('release')
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_native_builder_pins_reproducibility_environment(tmp_path,monkeypatch):
|
|
156
|
+
import build_client_package as package
|
|
157
|
+
class StopBeforeBuild(Exception):
|
|
158
|
+
pass
|
|
159
|
+
def capture(command,**kwargs):
|
|
160
|
+
env=kwargs['env']
|
|
161
|
+
assert env['PYTHONHASHSEED']=='0'
|
|
162
|
+
assert env['SOURCE_DATE_EPOCH'].isdigit()
|
|
163
|
+
assert 'SYNTHETIC_SECRET' not in env
|
|
164
|
+
raise StopBeforeBuild
|
|
165
|
+
monkeypatch.setenv('PYTHONHASHSEED','random')
|
|
166
|
+
monkeypatch.setenv('SOURCE_DATE_EPOCH','1')
|
|
167
|
+
monkeypatch.setenv('SYNTHETIC_SECRET','synthetic-not-a-secret')
|
|
168
|
+
monkeypatch.setattr(package.sys,'platform','win32')
|
|
169
|
+
monkeypatch.setattr(package.subprocess,'run',capture)
|
|
170
|
+
monkeypatch.setattr(package,'qualify',lambda mode: ('0.3.0' if TOOL=='plexus' else '0.6.0','synthetic-head'))
|
|
171
|
+
monkeypatch.setattr(package.subprocess,'check_output',lambda *a,**k:'1234567890\n')
|
|
172
|
+
with pytest.raises(StopBeforeBuild):
|
|
173
|
+
package.build(tmp_path/'native-build',native=True)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""A successful-looking protocol response cannot replace workflow evidence."""
|
|
2
|
+
import importlib.util
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from types import SimpleNamespace
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_workflow_rejects_protocol_success_without_effect(tmp_path, monkeypatch):
|
|
10
|
+
path = Path(__file__).resolve().parents[1] / 'scripts/check_native_workflow.py'
|
|
11
|
+
spec = importlib.util.spec_from_file_location('plexus_workflow', path)
|
|
12
|
+
module = importlib.util.module_from_spec(spec); spec.loader.exec_module(module)
|
|
13
|
+
response = {'result': {'content': [{'type': 'text', 'text': json.dumps({'edges': []})}]}}
|
|
14
|
+
monkeypatch.setattr(module.subprocess, 'run', lambda *a, **k:
|
|
15
|
+
SimpleNamespace(returncode=0, stdout=json.dumps(response), stderr=''))
|
|
16
|
+
with pytest.raises(ValueError):
|
|
17
|
+
module.check_workflow(tmp_path / 'fake.exe', tmp_path, {})
|
|
@@ -4,7 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
ROOT = Path(__file__).resolve().parents[1]
|
|
7
|
-
VERSION = "0.
|
|
7
|
+
VERSION = "0.3.0"
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def test_release_identity_is_aligned():
|
|
@@ -27,7 +27,7 @@ def test_install_docs_are_github_only_and_hash_verified():
|
|
|
27
27
|
assert "SHA256SUMS.txt" in readme
|
|
28
28
|
assert "Get-FileHash -Algorithm SHA256" in readme
|
|
29
29
|
assert "Invoke-WebRequest" in readme
|
|
30
|
-
assert "
|
|
30
|
+
assert "`plexus-mesh` 0.2.2 is published on PyPI" in readme
|
|
31
31
|
assert "pip install git+https://github.com/HarperZ9/plexus.git" not in readme
|
|
32
32
|
|
|
33
33
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|