machina-cli 0.6.2__tar.gz → 0.6.3__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 (101) hide show
  1. {machina_cli-0.6.2 → machina_cli-0.6.3}/CHANGELOG.md +5 -0
  2. {machina_cli-0.6.2 → machina_cli-0.6.3}/PKG-INFO +1 -1
  3. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/harness-loop-kit/README.md +21 -0
  4. machina_cli-0.6.3/docs/harness-loop-kit/nodes.py +202 -0
  5. {machina_cli-0.6.2 → machina_cli-0.6.3}/pyproject.toml +1 -1
  6. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/__init__.py +1 -1
  7. {machina_cli-0.6.2 → machina_cli-0.6.3}/.github/workflows/ci.yml +0 -0
  8. {machina_cli-0.6.2 → machina_cli-0.6.3}/.github/workflows/release.yml +0 -0
  9. {machina_cli-0.6.2 → machina_cli-0.6.3}/.gitignore +0 -0
  10. {machina_cli-0.6.2 → machina_cli-0.6.3}/CLAUDE.md +0 -0
  11. {machina_cli-0.6.2 → machina_cli-0.6.3}/README.md +0 -0
  12. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/agentic-harness-loop.md +0 -0
  13. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/credentials.md +0 -0
  14. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/harness-loop-kit/PLAYBOOK-SCORECARD.md +0 -0
  15. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/harness-loop-kit/VALIDATION.md +0 -0
  16. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/harness-loop-kit/context-verify.py +0 -0
  17. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/harness-loop-kit/provision.py +0 -0
  18. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/harness-loop-kit/surface-verify.py +0 -0
  19. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs/loop-tools-connector.py +0 -0
  20. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/.gitignore +0 -0
  21. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/.vitepress/config.mts +0 -0
  22. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/.vitepress/theme/custom.css +0 -0
  23. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/.vitepress/theme/index.ts +0 -0
  24. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/README.md +0 -0
  25. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/agent.md +0 -0
  26. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/config.md +0 -0
  27. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/connect.md +0 -0
  28. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/connector.md +0 -0
  29. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/context-graph.md +0 -0
  30. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/credentials.md +0 -0
  31. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/deploy.md +0 -0
  32. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/document.md +0 -0
  33. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/execution.md +0 -0
  34. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/factory.md +0 -0
  35. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/login.md +0 -0
  36. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/loop.md +0 -0
  37. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/mapping.md +0 -0
  38. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/mcp.md +0 -0
  39. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/org.md +0 -0
  40. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/project.md +0 -0
  41. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/prompt.md +0 -0
  42. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/skills.md +0 -0
  43. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/sports.md +0 -0
  44. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/template.md +0 -0
  45. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/update.md +0 -0
  46. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/commands/workflow.md +0 -0
  47. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/guide/authentication.md +0 -0
  48. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/guide/configuration.md +0 -0
  49. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/guide/installation.md +0 -0
  50. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/guide/quickstart.md +0 -0
  51. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/guide/repl.md +0 -0
  52. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/guide/running.md +0 -0
  53. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/index.md +0 -0
  54. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/package-lock.json +0 -0
  55. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/package.json +0 -0
  56. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/public/favicon.ico +0 -0
  57. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/public/machina-logo-dark.png +0 -0
  58. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/public/machina-logo-light.png +0 -0
  59. {machina_cli-0.6.2 → machina_cli-0.6.3}/docs-site/vercel.json +0 -0
  60. {machina_cli-0.6.2 → machina_cli-0.6.3}/install.ps1 +0 -0
  61. {machina_cli-0.6.2 → machina_cli-0.6.3}/install.sh +0 -0
  62. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/browser_auth.py +0 -0
  63. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/client.py +0 -0
  64. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/__init__.py +0 -0
  65. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/agent.py +0 -0
  66. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/auth.py +0 -0
  67. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/config_cmd.py +0 -0
  68. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/connect.py +0 -0
  69. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/connector.py +0 -0
  70. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/context_graph.py +0 -0
  71. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/credentials.py +0 -0
  72. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/deploy.py +0 -0
  73. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/document.py +0 -0
  74. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/execution.py +0 -0
  75. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/factory.py +0 -0
  76. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/loop.py +0 -0
  77. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/mapping.py +0 -0
  78. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/mcp.py +0 -0
  79. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/org.py +0 -0
  80. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/project.py +0 -0
  81. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/prompt.py +0 -0
  82. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/skills.py +0 -0
  83. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/sports.py +0 -0
  84. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/template.py +0 -0
  85. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/commands/workflow.py +0 -0
  86. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/config.py +0 -0
  87. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/factory_client.py +0 -0
  88. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/loop_client.py +0 -0
  89. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/main.py +0 -0
  90. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/models/__init__.py +0 -0
  91. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/project_client.py +0 -0
  92. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/repl.py +0 -0
  93. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/update_check.py +0 -0
  94. {machina_cli-0.6.2 → machina_cli-0.6.3}/src/machina_cli/updater.py +0 -0
  95. {machina_cli-0.6.2 → machina_cli-0.6.3}/tests/__init__.py +0 -0
  96. {machina_cli-0.6.2 → machina_cli-0.6.3}/tests/test_cli_output.py +0 -0
  97. {machina_cli-0.6.2 → machina_cli-0.6.3}/tests/test_connect.py +0 -0
  98. {machina_cli-0.6.2 → machina_cli-0.6.3}/tests/test_context_graph_timeline.py +0 -0
  99. {machina_cli-0.6.2 → machina_cli-0.6.3}/tests/test_mcp_url.py +0 -0
  100. {machina_cli-0.6.2 → machina_cli-0.6.3}/tests/test_org_usage.py +0 -0
  101. {machina_cli-0.6.2 → machina_cli-0.6.3}/tests/test_sports_integration.py +0 -0
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to machina-cli are documented here.
4
4
 
