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.
Files changed (99) hide show
  1. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/PKG-INFO +1 -1
  2. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/gateway.json +18 -0
  3. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/pyproject.toml +1 -1
  4. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/_contracts.py +0 -1
  5. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_client.py +13 -0
  6. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/extension_package.py +21 -4
  7. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_authoring.py +1 -1
  8. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_contracts.py +3 -3
  9. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_extension_package.py +17 -3
  10. vis_agent-0.2.30/contracts/fixtures/plans.json +0 -117
  11. vis_agent-0.2.30/contracts/schema/plans.json +0 -79
  12. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/.gitignore +0 -0
  13. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/LICENSE +0 -0
  14. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/README.md +0 -0
  15. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-arguments.json +0 -0
  16. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-cases.json +0 -0
  17. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-copy.json +0 -0
  18. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-execution.json +0 -0
  19. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-groups.json +0 -0
  20. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-read-session.json +0 -0
  21. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-reads.json +0 -0
  22. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-results.json +0 -0
  23. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity-tables.json +0 -0
  24. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/activity.json +0 -0
  25. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/diff.json +0 -0
  26. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/live-primitives.json +0 -0
  27. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/session-health.json +0 -0
  28. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/fixtures/view.json +0 -0
  29. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/activity.json +0 -0
  30. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/agents.json +0 -0
  31. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/automations.json +0 -0
  32. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/common.json +0 -0
  33. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/config.json +0 -0
  34. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/content.json +0 -0
  35. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/council.json +0 -0
  36. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/diff.json +0 -0
  37. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/improve.json +0 -0
  38. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/provider.json +0 -0
  39. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/rooms.json +0 -0
  40. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/symbol.json +0 -0
  41. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/toggle.json +0 -0
  42. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/contracts/schema/view.json +0 -0
  43. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/examples/greeter/tests/test_greeter.py +0 -0
  44. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/hatch_build.py +0 -0
  45. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/__init__.py +0 -0
  46. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/_outside.py +0 -0
  47. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/_wire.py +0 -0
  48. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/activity.py +0 -0
  49. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/__init__.py +0 -0
  50. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_agent.py +0 -0
  51. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_agents.py +0 -0
  52. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_council.py +0 -0
  53. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_extensions.py +0 -0
  54. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/engine/_local.py +0 -0
  55. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/extension.py +0 -0
  56. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/py.typed +0 -0
  57. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/rooms.py +0 -0
  58. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/src/blockether/vis/views.py +0 -0
  59. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/conftest.py +0 -0
  60. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_activity.py +0 -0
  61. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agent.py +0 -0
  62. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agent_extension_lifecycle.py +0 -0
  63. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agent_extensions.py +0 -0
  64. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_agents.py +0 -0
  65. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_api_guides.py +0 -0
  66. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_catalog.py +0 -0
  67. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_catalog_recipe.py +0 -0
  68. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_ci_report_recipe.py +0 -0
  69. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_client.py +0 -0
  70. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_client_extensions_engine.py +0 -0
  71. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_code_quality_recipe.py +0 -0
  72. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_council.py +0 -0
  73. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_declarations.py +0 -0
  74. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_engine.py +0 -0
  75. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_engine_docstrings.py +0 -0
  76. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_extension_reference.py +0 -0
  77. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_gateway_performance.py +0 -0
  78. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_goals.py +0 -0
  79. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_live_primitives.py +0 -0
  80. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_live_wait.py +0 -0
  81. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_local.py +0 -0
  82. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_method_typing.py +0 -0
  83. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_monitor_recipe.py +0 -0
  84. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_namespace.py +0 -0
  85. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_outside.py +0 -0
  86. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_providers.py +0 -0
  87. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_record_arguments.py +0 -0
  88. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_registration.py +0 -0
  89. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_repair_hooks.py +0 -0
  90. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_result_sequence.py +0 -0
  91. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_rooms.py +0 -0
  92. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_scoped_settings.py +0 -0
  93. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_sdk_bootstrap.py +0 -0
  94. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_sdk_guide.py +0 -0
  95. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_structured_live.py +0 -0
  96. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_symbol_contract.py +0 -0
  97. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_testing.py +0 -0
  98. {vis_agent-0.2.30 → vis_agent-0.2.32.dev7313}/tests/test_tools.py +0 -0
  99. {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.30
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.30"
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"
@@ -20,7 +20,6 @@ _SCHEMA_NAMES = (
20
20
  "diff",
21
21
  "gateway",
22
22
  "improve",
23
- "plans",
24
23
  "provider",
25
24
  "rooms",
26
25
  "symbol",
@@ -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 paths.
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 = [_relative(p) for p in skills]
186
- if len(set(skills)) != len(skills):
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) == 154
59
- assert len(operations) == 193
58
+ assert len(routes) == 155
59
+ assert len(operations) == 194
60
60
  assert Counter(operation["request"] for operation in operations) == {
61
- "none": 124,
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("skills", ['["skills/greeting"]', "[]"])
335
- def test_manifest_declares_skills_without_executing_code(tmp_path, skills):
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"] == (["skills/greeting"] if skills != "[]" else [])
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