vis-agent 0.2.30__tar.gz → 0.2.32.dev7313__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.
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/PKG-INFO +1 -1
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/gateway.json +18 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/pyproject.toml +1 -1
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/_contracts.py +0 -1
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_client.py +13 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/extension_package.py +21 -4
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_authoring.py +1 -1
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_contracts.py +3 -3
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_extension_package.py +17 -3
- vis_agent-0.2.30/contracts/fixtures/plans.json +0 -117
- vis_agent-0.2.30/contracts/schema/plans.json +0 -79
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/.gitignore +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/LICENSE +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/README.md +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-arguments.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-cases.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-copy.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-execution.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-groups.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-read-session.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-reads.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-results.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-tables.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/diff.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/live-primitives.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/session-health.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/view.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/activity.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/agents.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/automations.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/common.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/config.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/content.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/council.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/diff.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/improve.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/provider.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/rooms.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/symbol.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/toggle.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/view.json +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/examples/greeter/tests/test_greeter.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/hatch_build.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/__init__.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/_outside.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/_wire.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/activity.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/__init__.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_agent.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_agents.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_council.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_extensions.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_local.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/extension.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/py.typed +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/rooms.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/views.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/conftest.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_activity.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agent.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agent_extension_lifecycle.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agent_extensions.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agents.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_api_guides.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_catalog.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_catalog_recipe.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_ci_report_recipe.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_client.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_client_extensions_engine.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_code_quality_recipe.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_council.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_declarations.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_engine.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_engine_docstrings.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_extension_reference.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_gateway_performance.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_goals.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_live_primitives.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_live_wait.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_local.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_method_typing.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_monitor_recipe.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_namespace.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_outside.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_providers.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_record_arguments.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_registration.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_repair_hooks.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_result_sequence.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_rooms.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_scoped_settings.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_sdk_bootstrap.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_sdk_guide.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_structured_live.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_symbol_contract.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_testing.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_tools.py +0 -0
- {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_views.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vis-agent
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.32.dev7313
|
|
4
4
|
Summary: The Vis Python SDK — author extensions and control local or remote engines.
|
|
5
5
|
Project-URL: Homepage, https://vis.blockether.com
|
|
6
6
|
Project-URL: Documentation, https://vis.blockether.com
|
|
@@ -896,6 +896,16 @@
|
|
|
896
896
|
},
|
|
897
897
|
"path": "/v1/sessions/:sid/model"
|
|
898
898
|
},
|
|
899
|
+
{
|
|
900
|
+
"audience": "sdk",
|
|
901
|
+
"operations": {
|
|
902
|
+
"post": {
|
|
903
|
+
"request": "none",
|
|
904
|
+
"response": "json"
|
|
905
|
+
}
|
|
906
|
+
},
|
|
907
|
+
"path": "/v1/sessions/:sid/queue/send-now"
|
|
908
|
+
},
|
|
899
909
|
{
|
|
900
910
|
"audience": "sdk",
|
|
901
911
|
"operations": {
|
|
@@ -2331,6 +2341,10 @@
|
|
|
2331
2341
|
"const": "turn.failed",
|
|
2332
2342
|
"x-vis-turn-terminal": true
|
|
2333
2343
|
},
|
|
2344
|
+
{
|
|
2345
|
+
"const": "turn.input",
|
|
2346
|
+
"x-vis-turn-stream": true
|
|
2347
|
+
},
|
|
2334
2348
|
{
|
|
2335
2349
|
"const": "turn.progress",
|
|
2336
2350
|
"x-vis-turn-stream": true
|
|
@@ -2347,6 +2361,10 @@
|
|
|
2347
2361
|
"const": "turn.queued.drained",
|
|
2348
2362
|
"x-vis-queue-mirror": true
|
|
2349
2363
|
},
|
|
2364
|
+
{
|
|
2365
|
+
"const": "turn.queued.sent",
|
|
2366
|
+
"x-vis-queue-mirror": true
|
|
2367
|
+
},
|
|
2350
2368
|
{
|
|
2351
2369
|
"const": "turn.queued.updated",
|
|
2352
2370
|
"x-vis-queue-mirror": true
|
|
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
|
|
|
8
8
|
|
|
9
9
|
[project]
|
|
10
10
|
name = "vis-agent"
|
|
11
|
-
version = "0.2.
|
|
11
|
+
version = "0.2.32.dev7313"
|
|
12
12
|
description = "The Vis Python SDK — author extensions and control local or remote engines."
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
requires-python = ">=3.11"
|
|
@@ -1621,6 +1621,19 @@ class ExecutionLayer(ABC):
|
|
|
1621
1621
|
)
|
|
1622
1622
|
return response.json()
|
|
1623
1623
|
|
|
1624
|
+
def post_session_queue_send_now(
|
|
1625
|
+
self, sid: str, *, query: Query | None = None, timeout: float | None = None
|
|
1626
|
+
) -> JSONValue:
|
|
1627
|
+
"""POST /v1/sessions/:sid/queue/send-now — json response."""
|
|
1628
|
+
response = self._request(
|
|
1629
|
+
"POST",
|
|
1630
|
+
"/v1/sessions/:sid/queue/send-now",
|
|
1631
|
+
path={"sid": sid},
|
|
1632
|
+
query=query,
|
|
1633
|
+
timeout=timeout,
|
|
1634
|
+
)
|
|
1635
|
+
return response.json()
|
|
1636
|
+
|
|
1624
1637
|
def put_session_read(
|
|
1625
1638
|
self,
|
|
1626
1639
|
sid: str,
|
|
@@ -55,6 +55,22 @@ def _relative(value):
|
|
|
55
55
|
return value
|
|
56
56
|
|
|
57
57
|
|
|
58
|
+
def _skill(entry):
|
|
59
|
+
"""Normalize a skills entry: a directory, or a table with path and settings."""
|
|
60
|
+
if isinstance(entry, str):
|
|
61
|
+
return {"path": _relative(entry), "settings": True}
|
|
62
|
+
if (
|
|
63
|
+
not isinstance(entry, dict)
|
|
64
|
+
or "path" not in entry
|
|
65
|
+
or set(entry) - {"path", "settings"}
|
|
66
|
+
):
|
|
67
|
+
raise ValueError("A skills table needs path and accepts only path and settings")
|
|
68
|
+
settings = entry.get("settings", True)
|
|
69
|
+
if not isinstance(settings, bool):
|
|
70
|
+
raise ValueError("skills settings must be true or false")
|
|
71
|
+
return {"path": _relative(entry["path"]), "settings": settings}
|
|
72
|
+
|
|
73
|
+
|
|
58
74
|
def project_subdirectory(value=""):
|
|
59
75
|
"""An empty value or dot selects the repository root. Otherwise, use a portable path."""
|
|
60
76
|
return "" if value in ("", ".") else _relative(value)
|
|
@@ -131,7 +147,8 @@ def manifest_metadata(text, vis_version=None, python_version=None):
|
|
|
131
147
|
|
|
132
148
|
Returns:
|
|
133
149
|
A metadata dictionary containing normalized name and version, description,
|
|
134
|
-
category, Python requirement, dependencies, source paths and skill
|
|
150
|
+
category, Python requirement, dependencies, source paths and skills. Each skill
|
|
151
|
+
is a `path` and a `settings` flag; False keeps the skill out of settings.
|
|
135
152
|
|
|
136
153
|
Raises:
|
|
137
154
|
ValueError: Required metadata, dependency constraints or portable paths
|
|
@@ -182,8 +199,8 @@ def manifest_metadata(text, vis_version=None, python_version=None):
|
|
|
182
199
|
skills = vis.get("skills", [])
|
|
183
200
|
if not isinstance(skills, list) or len(skills) > 64:
|
|
184
201
|
raise ValueError("skills must be a list of at most 64 skill directories")
|
|
185
|
-
skills = [
|
|
186
|
-
if len(
|
|
202
|
+
skills = [_skill(entry) for entry in skills]
|
|
203
|
+
if len({skill["path"] for skill in skills}) != len(skills):
|
|
187
204
|
raise ValueError("skills must not repeat a directory")
|
|
188
205
|
return {
|
|
189
206
|
"name": canonicalize_name(name),
|
|
@@ -233,7 +250,7 @@ def inspect_source(directory, vis_version=None, python_version=None):
|
|
|
233
250
|
resolved = (directory / path).resolve(strict=True)
|
|
234
251
|
if not resolved.is_relative_to(directory) or not resolved.is_dir():
|
|
235
252
|
raise ValueError("source_paths must be directories inside the project")
|
|
236
|
-
for path in metadata["skills"]:
|
|
253
|
+
for path in (entry["path"] for entry in metadata["skills"]):
|
|
237
254
|
skill = directory / path
|
|
238
255
|
if not skill.is_dir() or not (skill / "SKILL.md").is_file():
|
|
239
256
|
raise ValueError(
|
|
@@ -38,7 +38,7 @@ def test_example_manifest_registration_and_domain_behavior(monkeypatch):
|
|
|
38
38
|
)
|
|
39
39
|
metadata = extension_package.inspect_source(EXAMPLE)
|
|
40
40
|
assert metadata["name"] == "vis-greeter"
|
|
41
|
-
assert metadata["skills"] == ["skills/greeting"]
|
|
41
|
+
assert metadata["skills"] == [{"path": "skills/greeting", "settings": True}]
|
|
42
42
|
assert vis._registration["spec"] is None
|
|
43
43
|
runpy.run_path(str(EXAMPLE / "extension.py"))
|
|
44
44
|
declaration = vis._registration["spec"]
|
|
@@ -55,10 +55,10 @@ def test_gateway_routes_and_lease_policy_are_shared():
|
|
|
55
55
|
lease = gateway["x-vis-client-lease"]
|
|
56
56
|
assert 0 < lease["touch_ms"] < lease["keepalive_ms"] < lease["ttl_ms"]
|
|
57
57
|
assert 0 < lease["keepalive_timeout_ms"] < lease["keepalive_ms"]
|
|
58
|
-
assert len(routes) ==
|
|
59
|
-
assert len(operations) ==
|
|
58
|
+
assert len(routes) == 155
|
|
59
|
+
assert len(operations) == 194
|
|
60
60
|
assert Counter(operation["request"] for operation in operations) == {
|
|
61
|
-
"none":
|
|
61
|
+
"none": 125,
|
|
62
62
|
"json": 64,
|
|
63
63
|
"binary": 5,
|
|
64
64
|
}
|
|
@@ -331,8 +331,18 @@ def test_remote_failure_and_invalid_revision_leave_no_installation(
|
|
|
331
331
|
package.install(REPOSITORY, target, trust=True, revision="--upload-pack=bad")
|
|
332
332
|
|
|
333
333
|
|
|
334
|
-
@pytest.mark.parametrize(
|
|
335
|
-
|
|
334
|
+
@pytest.mark.parametrize(
|
|
335
|
+
("skills", "expected"),
|
|
336
|
+
[
|
|
337
|
+
('["skills/greeting"]', [{"path": "skills/greeting", "settings": True}]),
|
|
338
|
+
(
|
|
339
|
+
'[{ path = "skills/greeting", settings = false }]',
|
|
340
|
+
[{"path": "skills/greeting", "settings": False}],
|
|
341
|
+
),
|
|
342
|
+
("[]", []),
|
|
343
|
+
],
|
|
344
|
+
)
|
|
345
|
+
def test_manifest_declares_skills_without_executing_code(tmp_path, skills, expected):
|
|
336
346
|
source = project(tmp_path / "source", MANIFEST + f"skills = {skills}\n")
|
|
337
347
|
skill = source / "skills/greeting"
|
|
338
348
|
skill.mkdir(parents=True)
|
|
@@ -340,7 +350,7 @@ def test_manifest_declares_skills_without_executing_code(tmp_path, skills):
|
|
|
340
350
|
"---\nname: greeting\ndescription: Greet a person.\n---\nRead the tool contract."
|
|
341
351
|
)
|
|
342
352
|
metadata = package.inspect_source(source)
|
|
343
|
-
assert metadata["skills"] ==
|
|
353
|
+
assert metadata["skills"] == expected
|
|
344
354
|
|
|
345
355
|
|
|
346
356
|
@pytest.mark.parametrize(
|
|
@@ -350,6 +360,10 @@ def test_manifest_declares_skills_without_executing_code(tmp_path, skills):
|
|
|
350
360
|
'["../outside"]',
|
|
351
361
|
'["skills/a", "skills/a"]',
|
|
352
362
|
'["/absolute"]',
|
|
363
|
+
"[{ settings = false }]",
|
|
364
|
+
'[{ path = "skills/a", settings = "no" }]',
|
|
365
|
+
'[{ path = "skills/a", hidden = true }]',
|
|
366
|
+
'["skills/a", { path = "skills/a" }]',
|
|
353
367
|
],
|
|
354
368
|
)
|
|
355
369
|
def test_invalid_skill_declarations_are_rejected(skills):
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"documents": [
|
|
3
|
-
{
|
|
4
|
-
"filename": "PLAN-search.md",
|
|
5
|
-
"text": "# Search\n\n**Feature:** search\n**Status:** ready\n\n## Spec\nFind sessions.\n",
|
|
6
|
-
"expected": {
|
|
7
|
-
"kind": "plan",
|
|
8
|
-
"feature": "search",
|
|
9
|
-
"status": "ready"
|
|
10
|
-
},
|
|
11
|
-
"actions": [
|
|
12
|
-
"approve"
|
|
13
|
-
]
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"filename": "PLAN-search.md",
|
|
17
|
-
"text": "# Search\n**Feature:** search\n**Status:** accepted\n",
|
|
18
|
-
"expected": {
|
|
19
|
-
"kind": "plan",
|
|
20
|
-
"feature": "search",
|
|
21
|
-
"status": "accepted"
|
|
22
|
-
},
|
|
23
|
-
"actions": [
|
|
24
|
-
"approve"
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"filename": "IMPLEMENTATION-search.md",
|
|
29
|
-
"text": "# Search\n**Feature:** search\n**Status:** implementing\n",
|
|
30
|
-
"expected": {
|
|
31
|
-
"kind": "implementation",
|
|
32
|
-
"feature": "search",
|
|
33
|
-
"status": "implementing"
|
|
34
|
-
},
|
|
35
|
-
"actions": []
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"filename": "PLAN-search.md",
|
|
39
|
-
"text": "# Search\n**Feature:** search\n**Status:** in-review\n",
|
|
40
|
-
"expected": {
|
|
41
|
-
"kind": "plan",
|
|
42
|
-
"feature": "search",
|
|
43
|
-
"status": "in-review"
|
|
44
|
-
},
|
|
45
|
-
"actions": []
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"filename": "notes.md",
|
|
49
|
-
"text": "# Search\n**Feature:** search\n**Status:** ready\n",
|
|
50
|
-
"expected": null,
|
|
51
|
-
"actions": []
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"filename": "PLAN-search.md",
|
|
55
|
-
"text": "# Search\n**Feature:** other\n**Status:** ready\n",
|
|
56
|
-
"expected": null,
|
|
57
|
-
"actions": []
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
"filename": "PLAN-search.md",
|
|
61
|
-
"text": "# Search\n**Feature:** search\n**Status:** ready\n**Status:** accepted\n",
|
|
62
|
-
"expected": null,
|
|
63
|
-
"actions": []
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"filename": "PLAN-search.md",
|
|
67
|
-
"text": "# Search\n## Spec\n**Feature:** search\n**Status:** ready\n",
|
|
68
|
-
"expected": null,
|
|
69
|
-
"actions": []
|
|
70
|
-
}
|
|
71
|
-
],
|
|
72
|
-
"annotations": [
|
|
73
|
-
{
|
|
74
|
-
"body": "# Plan\n\n## Resolved comments\n\n- **Whole document** — Earlier remark\n - Resolved in v2: Kept.",
|
|
75
|
-
"comments": [
|
|
76
|
-
{
|
|
77
|
-
"quote": "",
|
|
78
|
-
"body": "Keep the review separate."
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"quote": "A “passage”\n here",
|
|
82
|
-
"body": "A\n decision."
|
|
83
|
-
}
|
|
84
|
-
],
|
|
85
|
-
"rendered": "# Plan\n\n## Resolved comments\n\n- **Whole document** — Earlier remark\n - Resolved in v2: Kept.\n\n## Comments\n\n- **Whole document** — Keep the review separate.\n- **“A \"passage\" here”** — A decision.\n"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"body": "# Plan\n\n",
|
|
89
|
-
"comments": [
|
|
90
|
-
{
|
|
91
|
-
"quote": "x",
|
|
92
|
-
"body": " "
|
|
93
|
-
}
|
|
94
|
-
],
|
|
95
|
-
"rendered": "# Plan\n"
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
"body": "# Plan",
|
|
99
|
-
"comments": [],
|
|
100
|
-
"rendered": "# Plan\n"
|
|
101
|
-
}
|
|
102
|
-
],
|
|
103
|
-
"unrecognized": [
|
|
104
|
-
"# Plan\n\n## Comments\n\nOrdinary prose.\n",
|
|
105
|
-
"# Plan\n\n## Resolved comments\n\nDecisions.\n"
|
|
106
|
-
],
|
|
107
|
-
"quotes": [
|
|
108
|
-
{
|
|
109
|
-
"input": " A “quote”\n with spaces ",
|
|
110
|
-
"expected": "A \"quote\" with spaces"
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
"input": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
114
|
-
"expected": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa…aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
115
|
-
}
|
|
116
|
-
]
|
|
117
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://contract.blockether.com/vis/schema/plans.json",
|
|
4
|
-
"$ref": "#/$defs/document",
|
|
5
|
-
"$defs": {
|
|
6
|
-
"filename": {
|
|
7
|
-
"type": "string",
|
|
8
|
-
"pattern": "^(PLAN|IMPLEMENTATION)-([a-z0-9]+(?:-[a-z0-9]+)*)\\.md$"
|
|
9
|
-
},
|
|
10
|
-
"status": {
|
|
11
|
-
"type": "string",
|
|
12
|
-
"enum": [
|
|
13
|
-
"draft",
|
|
14
|
-
"in-review",
|
|
15
|
-
"ready",
|
|
16
|
-
"accepted",
|
|
17
|
-
"implementing",
|
|
18
|
-
"done"
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
|
-
"document": {
|
|
22
|
-
"type": "object",
|
|
23
|
-
"additionalProperties": false,
|
|
24
|
-
"required": [
|
|
25
|
-
"kind",
|
|
26
|
-
"feature",
|
|
27
|
-
"status"
|
|
28
|
-
],
|
|
29
|
-
"properties": {
|
|
30
|
-
"kind": {
|
|
31
|
-
"enum": [
|
|
32
|
-
"plan",
|
|
33
|
-
"implementation"
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
"feature": {
|
|
37
|
-
"type": "string",
|
|
38
|
-
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
39
|
-
},
|
|
40
|
-
"status": {
|
|
41
|
-
"$ref": "#/$defs/status"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
"action": {
|
|
46
|
-
"oneOf": [
|
|
47
|
-
{
|
|
48
|
-
"const": "revise",
|
|
49
|
-
"x-vis-request": "Revise this document, resolve every human comment and attach the next version under the same filename. Do not implement or change project files."
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"const": "approve",
|
|
53
|
-
"x-vis-request": "I approve this specification and its implementation plan. Start implementation now. Check that this is the latest version, its status is ready or accepted, and no questions or comments remain before editing. If not, stop and explain what needs review. Otherwise start implementation of this exact reviewed scope, keep the versioned implementation record current and follow existing verification and permission rules."
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
},
|
|
57
|
-
"action_request": {
|
|
58
|
-
"type": "object",
|
|
59
|
-
"additionalProperties": false,
|
|
60
|
-
"required": [
|
|
61
|
-
"filename",
|
|
62
|
-
"version",
|
|
63
|
-
"action"
|
|
64
|
-
],
|
|
65
|
-
"properties": {
|
|
66
|
-
"filename": {
|
|
67
|
-
"$ref": "#/$defs/filename"
|
|
68
|
-
},
|
|
69
|
-
"version": {
|
|
70
|
-
"type": "integer",
|
|
71
|
-
"minimum": 1
|
|
72
|
-
},
|
|
73
|
-
"action": {
|
|
74
|
-
"$ref": "#/$defs/action"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
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
|
|
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
|
|
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
|
|
File without changes
|