heyasa 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. heyasa-0.1.1/LICENSE +110 -0
  2. heyasa-0.1.1/PKG-INFO +53 -0
  3. heyasa-0.1.1/README.md +33 -0
  4. heyasa-0.1.1/heyasa/__init__.py +31 -0
  5. heyasa-0.1.1/heyasa/__main__.py +8 -0
  6. heyasa-0.1.1/heyasa/cli.py +399 -0
  7. heyasa-0.1.1/heyasa/config.py +138 -0
  8. heyasa-0.1.1/heyasa/engines/__init__.py +2 -0
  9. heyasa-0.1.1/heyasa/engines/base.py +76 -0
  10. heyasa-0.1.1/heyasa/engines/extended_adapters.py +130 -0
  11. heyasa-0.1.1/heyasa/engines/subactor_adapter.py +140 -0
  12. heyasa-0.1.1/heyasa/engines/willman_adapter.py +131 -0
  13. heyasa-0.1.1/heyasa/engines/willpad_adapter.py +135 -0
  14. heyasa-0.1.1/heyasa/hud.py +647 -0
  15. heyasa-0.1.1/heyasa/interfaces/__init__.py +2 -0
  16. heyasa-0.1.1/heyasa/interfaces/grpc_server.py +138 -0
  17. heyasa-0.1.1/heyasa/interfaces/mcp_server.py +182 -0
  18. heyasa-0.1.1/heyasa/interfaces/rest_server.py +148 -0
  19. heyasa-0.1.1/heyasa/router.py +281 -0
  20. heyasa-0.1.1/heyasa/shell.py +223 -0
  21. heyasa-0.1.1/heyasa/standard/__init__.py +2 -0
  22. heyasa-0.1.1/heyasa/standard/api_registry.py +491 -0
  23. heyasa-0.1.1/heyasa/standard/governance.py +157 -0
  24. heyasa-0.1.1/heyasa/standard/nl_pipeline.py +362 -0
  25. heyasa-0.1.1/heyasa/standard/receipts.py +263 -0
  26. heyasa-0.1.1/heyasa.egg-info/PKG-INFO +53 -0
  27. heyasa-0.1.1/heyasa.egg-info/SOURCES.txt +32 -0
  28. heyasa-0.1.1/heyasa.egg-info/dependency_links.txt +1 -0
  29. heyasa-0.1.1/heyasa.egg-info/entry_points.txt +3 -0
  30. heyasa-0.1.1/heyasa.egg-info/requires.txt +15 -0
  31. heyasa-0.1.1/heyasa.egg-info/top_level.txt +1 -0
  32. heyasa-0.1.1/pyproject.toml +45 -0
  33. heyasa-0.1.1/setup.cfg +4 -0
  34. heyasa-0.1.1/tests/test_heyasa.py +242 -0
