devtorch-cli 3.0.1__py3-none-any.whl
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.
- devtorch_cli/__init__.py +1 -0
- devtorch_cli/__main__.py +6 -0
- devtorch_cli/audit_cmds.py +221 -0
- devtorch_cli/capability_role_cmds.py +94 -0
- devtorch_cli/main.py +4090 -0
- devtorch_cli/pr_reporter_cmd.py +41 -0
- devtorch_cli/pre_commit_cmds.py +40 -0
- devtorch_cli/session_cmds.py +282 -0
- devtorch_cli-3.0.1.dist-info/METADATA +60 -0
- devtorch_cli-3.0.1.dist-info/RECORD +13 -0
- devtorch_cli-3.0.1.dist-info/WHEEL +5 -0
- devtorch_cli-3.0.1.dist-info/entry_points.txt +2 -0
- devtorch_cli-3.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""S29 CLI handler for `devtorch pr-report`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from devtorch_core.github.pr_reporter import run_pr_reporter
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def cmd_pr_report(args: argparse.Namespace) -> int:
|
|
13
|
+
project_root = Path(args.path).resolve()
|
|
14
|
+
gcc_dir = project_root / ".GCC"
|
|
15
|
+
if not gcc_dir.exists():
|
|
16
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
17
|
+
return 1
|
|
18
|
+
|
|
19
|
+
critical_concepts = [c.strip() for c in args.critical_concepts.split(",") if c.strip()] if args.critical_concepts else []
|
|
20
|
+
try:
|
|
21
|
+
result = run_pr_reporter(
|
|
22
|
+
gcc_repo_path=str(project_root),
|
|
23
|
+
base_branch=args.base,
|
|
24
|
+
head_branch=args.head,
|
|
25
|
+
repo_owner=args.repo_owner,
|
|
26
|
+
repo_name=args.repo_name,
|
|
27
|
+
pr_number=args.pr_number,
|
|
28
|
+
token=args.token,
|
|
29
|
+
critical_concepts=critical_concepts,
|
|
30
|
+
min_mcs=args.min_mcs,
|
|
31
|
+
)
|
|
32
|
+
except Exception as exc:
|
|
33
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
34
|
+
return 1
|
|
35
|
+
|
|
36
|
+
print(f"Posted reasoning-delta comment: {result.comment_posted}")
|
|
37
|
+
print(f"Merge gate: {'ALLOWED' if result.merge_gate_allowed else 'BLOCKED'}")
|
|
38
|
+
if result.merge_gate_reasons:
|
|
39
|
+
for reason in result.merge_gate_reasons:
|
|
40
|
+
print(f" - {reason}")
|
|
41
|
+
return 0 if result.merge_gate_allowed else 1
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""S29 CLI handlers for `devtorch pre-commit`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from devtorch_core.hooks.pre_commit import (
|
|
10
|
+
install_pre_commit_hook,
|
|
11
|
+
run_pre_commit_checks,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _project_root(args: argparse.Namespace) -> Path:
|
|
16
|
+
return Path(args.path).resolve()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def cmd_pre_commit_install(args: argparse.Namespace) -> int:
|
|
20
|
+
project_root = _project_root(args)
|
|
21
|
+
try:
|
|
22
|
+
path = install_pre_commit_hook(project_root)
|
|
23
|
+
except RuntimeError as exc:
|
|
24
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
25
|
+
return 1
|
|
26
|
+
print(f"Installed pre-commit hook at {path}")
|
|
27
|
+
return 0
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def cmd_pre_commit_run(args: argparse.Namespace) -> int:
|
|
31
|
+
project_root = _project_root(args)
|
|
32
|
+
result = run_pre_commit_checks(project_root)
|
|
33
|
+
for check in result.checks:
|
|
34
|
+
status = "✓" if check["passed"] else "✗"
|
|
35
|
+
print(f"{status} {check['name']} (exit={check['exit_code']})")
|
|
36
|
+
if result.passed:
|
|
37
|
+
print("Pre-commit checks passed.")
|
|
38
|
+
return 0
|
|
39
|
+
print("Pre-commit checks failed.", file=sys.stderr)
|
|
40
|
+
return 1
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""S28 CLI handlers for `devtorch session` and `devtorch simulate`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
|
|
11
|
+
from devtorch_core.session import (
|
|
12
|
+
ACTIVE,
|
|
13
|
+
COMPLETED,
|
|
14
|
+
PENDING,
|
|
15
|
+
AgentAssignment,
|
|
16
|
+
DisagreementResolver,
|
|
17
|
+
SessionOrchestrator,
|
|
18
|
+
SubtaskPlanner,
|
|
19
|
+
WhatIfSimulator,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _gcc_dir(args: argparse.Namespace) -> Path:
|
|
24
|
+
return Path(args.path).resolve() / ".GCC"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _parse_agent_assignments(raw: list[str] | None) -> List[AgentAssignment]:
|
|
28
|
+
assignments: List[AgentAssignment] = []
|
|
29
|
+
for item in raw or []:
|
|
30
|
+
if "=" not in item:
|
|
31
|
+
print(f"error: --agent must be AGENT_ID=ROLE, got: {item}", file=sys.stderr)
|
|
32
|
+
return []
|
|
33
|
+
agent_id, role = item.split("=", 1)
|
|
34
|
+
assignments.append(AgentAssignment(agent_id=agent_id.strip(), role=role.strip()))
|
|
35
|
+
return assignments
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _parse_positions(raw: list[str] | None) -> List[Dict[str, Any]]:
|
|
39
|
+
positions: List[Dict[str, Any]] = []
|
|
40
|
+
for item in raw or []:
|
|
41
|
+
# Format: agent=position:confidence
|
|
42
|
+
if "=" not in item:
|
|
43
|
+
print(f"error: --position must be AGENT=POSITION:CONFIDENCE, got: {item}", file=sys.stderr)
|
|
44
|
+
continue
|
|
45
|
+
agent_id, rest = item.split("=", 1)
|
|
46
|
+
confidence = 0.5
|
|
47
|
+
position = rest
|
|
48
|
+
if ":" in rest:
|
|
49
|
+
position, conf_str = rest.rsplit(":", 1)
|
|
50
|
+
try:
|
|
51
|
+
confidence = float(conf_str)
|
|
52
|
+
except ValueError:
|
|
53
|
+
pass
|
|
54
|
+
positions.append({"agent_id": agent_id.strip(), "position": position.strip(), "confidence": confidence})
|
|
55
|
+
return positions
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def cmd_session_start(args: argparse.Namespace) -> int:
|
|
59
|
+
gcc_dir = _gcc_dir(args)
|
|
60
|
+
if not gcc_dir.exists():
|
|
61
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
62
|
+
return 1
|
|
63
|
+
agents = _parse_agent_assignments(getattr(args, "agents", []))
|
|
64
|
+
orchestrator = SessionOrchestrator(gcc_dir)
|
|
65
|
+
session = orchestrator.start_session(
|
|
66
|
+
name=args.name,
|
|
67
|
+
problem=args.problem,
|
|
68
|
+
agent_assignments=agents,
|
|
69
|
+
)
|
|
70
|
+
print(f"Started session {session.session_id}: {session.name}")
|
|
71
|
+
print(f" status: {session.status}")
|
|
72
|
+
if session.agent_roles:
|
|
73
|
+
print(" agents:")
|
|
74
|
+
for a in session.agent_roles:
|
|
75
|
+
print(f" {a.agent_id} -> {a.role}")
|
|
76
|
+
return 0
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def cmd_session_list(args: argparse.Namespace) -> int:
|
|
80
|
+
gcc_dir = _gcc_dir(args)
|
|
81
|
+
if not gcc_dir.exists():
|
|
82
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
83
|
+
return 1
|
|
84
|
+
orchestrator = SessionOrchestrator(gcc_dir)
|
|
85
|
+
sessions = orchestrator.list_sessions()
|
|
86
|
+
if not sessions:
|
|
87
|
+
print("No sessions.")
|
|
88
|
+
return 0
|
|
89
|
+
print(f"{'ID':<24} {'Name':<30} {'Status':<12} {'Subtasks':>10}")
|
|
90
|
+
print("-" * 80)
|
|
91
|
+
for s in sessions:
|
|
92
|
+
total = len(s.subtasks)
|
|
93
|
+
done = sum(1 for t in s.subtasks if t.status == COMPLETED)
|
|
94
|
+
print(f"{s.session_id:<24} {s.name:<30} {s.status:<12} {done}/{total}")
|
|
95
|
+
return 0
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def cmd_session_show(args: argparse.Namespace) -> int:
|
|
99
|
+
gcc_dir = _gcc_dir(args)
|
|
100
|
+
if not gcc_dir.exists():
|
|
101
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
102
|
+
return 1
|
|
103
|
+
orchestrator = SessionOrchestrator(gcc_dir)
|
|
104
|
+
try:
|
|
105
|
+
session = orchestrator.get_session(args.session_id)
|
|
106
|
+
except FileNotFoundError:
|
|
107
|
+
print(f"error: session {args.session_id} not found", file=sys.stderr)
|
|
108
|
+
return 1
|
|
109
|
+
print(f"Session {session.session_id}: {session.name}")
|
|
110
|
+
print(f" status: {session.status}")
|
|
111
|
+
print(f" problem: {session.problem}")
|
|
112
|
+
if session.assumptions:
|
|
113
|
+
print(" assumptions:")
|
|
114
|
+
for k, v in session.assumptions.items():
|
|
115
|
+
print(f" {k}: {v}")
|
|
116
|
+
if session.agent_roles:
|
|
117
|
+
print(" agents:")
|
|
118
|
+
for a in session.agent_roles:
|
|
119
|
+
print(f" {a.agent_id} -> {a.role}")
|
|
120
|
+
if session.subtasks:
|
|
121
|
+
print(" subtasks:")
|
|
122
|
+
for t in session.subtasks:
|
|
123
|
+
deps = f" (depends on {', '.join(t.dependencies)})" if t.dependencies else ""
|
|
124
|
+
print(f" [{t.status}] {t.subtask_id}: {t.description}{deps}")
|
|
125
|
+
return 0
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def cmd_session_plan(args: argparse.Namespace) -> int:
|
|
129
|
+
gcc_dir = _gcc_dir(args)
|
|
130
|
+
if not gcc_dir.exists():
|
|
131
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
132
|
+
return 1
|
|
133
|
+
orchestrator = SessionOrchestrator(gcc_dir)
|
|
134
|
+
try:
|
|
135
|
+
session = orchestrator.get_session(args.session_id)
|
|
136
|
+
except FileNotFoundError:
|
|
137
|
+
print(f"error: session {args.session_id} not found", file=sys.stderr)
|
|
138
|
+
return 1
|
|
139
|
+
problem = args.problem or session.problem
|
|
140
|
+
planner = SubtaskPlanner()
|
|
141
|
+
subtasks = planner.plan(args.session_id, problem, orchestrator)
|
|
142
|
+
print(f"Planned {len(subtasks)} subtask(s) for session {args.session_id}:")
|
|
143
|
+
for t in subtasks:
|
|
144
|
+
deps = f" (depends on {', '.join(t.dependencies)})" if t.dependencies else ""
|
|
145
|
+
print(f" {t.subtask_id}: {t.description}{deps}")
|
|
146
|
+
return 0
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def cmd_session_next(args: argparse.Namespace) -> int:
|
|
150
|
+
gcc_dir = _gcc_dir(args)
|
|
151
|
+
if not gcc_dir.exists():
|
|
152
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
153
|
+
return 1
|
|
154
|
+
orchestrator = SessionOrchestrator(gcc_dir)
|
|
155
|
+
planner = SubtaskPlanner()
|
|
156
|
+
subtask = planner.next_subtask(args.session_id, orchestrator)
|
|
157
|
+
if subtask is None:
|
|
158
|
+
print("No pending subtasks ready.")
|
|
159
|
+
return 0
|
|
160
|
+
print(f"Next subtask: {subtask.subtask_id}")
|
|
161
|
+
print(f" {subtask.description}")
|
|
162
|
+
return 0
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def cmd_session_mark(args: argparse.Namespace) -> int:
|
|
166
|
+
gcc_dir = _gcc_dir(args)
|
|
167
|
+
if not gcc_dir.exists():
|
|
168
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
169
|
+
return 1
|
|
170
|
+
orchestrator = SessionOrchestrator(gcc_dir)
|
|
171
|
+
planner = SubtaskPlanner()
|
|
172
|
+
subtask = planner.mark_subtask(args.session_id, args.subtask_id, args.status, orchestrator)
|
|
173
|
+
if subtask is None:
|
|
174
|
+
print(f"error: subtask {args.subtask_id} not found", file=sys.stderr)
|
|
175
|
+
return 1
|
|
176
|
+
print(f"Marked {subtask.subtask_id} as {subtask.status}")
|
|
177
|
+
return 0
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def cmd_session_close(args: argparse.Namespace) -> int:
|
|
181
|
+
gcc_dir = _gcc_dir(args)
|
|
182
|
+
if not gcc_dir.exists():
|
|
183
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
184
|
+
return 1
|
|
185
|
+
orchestrator = SessionOrchestrator(gcc_dir)
|
|
186
|
+
try:
|
|
187
|
+
session = orchestrator.close_session(args.session_id)
|
|
188
|
+
except FileNotFoundError:
|
|
189
|
+
print(f"error: session {args.session_id} not found", file=sys.stderr)
|
|
190
|
+
return 1
|
|
191
|
+
print(f"Closed session {session.session_id} (status={session.status})")
|
|
192
|
+
return 0
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def cmd_session_disagree(args: argparse.Namespace) -> int:
|
|
196
|
+
gcc_dir = _gcc_dir(args)
|
|
197
|
+
if not gcc_dir.exists():
|
|
198
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
199
|
+
return 1
|
|
200
|
+
positions = _parse_positions(getattr(args, "positions", []))
|
|
201
|
+
if not positions:
|
|
202
|
+
print("error: at least one --position required", file=sys.stderr)
|
|
203
|
+
return 1
|
|
204
|
+
resolver = DisagreementResolver(gcc_dir)
|
|
205
|
+
record = resolver.record_disagreement(args.session_id, args.concept, positions)
|
|
206
|
+
print(f"Recorded disagreement {record.disagreement_id} on '{record.concept}'")
|
|
207
|
+
print(f" state: {record.state}")
|
|
208
|
+
for p in record.positions:
|
|
209
|
+
print(f" {p['agent_id']}: {p['position']} (conf={p['confidence']})")
|
|
210
|
+
return 0
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def cmd_session_resolve(args: argparse.Namespace) -> int:
|
|
214
|
+
gcc_dir = _gcc_dir(args)
|
|
215
|
+
if not gcc_dir.exists():
|
|
216
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
217
|
+
return 1
|
|
218
|
+
resolver = DisagreementResolver(gcc_dir)
|
|
219
|
+
try:
|
|
220
|
+
record = resolver.resolve(
|
|
221
|
+
args.disagreement_id,
|
|
222
|
+
human_decision=args.decision,
|
|
223
|
+
)
|
|
224
|
+
except ValueError as exc:
|
|
225
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
226
|
+
return 1
|
|
227
|
+
print(f"Resolved disagreement {record.disagreement_id}: {record.state}")
|
|
228
|
+
if record.resolution:
|
|
229
|
+
print(f" resolution: {record.resolution}")
|
|
230
|
+
return 0
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def cmd_session_disagreements(args: argparse.Namespace) -> int:
|
|
234
|
+
gcc_dir = _gcc_dir(args)
|
|
235
|
+
if not gcc_dir.exists():
|
|
236
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
237
|
+
return 1
|
|
238
|
+
resolver = DisagreementResolver(gcc_dir)
|
|
239
|
+
records = resolver.list_disagreements(session_id=getattr(args, "session_id", None))
|
|
240
|
+
if not records:
|
|
241
|
+
print("No disagreements.")
|
|
242
|
+
return 0
|
|
243
|
+
print(f"{'ID':<36} {'Session':<24} {'Concept':<20} {'State':<14} {'Resolution'}")
|
|
244
|
+
print("-" * 100)
|
|
245
|
+
for r in records:
|
|
246
|
+
print(f"{r.disagreement_id:<36} {r.session_id:<24} {r.concept:<20} {r.state:<14} {r.resolution}")
|
|
247
|
+
return 0
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def cmd_simulate(args: argparse.Namespace) -> int:
|
|
251
|
+
gcc_dir = _gcc_dir(args)
|
|
252
|
+
if not gcc_dir.exists():
|
|
253
|
+
print(f"error: {gcc_dir} not found. Run `devtorch init` first.", file=sys.stderr)
|
|
254
|
+
return 1
|
|
255
|
+
assumptions: Dict[str, Any] = {}
|
|
256
|
+
for item in getattr(args, "assumptions", []) or []:
|
|
257
|
+
if "=" not in item:
|
|
258
|
+
print(f"error: --assume must be KEY=VALUE, got: {item}", file=sys.stderr)
|
|
259
|
+
return 1
|
|
260
|
+
k, v = item.split("=", 1)
|
|
261
|
+
assumptions[k.strip()] = v.strip()
|
|
262
|
+
simulator = WhatIfSimulator(gcc_dir)
|
|
263
|
+
try:
|
|
264
|
+
result = simulator.simulate(args.session_id, assumptions)
|
|
265
|
+
except ValueError as exc:
|
|
266
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
267
|
+
return 1
|
|
268
|
+
print(f"Simulation {result.simulation_id} for session {result.session_id}")
|
|
269
|
+
print(" alternate assumptions:")
|
|
270
|
+
for k, v in result.alternate_assumptions.items():
|
|
271
|
+
print(f" {k}: {v}")
|
|
272
|
+
print(" affected concepts:")
|
|
273
|
+
if result.affected_concepts:
|
|
274
|
+
for c in result.affected_concepts:
|
|
275
|
+
print(f" - {c}")
|
|
276
|
+
else:
|
|
277
|
+
print(" (none)")
|
|
278
|
+
print(" predicted outcome:")
|
|
279
|
+
print(result.predicted_outcome)
|
|
280
|
+
if getattr(args, "json", False):
|
|
281
|
+
print(json.dumps(result.to_dict(), indent=2))
|
|
282
|
+
return 0
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devtorch-cli
|
|
3
|
+
Version: 3.0.1
|
|
4
|
+
Summary: DevTorch — command-line interface for the devtorch-core governance SDK
|
|
5
|
+
Author-email: Hemant Joshi <hemant@flotorch.ai>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/hemantcgi/DevTorch
|
|
8
|
+
Project-URL: Repository, https://github.com/hemantcgi/DevTorch
|
|
9
|
+
Project-URL: Documentation, https://github.com/hemantcgi/DevTorch/blob/main/Implementation/README.md
|
|
10
|
+
Keywords: ai,agents,governance,audit,llm,reasoning,devtorch
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: devtorch-core>=3.0.1
|
|
23
|
+
Provides-Extra: cloud
|
|
24
|
+
Requires-Dist: devtorch-core[cloud]; extra == "cloud"
|
|
25
|
+
Provides-Extra: mcp
|
|
26
|
+
Requires-Dist: devtorch-core[mcp]; extra == "mcp"
|
|
27
|
+
Provides-Extra: audit
|
|
28
|
+
Requires-Dist: devtorch-core[audit]; extra == "audit"
|
|
29
|
+
Provides-Extra: proxy
|
|
30
|
+
Requires-Dist: devtorch-core[proxy]; extra == "proxy"
|
|
31
|
+
Provides-Extra: wrapper
|
|
32
|
+
Requires-Dist: devtorch-core[wrapper]; extra == "wrapper"
|
|
33
|
+
Provides-Extra: embeddings
|
|
34
|
+
Requires-Dist: devtorch-core[embeddings]; extra == "embeddings"
|
|
35
|
+
Provides-Extra: broadcast
|
|
36
|
+
Requires-Dist: devtorch-core[broadcast]; extra == "broadcast"
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: devtorch-core[dev]; extra == "dev"
|
|
39
|
+
Provides-Extra: all
|
|
40
|
+
Requires-Dist: devtorch-core[all]; extra == "all"
|
|
41
|
+
|
|
42
|
+
# devtorch-cli
|
|
43
|
+
|
|
44
|
+
Command-line interface for [DevTorch](https://github.com/hemantcgi/DevTorch), a local-first AI governance platform.
|
|
45
|
+
|
|
46
|
+
This package installs the `devtorch` command and depends on `devtorch-core`, which provides the governance SDK.
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install devtorch-cli
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For the full experience including cloud sync, MCP, and IDE wrappers:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install devtorch-cli[all]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
See the main repository README for detailed setup instructions.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
devtorch_cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
2
|
+
devtorch_cli/__main__.py,sha256=yOQ0W0lH4pSVd-goEkwkH24SCS405zHwDrhsCxQqCaA,171
|
|
3
|
+
devtorch_cli/audit_cmds.py,sha256=ZTVB7lmB7pYCCZpuZQscmeitfvs7-9VMe9K8wP5Fkwk,8605
|
|
4
|
+
devtorch_cli/capability_role_cmds.py,sha256=_j9rpresbPs496hBNGUVDszg2hq_qAq9JLGS4Bnf6nw,2975
|
|
5
|
+
devtorch_cli/main.py,sha256=dwb2Xr7OtBNJEYk8IyU8NGeEAPADlN3venV9e1ti_0o,174178
|
|
6
|
+
devtorch_cli/pr_reporter_cmd.py,sha256=wb9IRAWzWWXo7-esJDaIPHJTJS9y8WoTVlE1qepHgCU,1408
|
|
7
|
+
devtorch_cli/pre_commit_cmds.py,sha256=w3PeUr6z2NoP_7I98E6REuGCs_0bZjdrpsIMPNEEF-o,1113
|
|
8
|
+
devtorch_cli/session_cmds.py,sha256=hA6YhFkMwE0-an5LK4SswvVIaKuO4h-9V98RnUlqPGs,10280
|
|
9
|
+
devtorch_cli-3.0.1.dist-info/METADATA,sha256=tqHM3EQuI5YTAkkGm8ujbF4bA_5rmpcrvdwp3G-UD3A,2272
|
|
10
|
+
devtorch_cli-3.0.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
11
|
+
devtorch_cli-3.0.1.dist-info/entry_points.txt,sha256=iimCDbtjqjoEbpySI9sfLJAsZmPkz2_nHtWoHFgMvIk,52
|
|
12
|
+
devtorch_cli-3.0.1.dist-info/top_level.txt,sha256=FBW8lXo3q5SicN7Y27MikpGiBsjgQ_cWXE6mOUUQBPg,13
|
|
13
|
+
devtorch_cli-3.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
devtorch_cli
|