5
+ ## [0.6.3] - 2026-07-02
6
+
7
+ ### Added
8
+ - **`machina-nodes` — a shared action-node library for pod workflows** (`docs/harness-loop-kit/nodes.py`). The Pressbox lesson applied to Machina's own engine: workflows are already data walked by an executor — what was missing was a registry of small, composable action nodes, so a new automation is graph wiring instead of another copy-pasted pyscript (the Slack notify logic had been written twice across the verify kits). Ships two nodes: `slack_notify` (posts a ready-composed text; webhook from the same `slack-notify-config` doc the verifies use) and `github_issue` (opens a GitHub issue; token+repo from a `github-issue-config` doc — **inert until configured**, so it deploys everywhere safely). Every node is best-effort (never raises), inert without config, and composed via task inputs. A `machina-nodes-demo` workflow ships as living documentation of the pattern.
9
+
5
10
  ## [0.6.2] - 2026-07-01
6
11
 
7
12
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machina-cli
3
- Version: 0.6.2
3
+ Version: 0.6.3
4
4
  Summary: CLI for the Machina AI Agent platform
5
5
  Project-URL: Homepage, https://machina.gg
6
6
  Project-URL: Repository, https://github.com/machina-sports/machina-cli
@@ -183,6 +183,27 @@ pelo LLM e persistido pra a montagem de contexto do cliente consumir. O agent
183
183
  detect → heal → **resolve ids** → persist → repeat. *(Conservador: só links que resolvem a ids
184
184
  reais são gravados — o resto fica como órfão.)*
185
185
 