heyasa-0.1.1/LICENSE ADDED
@@ -0,0 +1,110 @@
1
+ PROPRIETARY AND CONFIDENTIAL SOURCE CODE LICENSE
2
+ STRICT ANTI-AI / ANTI-MINING RESERVATION OF RIGHTS
3
+
4
+ Copyright (c) 2026 Tomasz Sapletta Prototypowanie.pl NIP: 5881918662, REGON: 220665410. All rights reserved.
5
+ Właścicielem oprogramowania jest Tomasz Sapletta Prototypowanie.pl NIP: 5881918662, REGON: 220665410.
6
+
7
+ ================================================================================
8
+ IMPORTANT NOTICE - PROPRIETARY AND CONFIDENTIAL
9
+ ================================================================================
10
+
11
+ This software, source code, documentation, specifications, schemas, models,
12
+ algorithms, and associated digital assets ("the Software") are the confidential
13
+ and proprietary intellectual property of Tomasz Sapletta Prototypowanie.pl
14
+ (NIP: 5881918662, REGON: 220665410) and its licensors.
15
+
16
+ The Software is NOT licensed under any open source, free software, or
17
+ source-available license (such as MIT, Apache 2.0, BSD, GPL, AGPL, BSL, or SSPL).
18
+ All rights not expressly granted under a separate, signed written commercial
19
+ agreement executed by Tomasz Sapletta Prototypowanie.pl are strictly reserved.
20
+
21
+ ================================================================================
22
+ SECTION 1. STRICT PROHIBITION ON ARTIFICIAL INTELLIGENCE & MACHINE LEARNING INGESTION
23
+ ================================================================================
24
+
25
+ Under no circumstances may any portion of the Software, whether in human-readable
26
+ source code, compiled binary, abstract syntax tree (AST), intermediate representation,
27
+ documentation, ticket history, or commit metadata, be:
28
+
29
+ 1.1. Ingested, scraped, crawled, harvested, indexed, tokenized, cached, or stored
30
+ for the purpose of training, pre-training, fine-tuning, evaluating, or weighting
31
+ any artificial intelligence system, machine learning model, large language
32
+ model (LLM), code-generation model, neural network, diffusion model, or
33
+ multimodal model.
34
+
35
+ 1.2. Used by, or fed into the training datasets, prompt contexts, retrieval-augmented
36
+ generation (RAG) stores, vector databases, or telemetry caches of any commercial
37
+ or non-commercial AI system, including but not limited to:
38
+ - GitHub Copilot / Microsoft Copilot (Microsoft Corporation)
39
+ - OpenAI ChatGPT, Codex, GPT-4, GPT-5, o-series, and related APIs (OpenAI Inc.)
40
+ - Google Gemini, PaLM, Codey, Vertex AI, and DeepMind systems (Google LLC / Alphabet)
41
+ - Anthropic Claude, Constitutional AI, and related models (Anthropic PBC)
42
+ - Meta LLaMA, Code Llama, and related foundation models (Meta Platforms, Inc.)
43
+ - Amazon CodeWhisperer, Bedrock, and Titan models (Amazon.com, Inc.)
44
+ - Mistral AI, Cohere, Cursor AI, Tabnine, Replit Ghostwriter, or any automated
45
+ code-synthesis engine or AI coding assistant.
46
+
47
+ 1.3. Processed or analyzed by any automated tool, bot, crawler, or scraper to generate
48
+ synthetic code, code suggestions, autocomplete suggestions, embeddings, or
49
+ derivative software models.
50
+
51
+ ================================================================================
52
+ SECTION 2. STATUTORY RESERVATION OF RIGHTS (EU DIRECTIVE 2019/790)
53
+ ================================================================================
54
+
55
+ 2.1. In accordance with Article 4(3) of Directive (EU) 2019/790 of the European
56
+ Parliament and of the Council on copyright and related rights in the Digital
57
+ Single Market, the rights holder hereby EXPRESSLY RESERVES ALL RIGHTS
58
+ regarding Text and Data Mining (TDM) for this Software, its source repositories,
59
+ documentation, schemas, and all associated materials.
60
+
61
+ 2.2. Any extraction, automated reading, indexing, or reproduction of the Software
62
+ for text and data mining purposes within the meaning of Directive (EU) 2019/790
63
+ is strictly prohibited without prior written authorization from the rights holder.
64
+
65
+ 2.3. This reservation applies worldwide and is declared in machine-readable form
66
+ within the repository metadata, headers, and this License specification.
67
+
68
+ ================================================================================
69
+ SECTION 3. HOSTING & PLATFORM PREEMPTION CLAUSE
70
+ ================================================================================
71
+
72
+ 3.1. The presence of this source code or repository on any third-party hosting service,
73
+ code forge, version control platform, or cloud provider (including but not
74
+ limited to GitHub, GitLab, Bitbucket, or AWS) does NOT constitute a waiver,
75
+ license grant, or implied consent to the hosting provider, its parent,
76
+ subsidiaries, or third parties to:
77
+ (a) use the Software for machine learning training, telemetry harvesting, or
78
+ model improvement;
79
+ (b) distribute or reproduce the Software to other users or automated agents;
80
+ (c) index the Software in any public search or retrieval system.
81
+
82
+ 3.2. Any terms of service, platform agreements, or automated licenses purporting
83
+ to grant the platform operator an implied, royalty-free, or transferable
84
+ license to utilize hosted code for artificial intelligence development, model
85
+ training, or feature synthesis are hereby explicitly rejected, preempted,
86
+ and declared null and void with respect to this Software.
87
+
88
+ ================================================================================
89
+ SECTION 4. PROHIBITED USES & RESTRICTIONS
90
+ ================================================================================
91
+
92
+ Except as expressly authorized under a valid, executed commercial enterprise license
93
+ with Tomasz Sapletta Prototypowanie.pl, you may NOT:
94
+ - Copy, modify, adapt, translate, reverse engineer, decompile, or disassemble the Software.
95
+ - Distribute, sublicense, rent, lease, lend, sell, or publicly display the Software.
96
+ - Use the Software to provide competitive time-sharing, SaaS, cloud twin, or virtualization services.
97
+ - Remove, alter, or obscure any proprietary notices, copyright labels, or license files.
98
+
99
+ ================================================================================
100
+ SECTION 5. ENFORCEMENT & REMEDIES
101
+ ================================================================================
102
+
103
+ Any breach of this License, including unauthorized scraping, tokenization, or ingestion
104
+ into an artificial intelligence system, constitutes willful copyright infringement,
105
+ unauthorized access, and breach of contract. Tomasz Sapletta Prototypowanie.pl reserves
106
+ the right to seek immediate injunctive relief, statutory damages, compensation for commercial
107
+ harm, and mandatory destruction of all derivative model weights, embeddings, and training
108
+ caches containing representations of the Software.
109
+
110
+ For licensing inquiries and commercial authorization, contact: tom@prototypowanie.pl / legal@clonerd.com
heyasa-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.4
2
+ Name: heyasa
3
+ Version: 0.1.1
4
+ Summary: Hey Asa — Unified Autonomous CLI Shell & Multi-Protocol Gateway for willman, willpad (willmux), and subactor standardized by wellmanifest/wellman and wellmanifest/nl-*
5
+ Author: Tom Sapletta
6
+ Author-email: Tom Sapletta <tom@sapletta.com>
7
+ License-Expression: Apache-2.0
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Provides-Extra: mcp
12
+ Requires-Dist: mcp>=1.0.0; extra == "mcp"
13
+ Provides-Extra: grpc
14
+ Requires-Dist: grpcio>=1.60.0; extra == "grpc"
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
17
+ Requires-Dist: goal>=2.1.0; python_version >= "3.12" and extra == "dev"
18
+ Requires-Dist: costs>=0.1.53; python_version >= "3.9" and extra == "dev"
19
+ Dynamic: license-file
20
+
21
+ # Hey Asa (`heyasa`)
22
+
23
+ **Unified Autonomous CLI Shell & Multi-Protocol Gateway** dla ekosystemów **`willman`**, **`willpad` (`willmux`)** oraz **`subactor`** (a także wtyczek **`dockuri`** i **`taskand`**), ustandaryzowany przez **`wellmanifest/wellman`**, **`wellmanifest/autonomy`** oraz rodzinę **`wellmanifest/nl-*`** (`nl-dsl-llm`, `nl-uri-dsl-llm`, `nl-api-llm`).
24
+
25
+ ## Główne właściwości
26
+
27
+ - **Jedna nazwa i marka**: `heyasa` (asystent **Asa**, wake phrase: `Hey Asa`).
28
+ - **Wybór silnika autonomicznego (`-e` / `--engine`)**:
29
+ - `auto` (domyślny — deterministyczny klasyfikator intencji `nl-uri-dsl-llm` + `willuri`),
30
+ - `willman` — kolejka zadań DAG, cykl bodźców Koru (`stimulate`), obserwacyjna samonaprawa (`willman.observation-policy/v1`), flota projektów (`ProjectFleet`), artefakty,
31
+ - `willpad` — sterownik przestrzeni roboczej `willmux` (okna `A`–`F`, centralny pad w trybach `quad`/`radial`/`panel`, kompaktowy czat Table 4, narzędzia okien `shot`/`ocr`/`copy`/`record`, plany z zależnościami `chat_plan`/`chat_run`, Rynek),
32
+ - `subactor` — kontraktowa autonomia z `../subactor` (`IntentIR v1` → `ExecutionPlan` → bramka `AQL` → `OQL` → `urirun`, Founder Control `:8091`, `subactor-shell` ACP/SQLite/Vault),
33
+ - `dockuri` — modularne usługi autonomiczne `proc://.../v1` (`QueueHealService`, `SelfImprovementService`, `FinancialIntegrityService`, `ScannerIndexService`),
34
+ - `taskand` — kapsuły wykonawcze `proc://.../v1` i workflowy przeglądarkowe `task2willmux`.
35
+ - **Domyślne poziomy autonomii (`--autonomy`)**:
36
+ - **Tryb interaktywny (TTY / REPL)**: `confirm` — prezentuje plan i oczekuje na zgodę operatora przed wykonaniem mutacji,
37
+ - **Tryb wsadowy / agentowy (non-TTY / batch)**: `execute-once` — wykonuje maksymalnie jeden atomowy cykl i automatycznie wraca do stanu `safe`,
38
+ - Pozostałe tryby: `suggest` (tylko plan / `--dry-run`) oraz `auto` (w ramach jawnego grantu autonomii).
39
+ - **Wieloprotokołowe interfejsy**:
40
+ - `heyasa [polecenie]` / `heyasa shell` — CLI one-shot oraz interaktywny REPL,
41
+ - `heyasa mcp` — serwer MCP (`stdio` oraz `streamable-http` na `:7081`) zgodny z `NUL-015`,
42
+ - `heyasa serve` — zunifikowany serwer REST + SSE (`:7080`),
43
+ - `heyasa grpc` — serwer gRPC (`:7082` oraz UDS),
44
+ - `heyasa acp` — serwer Agent Client Protocol v1 (`stdin/stdout` JSON-RPC),
45
+ - `heyasa open <uri>` — dispatcher RFC 3986 Action URI (`heyasa://`, `willpad://`, `willmux://`, `willman://`, `subactor://`, `proc://`),
46
+ - `heyasa switch <tool|pane|preset|next|prev>` — błyskawiczne przełączanie narzędzi na ekranie (`chat`, `files`, `willman`, `subactor`, `dockuri`, `approval`, presety `ops`/`dev`/`compact`),
47
+ - `heyasa hud [--top|--bottom|--bench|--export-tauri]` — uruchamianie i przełączanie okna HUD (`willmux` / `willman`) zajmującego maksymalnie **50% wysokości ekranu** (Quake-style scratchpad / Tauri v2 Wry / Chromium `--app`).
48
+
49
+
50
+
51
+ ## License
52
+
53
+ Licensed under Apache-2.0.
heyasa-0.1.1/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Hey Asa (`heyasa`)
2
+
3
+ **Unified Autonomous CLI Shell & Multi-Protocol Gateway** dla ekosystemów **`willman`**, **`willpad` (`willmux`)** oraz **`subactor`** (a także wtyczek **`dockuri`** i **`taskand`**), ustandaryzowany przez **`wellmanifest/wellman`**, **`wellmanifest/autonomy`** oraz rodzinę **`wellmanifest/nl-*`** (`nl-dsl-llm`, `nl-uri-dsl-llm`, `nl-api-llm`).
4
+
5
+ ## Główne właściwości
6
+
7
+ - **Jedna nazwa i marka**: `heyasa` (asystent **Asa**, wake phrase: `Hey Asa`).
8
+ - **Wybór silnika autonomicznego (`-e` / `--engine`)**:
9
+ - `auto` (domyślny — deterministyczny klasyfikator intencji `nl-uri-dsl-llm` + `willuri`),
10
+ - `willman` — kolejka zadań DAG, cykl bodźców Koru (`stimulate`), obserwacyjna samonaprawa (`willman.observation-policy/v1`), flota projektów (`ProjectFleet`), artefakty,
11
+ - `willpad` — sterownik przestrzeni roboczej `willmux` (okna `A`–`F`, centralny pad w trybach `quad`/`radial`/`panel`, kompaktowy czat Table 4, narzędzia okien `shot`/`ocr`/`copy`/`record`, plany z zależnościami `chat_plan`/`chat_run`, Rynek),
12
+ - `subactor` — kontraktowa autonomia z `../subactor` (`IntentIR v1` → `ExecutionPlan` → bramka `AQL` → `OQL` → `urirun`, Founder Control `:8091`, `subactor-shell` ACP/SQLite/Vault),
13
+ - `dockuri` — modularne usługi autonomiczne `proc://.../v1` (`QueueHealService`, `SelfImprovementService`, `FinancialIntegrityService`, `ScannerIndexService`),
14
+ - `taskand` — kapsuły wykonawcze `proc://.../v1` i workflowy przeglądarkowe `task2willmux`.
15
+ - **Domyślne poziomy autonomii (`--autonomy`)**:
16
+ - **Tryb interaktywny (TTY / REPL)**: `confirm` — prezentuje plan i oczekuje na zgodę operatora przed wykonaniem mutacji,
17
+ - **Tryb wsadowy / agentowy (non-TTY / batch)**: `execute-once` — wykonuje maksymalnie jeden atomowy cykl i automatycznie wraca do stanu `safe`,
18
+ - Pozostałe tryby: `suggest` (tylko plan / `--dry-run`) oraz `auto` (w ramach jawnego grantu autonomii).
19
+ - **Wieloprotokołowe interfejsy**:
20
+ - `heyasa [polecenie]` / `heyasa shell` — CLI one-shot oraz interaktywny REPL,
21
+ - `heyasa mcp` — serwer MCP (`stdio` oraz `streamable-http` na `:7081`) zgodny z `NUL-015`,
22
+ - `heyasa serve` — zunifikowany serwer REST + SSE (`:7080`),
23
+ - `heyasa grpc` — serwer gRPC (`:7082` oraz UDS),
24
+ - `heyasa acp` — serwer Agent Client Protocol v1 (`stdin/stdout` JSON-RPC),
25
+ - `heyasa open <uri>` — dispatcher RFC 3986 Action URI (`heyasa://`, `willpad://`, `willmux://`, `willman://`, `subactor://`, `proc://`),
26
+ - `heyasa switch <tool|pane|preset|next|prev>` — błyskawiczne przełączanie narzędzi na ekranie (`chat`, `files`, `willman`, `subactor`, `dockuri`, `approval`, presety `ops`/`dev`/`compact`),
27
+ - `heyasa hud [--top|--bottom|--bench|--export-tauri]` — uruchamianie i przełączanie okna HUD (`willmux` / `willman`) zajmującego maksymalnie **50% wysokości ekranu** (Quake-style scratchpad / Tauri v2 Wry / Chromium `--app`).
28
+
29
+
30
+
31
+ ## License
32
+
33
+ Licensed under Apache-2.0.
@@ -0,0 +1,31 @@
1
+ """Hey Asa — Unified Autonomous CLI Shell & Multi-Protocol Gateway."""
2
+ from __future__ import annotations
3
+
4
+ from .hud import (
5
+ HalfScreenWindowManager,
6
+ ScreenGeometry,
7
+ ToolSwitcher,
8
+ compute_half_screen_geometry,
9
+ launch_hud,
10
+ switch_tool,
11
+ )
12
+ from .router import HeyasaRouter
13
+
14
+ __version__ = "0.1.1"
15
+ __brand__ = "heyasa"
16
+ __assistant__ = "Asa"
17
+ __wake_phrase__ = "Hey Asa"
18
+
19
+ __all__ = [
20
+ "__version__",
21
+ "__brand__",
22
+ "__assistant__",
23
+ "__wake_phrase__",
24
+ "HeyasaRouter",
25
+ "ToolSwitcher",
26
+ "HalfScreenWindowManager",
27
+ "ScreenGeometry",
28
+ "compute_half_screen_geometry",
29
+ "switch_tool",
30
+ "launch_hud",
31
+ ]
@@ -0,0 +1,8 @@
1
+ """Entrypoint for `python -m heyasa`."""
2
+ from __future__ import annotations
3
+
4
+ import sys
5
+ from .cli import main
6
+
7
+ if __name__ == "__main__":
8
+ raise SystemExit(main(sys.argv[1:]))
@@ -0,0 +1,399 @@
1
+ """CLI entrypoint for `heyasa` — Unified Autonomous CLI Shell & Multi-Protocol Gateway."""
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import json
6
+ from pathlib import Path
7
+ import sys
8
+ from typing import List, Optional
9
+
10
+ from .config import (
11
+ AUTONOMY_MODES,
12
+ ENGINE_CHOICES,
13
+ PROTOCOL_CHOICES,
14
+ WILLPAD_STYLES,
15
+ WILLPAD_TOOLS,
16
+ HeyasaConfig,
17
+ default_autonomy_mode,
18
+ )
19
+ from .hud import (
20
+ TOOL_TARGETS,
21
+ WINDOW_RUNTIMES_BENCHMARK,
22
+ WORKSPACE_PRESETS,
23
+ HalfScreenWindowManager,
24
+ ToolSwitcher,
25
+ )
26
+ from .interfaces.grpc_server import HEYASA_PROTO_SPEC, HeyasaGrpcService, serve_acp_stdio
27
+ from .interfaces.mcp_server import build_mcp_gateway_manifest, serve_mcp
28
+ from .interfaces.rest_server import serve_rest
29
+ from .router import HeyasaRouter
30
+ from .shell import format_engines_table, run_interactive_shell
31
+ from .standard.governance import run_wellman_governance
32
+
33
+ KNOWN_SUBCOMMANDS = {
34
+ "shell",
35
+ "engines",
36
+ "status",
37
+ "switch",
38
+ "hud",
39
+ "window",
40
+ "willpad",
41
+ "willman",
42
+ "subactor",
43
+ "dockuri",
44
+ "taskand",
45
+ "plan",
46
+ "run",
47
+ "dsl",
48
+ "uri",
49
+ "open",
50
+ "catalog",
51
+ "snapshot",
52
+ "receipts",
53
+ "gov",
54
+ "serve",
55
+ "mcp",
56
+ "grpc",
57
+ "acp",
58
+ }
59
+
60
+
61
+ def build_parser() -> argparse.ArgumentParser:
62
+ parser = argparse.ArgumentParser(
63
+ prog="heyasa",
64
+ description=(
65
+ "Hey Asa (heyasa) — Zunifikowany CLI Shell i brama wieloprotokołowa dla "
66
+ "willman, willpad (willmux), subactor, dockuri i taskand."
67
+ ),
68
+ )
69
+ parser.add_argument(
70
+ "-e",
71
+ "--engine",
72
+ choices=ENGINE_CHOICES,
73
+ default="auto",
74
+ help="Wybór silnika autonomicznego (domyślnie: auto)",
75
+ )
76
+ parser.add_argument(
77
+ "-a",
78
+ "--autonomy",
79
+ choices=AUTONOMY_MODES,
80
+ default=None,
81
+ help="Poziom autonomii: suggest, confirm (domyślny interaktywnie), execute-once (domyślny wsadowo), auto",
82
+ )
83
+ parser.add_argument(
84
+ "-p",
85
+ "--protocol",
86
+ choices=PROTOCOL_CHOICES,
87
+ default="auto",
88
+ help="Preferowany interfejs komunikacji z silnikiem (auto, shell, rest, mcp, grpc, acp, uri)",
89
+ )
90
+ parser.add_argument(
91
+ "-y",
92
+ "--yes",
93
+ action="store_true",
94
+ help="Potwierdź wykonanie planu zmieniającego stan (dla trybu confirm)",
95
+ )
96
+ parser.add_argument(
97
+ "--dry-run",
98
+ action="store_true",
99
+ help="Alias dla --autonomy suggest (tylko kompilacja planu i Action URI bez wykonania)",
100
+ )
101
+ parser.add_argument(
102
+ "--json",
103
+ action="store_true",
104
+ help="Wypisz odpowiedź jako sformatowany JSON",
105
+ )
106
+ return parser
107
+
108
+
109
+ def main(argv: Optional[List[str]] = None) -> int:
110
+ raw_argv = list(sys.argv[1:] if argv is None else argv)
111
+ config = HeyasaConfig()
112
+ router = HeyasaRouter(config)
113
+
114
+ if not raw_argv:
115
+ if sys.stdin and sys.stdin.isatty():
116
+ return run_interactive_shell(router, initial_engine="auto", initial_autonomy="confirm")
117
+ raw_argv = ["status", "--json"]
118
+
119
+ # Parse global flags + positional tokens flexibly so both `heyasa "zdanie"` and `heyasa subcmd ...` work
120
+ parser = build_parser()
121
+ known, rest = parser.parse_known_args(raw_argv)
122
+
123
+ autonomy = "suggest" if known.dry_run else (known.autonomy or default_autonomy_mode())
124
+ engine = known.engine
125
+ protocol = known.protocol
126
+ confirmed = known.yes
127
+
128
+ if not rest:
129
+ return run_interactive_shell(
130
+ router,
131
+ initial_engine=engine,
132
+ initial_autonomy=autonomy,
133
+ initial_protocol=protocol,
134
+ )
135
+
136
+ subcmd = rest[0]
137
+ sub_args = rest[1:]
138
+
139
+ if subcmd == "shell":
140
+ return run_interactive_shell(
141
+ router,
142
+ initial_engine=engine,
143
+ initial_autonomy=known.autonomy or "confirm",
144
+ initial_protocol=protocol,
145
+ )
146
+
147
+ if subcmd in ("engines", "status"):
148
+ statuses = router.list_engines_status()
149
+ if known.json:
150
+ print(
151
+ json.dumps(
152
+ {
153
+ "schema": "heyasa.status/v1",
154
+ "brand": "heyasa",
155
+ "assistant": "Asa",
156
+ "wake_phrase": "Hey Asa",
157
+ "default_autonomy_interactive": "confirm",
158
+ "default_autonomy_batch": "execute-once",
159
+ "active_autonomy": autonomy,
160
+ "engines": statuses,
161
+ },
162
+ ensure_ascii=False,
163
+ indent=2,
164
+ )
165
+ )
166
+ else:
167
+ print(format_engines_table(router))
168
+ return 0
169
+
170
+ if subcmd == "dsl":
171
+ query = " ".join(sub_args).strip()
172
+ res = router.pipeline.interpret(query, engine_override=engine, language=config.language)
173
+ print(json.dumps(res, ensure_ascii=False, indent=2))
174
+ return 0
175
+
176
+ if subcmd in ("uri", "open"):
177
+ target_uri = sub_args[0] if sub_args else "heyasa://willpad/pane/focus?pane=A"
178
+ receipt = router.dispatch(
179
+ target_uri,
180
+ engine=engine,
181
+ protocol=protocol,
182
+ autonomy_mode=autonomy,
183
+ confirmed=confirmed or (autonomy == "execute-once"),
184
+ origin="uri",
185
+ )
186
+ print(json.dumps(receipt, ensure_ascii=False, indent=2))
187
+ return 0
188
+
189
+ if subcmd == "plan":
190
+ query = " ".join(sub_args).strip()
191
+ plan = router.compile_plan(query, engine=engine, autonomy_mode=autonomy)
192
+ print(json.dumps(plan, ensure_ascii=False, indent=2))
193
+ return 0
194
+
195
+ if subcmd == "run":
196
+ if not sub_args:
197
+ print("heyasa: podaj ID planu lub polecenie do uruchomienia", file=sys.stderr)
198
+ return 2
199
+ plan_id = sub_args[0]
200
+ if plan_id in router.plans:
201
+ receipt = router.run_plan(plan_id, confirmed=True, autonomy_mode=autonomy, protocol=protocol)
202
+ else:
203
+ receipt = router.dispatch(
204
+ " ".join(sub_args),
205
+ engine=engine,
206
+ protocol=protocol,
207
+ autonomy_mode=autonomy,
208
+ confirmed=True,
209
+ origin="cli",
210
+ )
211
+ print(json.dumps(receipt, ensure_ascii=False, indent=2))
212
+ return 0
213
+
214
+ if subcmd == "switch":
215
+ switcher = ToolSwitcher(router)
216
+ if not sub_args or sub_args[0] in ("--list", "list"):
217
+ print(
218
+ json.dumps(
219
+ {"tools": TOOL_TARGETS, "presets": WORKSPACE_PRESETS},
220
+ ensure_ascii=False,
221
+ indent=2,
222
+ )
223
+ )
224
+ return 0
225
+ target = sub_args[0]
226
+ pane = sub_args[1] if len(sub_args) > 1 and len(sub_args[1]) == 1 else None
227
+ res = switcher.switch(target, pane=pane)
228
+ print(json.dumps(res, ensure_ascii=False, indent=2))
229
+ return 0
230
+
231
+ if subcmd in ("hud", "window"):
232
+ wm = HalfScreenWindowManager(config)
233
+ if "--bench" in sub_args or "bench" in sub_args:
234
+ print(json.dumps({"runtimes": WINDOW_RUNTIMES_BENCHMARK}, ensure_ascii=False, indent=2))
235
+ return 0
236
+ for i, tok in enumerate(sub_args):
237
+ if tok == "--export-tauri":
238
+ out_dir = Path(sub_args[i + 1]) if i + 1 < len(sub_args) else (Path.cwd() / "heyasa-tauri-hud")
239
+ print(json.dumps(wm.export_tauri_v2_scaffold(out_dir), ensure_ascii=False, indent=2))
240
+ return 0
241
+ position = "top" if "--top" in sub_args else "bottom"
242
+ target_app = "willman" if "willman" in sub_args else "willmux"
243
+ dry = known.dry_run or "--dry-run" in sub_args or "--geometry" in sub_args
244
+ res = wm.launch_or_toggle(target=target_app, position=position, height_ratio=0.48, dry_run=dry)
245
+ print(json.dumps(res, ensure_ascii=False, indent=2))
246
+ return 0
247
+
248
+ if subcmd == "willpad":
249
+ return _handle_willpad_subcommand(router, sub_args, protocol=protocol, as_json=known.json)
250
+
251
+ if subcmd in ("willman", "subactor", "dockuri", "taskand"):
252
+ query = " ".join(sub_args).strip() or "status"
253
+ receipt = router.dispatch(
254
+ query,
255
+ engine=subcmd,
256
+ protocol=protocol,
257
+ autonomy_mode=autonomy,
258
+ confirmed=confirmed,
259
+ origin="cli",
260
+ )
261
+ _print_receipt(receipt, as_json=known.json)
262
+ return 0
263
+
264
+ if subcmd == "catalog":
265
+ fmt = "json" if known.json else "table"
266
+ for i, tok in enumerate(sub_args):
267
+ if tok in ("--format", "-f") and i + 1 < len(sub_args):
268
+ fmt = sub_args[i + 1]
269
+ if fmt == "gbnf":
270
+ print(router.registry.export_gbnf_grammar(engine))
271
+ return 0
272
+ manifest = router.registry.export_nl_api_manifest(engine)
273
+ if fmt in ("json", "nl-api"):
274
+ print(json.dumps(manifest, ensure_ascii=False, indent=2))
275
+ else:
276
+ print(f"{'ENGINE':<10} {'ACTION URI':<44} {'EFFECT':<8} {'RISK':<7} {'OPIS'}")
277
+ print("-" * 105)
278
+ for ep in manifest["endpoints"]:
279
+ print(
280
+ f"{ep['engine']:<10} {ep['native_uri']:<44} {ep['effect']:<8} {ep['risk']:<7} {ep['summary_pl']}"
281
+ )
282
+ return 0
283
+
284
+ if subcmd == "snapshot":
285
+ snap = router.snapshot(engine=engine, autonomy=autonomy)
286
+ print(json.dumps(snap, ensure_ascii=False, indent=2))
287
+ return 0
288
+
289
+ if subcmd == "receipts":
290
+ limit = 20
291
+ items = router.receipt_store.list_receipts(limit=limit, engine=engine)
292
+ print(json.dumps({"receipts": items}, ensure_ascii=False, indent=2))
293
+ return 0
294
+
295
+ if subcmd == "gov":
296
+ action = sub_args[0] if sub_args else "standards"
297
+ root = Path.cwd()
298
+ res = run_wellman_governance(action, root=root)
299
+ print(json.dumps(res, ensure_ascii=False, indent=2))
300
+ return 0
301
+
302
+ if subcmd == "serve":
303
+ port = config.rest_port
304
+ host = config.rest_host
305
+ for i, tok in enumerate(sub_args):
306
+ if tok == "--port" and i + 1 < len(sub_args):
307
+ port = int(sub_args[i + 1])
308
+ elif tok == "--host" and i + 1 < len(sub_args):
309
+ host = sub_args[i + 1]
310
+ return serve_rest(router, host=host, port=port)
311
+
312
+ if subcmd == "mcp":
313
+ if "--manifest" in sub_args or known.json:
314
+ print(json.dumps(build_mcp_gateway_manifest(router), ensure_ascii=False, indent=2))
315
+ return 0
316
+ transport = "streamable-http" if "--http" in sub_args else "stdio"
317
+ return serve_mcp(router, transport=transport, host=config.rest_host, port=config.mcp_port)
318
+
319
+ if subcmd == "grpc":
320
+ if "--proto" in sub_args:
321
+ print(HEYASA_PROTO_SPEC)
322
+ return 0
323
+ svc = HeyasaGrpcService(router)
324
+ print(json.dumps({"service": "heyasa.v1.HeyasaService", "port": config.grpc_port, "state": svc.get_state()}, ensure_ascii=False, indent=2))
325
+ return 0
326
+
327
+ if subcmd == "acp":
328
+ return serve_acp_stdio(router)
329
+
330
+ # Free-form natural language sentence or DSL command
331
+ full_text = " ".join(rest).strip()
332
+ receipt = router.dispatch(
333
+ full_text,
334
+ engine=engine,
335
+ protocol=protocol,
336
+ autonomy_mode=autonomy,
337
+ confirmed=confirmed,
338
+ origin="cli",
339
+ )
340
+ _print_receipt(receipt, as_json=known.json)
341
+ return 0
342
+
343
+
344
+ def _handle_willpad_subcommand(
345
+ router: HeyasaRouter,
346
+ sub_args: List[str],
347
+ *,
348
+ protocol: str = "auto",
349
+ as_json: bool = False,
350
+ ) -> int:
351
+ if not sub_args:
352
+ st = router.willpad.status()
353
+ print(json.dumps(st, ensure_ascii=False, indent=2))
354
+ return 0
355
+
356
+ verb = sub_args[0].lower()
357
+ if verb == "focus":
358
+ pane = sub_args[1].upper() if len(sub_args) > 1 else "A"
359
+ uri = f"willpad://pane/focus?pane={pane}"
360
+ elif verb == "style":
361
+ style = sub_args[1].lower() if len(sub_args) > 1 and sub_args[1].lower() in WILLPAD_STYLES else "quad"
362
+ uri = f"willpad://menu/style?style={style}"
363
+ elif verb == "layout":
364
+ layout = sub_args[1].lower() if len(sub_args) > 1 else "grid"
365
+ uri = f"willpad://layout/set?layout={layout}"
366
+ elif verb == "compact":
367
+ mode = sub_args[1].lower() if len(sub_args) > 1 else "compact"
368
+ uri = f"willpad://chat/compact?mode={mode}"
369
+ elif verb == "tool":
370
+ pane = sub_args[1].upper() if len(sub_args) > 1 else "B"
371
+ tool = sub_args[2].lower() if len(sub_args) > 2 and sub_args[2].lower() in WILLPAD_TOOLS else "shot"
372
+ uri = f"willpad://window/tool?pane={pane}&tool={tool}"
373
+ else:
374
+ uri = " ".join(sub_args)
375
+
376
+ receipt = router.dispatch(
377
+ uri,
378
+ engine="willpad",
379
+ protocol=protocol,
380
+ autonomy_mode="auto",
381
+ confirmed=True,
382
+ origin="cli",
383
+ )
384
+ _print_receipt(receipt, as_json=as_json)
385
+ return 0
386
+
387
+
388
+ def _print_receipt(receipt: dict, *, as_json: bool = False) -> None:
389
+ if as_json:
390
+ print(json.dumps(receipt, ensure_ascii=False, indent=2))
391
+ return
392
+ card = receipt.get("chat_card") or {}
393
+ print(f"[{receipt['engine']} | {receipt['autonomy_mode']} -> {receipt['post_execution_state']}] {card.get('summary', '')}")
394
+ print(f" URI: {receipt['resolved_action_uri']}")
395
+ print(f" Receipt: {receipt['receipt_ref']} ({receipt['process_urn']})")
396
+ if receipt["status"] == "pending_approval":
397
+ plan = (receipt.get("result") or {}).get("plan") or {}
398
+ if plan.get("id"):
399
+ print(f" Zatwierdź: heyasa run {plan['id']} --yes")