186
+ ## 6.1 `nodes.py` — biblioteca de nós compartilhados (padrão Pressbox)
187
+
188
+ Os workflows da Machina já são *dados* (tasks + conditions + `$.get()`), mas cada
189
+ automação nova vinha copiando código de ação (o notify do Slack foi escrito 2x nos
190
+ verifies). **`nodes.py`** provisiona o connector **`machina-nodes`** — um *registry*
191
+ de nós de ação pequenos e compostos no grafo, não no código:
192
+
193
+ | Nó | Faz | Config |
194
+ | --- | --- | --- |
195
+ | `slack_notify` | posta um texto **já composto** no webhook do pod | doc `slack-notify-config` (o mesmo dos verifies) |
196
+ | `github_issue` | abre issue no GitHub (title/body/labels) | doc `github-issue-config` `{token, repo}` — **inerte até existir** |
197
+
198
+ Regras de todo nó: **best-effort** (nunca lança — automação acessória não pode derrubar
199
+ o workflow que a carrega), **inerte sem config**, **composição via inputs da task**
200
+ (o workflow compõe; o nó só executa). O workflow `machina-nodes-demo` fica provisionado
201
+ como documentação viva do padrão.
202
+
203
+ ```bash
204
+ CLIENT_API_URL=… API_TOKEN=… python3 docs/harness-loop-kit/nodes.py --run # provisiona + smoke no Slack
205
+ ```
206
+
186
207
  ## 7. Pendências honestas (transparência)
187
208
 
188
209
  1. **Redeploy do MCP** ([#287](https://github.com/machina-sports/machina-client-api/issues/287)):
@@ -0,0 +1,202 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Machina Nodes — a shared, reusable node library for pod workflows.
4
+
5
+ The Pressbox lesson applied to Machina's own engine: workflows here are already
6
+ data (tasks + conditions + $.get() templating) walked by an executor — what was
7
+ missing is a REGISTRY of small, composable action nodes, so a new automation is
8
+ graph wiring instead of another copy-pasted pyscript. This kit provisions one
9
+ connector, `machina-nodes`, whose commands are those nodes:
10
+
11
+ slack_notify post a ready-composed text to the pod's Slack webhook.
12
+ Resolves the webhook from the `slack-notify-config` document
13
+ (same doc surface-verify/context-verify already use) or an
14
+ explicit input. No text / no webhook -> clean no-op.
15
+ github_issue open a GitHub issue (title/body/labels). Token + default repo
16
+ come from a `github-issue-config` document ({token, repo}) or
17
+ explicit inputs. INERT until that doc exists -- provisioning
18
+ this connector changes nothing until someone drops a token.
19
+
20
+ Design rules every node follows (and future nodes must too):
21
+ - best-effort: a node NEVER raises -- an automation nicety must never fail
22
+ the workflow that carries it. Failures return {..., "error": "..."}.
23
+ - inert by default: missing config -> {"skipped": "..."}, zero side effects.
24
+ - composition over configuration: nodes take READY inputs (text, title);
25
+ composing them is the calling workflow's job, in task inputs -- that keeps
26
+ each node small and every combination possible.
27
+
28
+ A `machina-nodes-demo` workflow is provisioned alongside as living
29
+ documentation of the pattern (one compose-in-inputs -> post task).
30
+
31
+ Usage:
32
+ CLIENT_API_URL="https://<org>-<project>.org.machina.gg" \\
33
+ API_TOKEN="<project X-Api-Token>" \\
34
+ python3 nodes.py # provision the connector + demo workflow
35
+ python3 nodes.py --run # provision + post one marked smoke message
36
+ python3 nodes.py --teardown # remove
37
+ """
38
+
39
+ import json
40
+ import os
41
+ import sys
42
+
43
+ import urllib.request
44
+ import urllib.error
45
+
46
+ BASE = os.environ.get("CLIENT_API_URL", "").rstrip("/")
47
+ TOKEN = os.environ.get("API_TOKEN", "")
48
+
49
+
50
+ def _req(method, path, body=None):
51
+ url = f"{BASE}/{path.lstrip('/')}"
52
+ data = json.dumps(body).encode() if body is not None else None
53
+ req = urllib.request.Request(url, data=data, method=method,
54
+ headers={"X-Api-Token": TOKEN, "Content-Type": "application/json"})
55
+ try:
56
+ with urllib.request.urlopen(req, timeout=120) as r:
57
+ return json.loads(r.read() or "{}")
58
+ except urllib.error.HTTPError as e:
59
+ return {"status": False, "error": {"message": f"HTTP {e.code}: {e.read()[:200]}"}}
60
+ except Exception as e: # noqa: BLE001
61
+ return {"status": False, "error": {"message": str(e)}}
62
+
63
+
64
+ def _delete_by_name(kind, name):
65
+ d = _req("GET", f"{kind}/{name}").get("data", {})
66
+ if isinstance(d, dict) and d.get("_id"):
67
+ _req("DELETE", f"{kind}/{d['_id']}")
68
+
69
+
70
+ def _create(kind, body):
71
+ _delete_by_name(kind, body["name"])
72
+ res = _req("POST", kind, body)
73
+ ok = res.get("status") in (True, "success")
74
+ print(f" {'OK ' if ok else 'ERR'} {kind}/{body['name']}"
75
+ + ("" if ok else f" -> {json.dumps(res.get('error'))[:120]}"))
76
+ return ok
77
+
78
+
79
+ NODES_SRC = r'''"""machina-nodes: small, composable action nodes for pod workflows."""
80
+ import json, urllib.request, urllib.error
81
+
82
+
83
+ def _config_doc(name):
84
+ """Read a single config document's value by name; {} when absent/unreadable."""
85
+ try:
86
+ from core.document.controller import document_search
87
+ r = document_search(filters={"name": name}, page=1, page_size=1)
88
+ dd = r.get("data") if isinstance(r, dict) else None
89
+ rows = dd.get("data") if isinstance(dd, dict) else (dd if isinstance(dd, list) else [])
90
+ if rows:
91
+ return rows[0].get("value") or {}
92
+ except Exception:
93
+ pass
94
+ return {}
95
+
96
+
97
+ def slack_notify(request_data: dict) -> dict:
98
+ """Post a ready-composed text to Slack. Webhook: explicit input, else the pod's
99
+ slack-notify-config document. No text / unresolved template / no webhook -> no-op.
100
+ Best-effort: never raises."""
101
+ p = request_data.get("params", {}) or request_data
102
+ text = (p.get("text") or "").strip()
103
+ if not text or text.startswith("$"):
104
+ return {"status": True, "data": {"notified": False, "skipped": "no text"}}
105
+ webhook = (p.get("webhook_url") or "").strip()
106
+ if not webhook or webhook.startswith("$"):
107
+ webhook = (_config_doc("slack-notify-config").get("webhook_url") or "").strip()
108
+ if not webhook:
109
+ return {"status": True, "data": {"notified": False, "skipped": "no webhook configured"}}
110
+ try:
111
+ req = urllib.request.Request(webhook, data=json.dumps({"text": text}).encode(),
112
+ method="POST", headers={"Content-Type": "application/json"})
113
+ with urllib.request.urlopen(req, timeout=15) as r:
114
+ r.read()
115
+ return {"status": True, "data": {"notified": True}}
116
+ except Exception as e:
117
+ return {"status": True, "data": {"notified": False, "error": str(e)[:150]}}
118
+
119
+
120
+ def github_issue(request_data: dict) -> dict:
121
+ """Open a GitHub issue. Token + default repo come from the github-issue-config
122
+ document ({token, repo}) or explicit inputs -- INERT until configured. Repo is
123
+ "owner/name". Best-effort: never raises."""
124
+ p = request_data.get("params", {}) or request_data
125
+ title = (p.get("title") or "").strip()
126
+ if not title or title.startswith("$"):
127
+ return {"status": True, "data": {"filed": False, "skipped": "no title"}}
128
+ token = (p.get("token") or "").strip()
129
+ repo = (p.get("repo") or "").strip()
130
+ if not token or not repo or repo.startswith("$"):
131
+ cfg = _config_doc("github-issue-config")
132
+ token = token if token and not token.startswith("$") else (cfg.get("token") or "").strip()
133
+ repo = repo if repo and not repo.startswith("$") else (cfg.get("repo") or "").strip()
134
+ if not token or not repo:
135
+ return {"status": True, "data": {"filed": False, "skipped": "not configured (github-issue-config)"}}
136
+ payload = {"title": title, "body": p.get("body") or ""}
137
+ labels = p.get("labels")
138
+ if isinstance(labels, list) and labels:
139
+ payload["labels"] = labels
140
+ try:
141
+ req = urllib.request.Request(
142
+ "https://api.github.com/repos/%s/issues" % repo,
143
+ data=json.dumps(payload).encode(), method="POST",
144
+ headers={"Authorization": "Bearer " + token,
145
+ "Accept": "application/vnd.github+json",
146
+ # GitHub's API rejects requests without a User-Agent.
147
+ "User-Agent": "machina-nodes",
148
+ "Content-Type": "application/json"})
149
+ with urllib.request.urlopen(req, timeout=20) as r:
150
+ d = json.loads(r.read() or "{}")
151
+ return {"status": True, "data": {"filed": True, "issue_url": d.get("html_url"),
152
+ "number": d.get("number")}}
153
+ except Exception as e:
154
+ return {"status": True, "data": {"filed": False, "error": str(e)[:150]}}
155
+ '''
156
+
157
+
158
+ def definitions():
159
+ connector = {"name": "machina-nodes", "title": "Machina Nodes", "status": "active",
160
+ "description": "shared action-node registry (slack_notify, github_issue) for workflow composition",
161
+ "filename": "machina_nodes.py", "filetype": "pyscript", "filecontent": NODES_SRC,
162
+ "commands": [{"name": "SlackNotify", "value": "slack_notify"},
163
+ {"name": "GithubIssue", "value": "github_issue"}]}
164
+ # Living documentation of the composition pattern: the workflow composes the
165
+ # message in task INPUTS; the node just posts it. Any workflow can copy this task.
166
+ demo = {"name": "machina-nodes-demo", "title": "Machina Nodes Demo", "status": "active",
167
+ "description": "composition demo: compose in inputs -> slack_notify node",
168
+ "context-variables": {"debugger": {"enabled": True}},
169
+ "inputs": {"text": "$.get('text', '')"},
170
+ "outputs": {"notified": "$.get('nd_out', {})", "workflow-status": "'executed'"},
171
+ "tasks": [
172
+ {"name": "post", "type": "connector",
173
+ "connector": {"command": "slack_notify", "name": "machina-nodes"},
174
+ "inputs": {"text": "$.get('text', '')"},
175
+ "outputs": {"nd_out": "$"}},
176
+ ]}
177
+ return [("connector", connector), ("workflow", demo)]
178
+
179
+
180
+ def main():
181
+ if not BASE or not TOKEN:
182
+ sys.exit("Set CLIENT_API_URL and API_TOKEN environment variables.")
183
+ defs = definitions()
184
+ if "--teardown" in sys.argv:
185
+ print(f"Tearing down machina-nodes on {BASE} ...")
186
+ for kind, body in reversed(defs):
187
+ _delete_by_name(kind, body["name"])
188
+ print(f" removed {kind}/{body['name']}")
189
+ return
190
+ print(f"Provisioning machina-nodes on {BASE} ...")
191
+ ok = all(_create(kind, body) for kind, body in defs)
192
+ print("Done." if ok else "Done with errors — check output above.")
193
+ if "--run" in sys.argv:
194
+ print("\nSmoke: posting one marked message via the demo workflow ...")
195
+ r = _req("POST", "workflow/execute/machina-nodes-demo",
196
+ {"text": ":test_tube: machina-nodes — shared node library is live in this pod "
197
+ "(slack_notify + github_issue registered)."})
198
+ print(" execute status:", r.get("status"), "| error:", r.get("error"))
199
+
200
+
201
+ if __name__ == "__main__":
202
+ main()
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "machina-cli"
7
- version = "0.6.2"
7
+ version = "0.6.3"
8
8
  description = "CLI for the Machina AI Agent platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """Machina CLI - Command line interface for the Machina AI Agent platform."""
2
2
 
3
- __version__ = "0.6.2"
3
+ __version__ = "0.6.3"
File without changes
File without changes
File without changes
File without changes
File without changes