hap-cli 0.5.0__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.
- hap_cli/README.md +194 -0
- hap_cli/README_CN.md +601 -0
- hap_cli/__init__.py +3 -0
- hap_cli/commands/__init__.py +1 -0
- hap_cli/commands/ai_cmd.py +224 -0
- hap_cli/commands/app_cmd.py +308 -0
- hap_cli/commands/calendar_cmd.py +138 -0
- hap_cli/commands/chat_cmd.py +101 -0
- hap_cli/commands/config_cmd.py +169 -0
- hap_cli/commands/contact_cmd.py +125 -0
- hap_cli/commands/department_cmd.py +168 -0
- hap_cli/commands/group_cmd.py +128 -0
- hap_cli/commands/instance_cmd.py +310 -0
- hap_cli/commands/node_cmd.py +538 -0
- hap_cli/commands/optionset_cmd.py +99 -0
- hap_cli/commands/page_cmd.py +102 -0
- hap_cli/commands/plugin_cmd.py +133 -0
- hap_cli/commands/post_cmd.py +155 -0
- hap_cli/commands/record_cmd.py +228 -0
- hap_cli/commands/role_cmd.py +221 -0
- hap_cli/commands/workflow_cmd.py +284 -0
- hap_cli/commands/worksheet_cmd.py +342 -0
- hap_cli/context.py +43 -0
- hap_cli/core/__init__.py +1 -0
- hap_cli/core/ai.py +133 -0
- hap_cli/core/app.py +307 -0
- hap_cli/core/auth.py +219 -0
- hap_cli/core/calendar_mod.py +114 -0
- hap_cli/core/chat.py +73 -0
- hap_cli/core/contact.py +85 -0
- hap_cli/core/department.py +131 -0
- hap_cli/core/flow_node.py +1001 -0
- hap_cli/core/group.py +99 -0
- hap_cli/core/instance.py +572 -0
- hap_cli/core/optionset.py +112 -0
- hap_cli/core/page.py +138 -0
- hap_cli/core/plugin.py +87 -0
- hap_cli/core/post.py +118 -0
- hap_cli/core/record.py +268 -0
- hap_cli/core/role.py +227 -0
- hap_cli/core/session.py +348 -0
- hap_cli/core/workflow.py +556 -0
- hap_cli/core/worksheet.py +403 -0
- hap_cli/hap_cli.py +105 -0
- hap_cli/skills/SKILL.md +383 -0
- hap_cli/skills/__init__.py +0 -0
- hap_cli/tests/__init__.py +1 -0
- hap_cli/tests/test_core.py +1824 -0
- hap_cli/tests/test_full_e2e.py +136 -0
- hap_cli/tests/test_integration.py +805 -0
- hap_cli/utils/__init__.py +1 -0
- hap_cli/utils/formatting.py +111 -0
- hap_cli/utils/options.py +10 -0
- hap_cli-0.5.0.dist-info/METADATA +223 -0
- hap_cli-0.5.0.dist-info/RECORD +58 -0
- hap_cli-0.5.0.dist-info/WHEEL +5 -0
- hap_cli-0.5.0.dist-info/entry_points.txt +2 -0
- hap_cli-0.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"""CLI commands for workflow instance and approval management."""
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
|
|
5
|
+
from hap_cli.context import pass_context
|
|
6
|
+
from hap_cli.core import instance as inst_mod
|
|
7
|
+
from hap_cli.utils.formatting import output_json, output_table, output_kv
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@click.group()
|
|
11
|
+
def instance():
|
|
12
|
+
"""Workflow instance and approval management."""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@instance.command("todo-count")
|
|
17
|
+
@pass_context
|
|
18
|
+
def instance_todo_count(ctx):
|
|
19
|
+
"""Get count of pending workflow tasks."""
|
|
20
|
+
try:
|
|
21
|
+
session = ctx.get_session()
|
|
22
|
+
data = inst_mod.get_todo_count(session)
|
|
23
|
+
ctx.output(data, lambda d: output_kv(d))
|
|
24
|
+
except Exception as e:
|
|
25
|
+
ctx.handle_error(e)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@instance.command("todo")
|
|
29
|
+
@click.option("--type", "type_", default=-1, type=int,
|
|
30
|
+
help="Type: -1=all pending, 0=initiated, 3=fill, 4=approval, 5=view")
|
|
31
|
+
@click.option("--keyword", "-k", default="", help="Search keyword")
|
|
32
|
+
@click.option("--process-id", default="", help="Filter by process")
|
|
33
|
+
@click.option("--page-size", "-n", default=20, help="Items per page")
|
|
34
|
+
@click.option("--page", "-p", default=1, help="Page number")
|
|
35
|
+
@pass_context
|
|
36
|
+
def instance_todo(ctx, type_, keyword, process_id, page_size, page):
|
|
37
|
+
"""List pending tasks (todo list)."""
|
|
38
|
+
try:
|
|
39
|
+
session = ctx.get_session()
|
|
40
|
+
result = inst_mod.get_todo_list(
|
|
41
|
+
session, page_index=page, page_size=page_size,
|
|
42
|
+
type_=type_, keyword=keyword, process_id=process_id,
|
|
43
|
+
)
|
|
44
|
+
ctx.output(
|
|
45
|
+
result,
|
|
46
|
+
lambda d: output_table(
|
|
47
|
+
d.get("data", []),
|
|
48
|
+
["id", "title", "workId", "createDate"],
|
|
49
|
+
["Instance ID", "Title", "Work ID", "Created"],
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
ctx.handle_error(e)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@instance.command("get")
|
|
57
|
+
@click.argument("instance_id")
|
|
58
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
59
|
+
@pass_context
|
|
60
|
+
def instance_get(ctx, instance_id, work_id):
|
|
61
|
+
"""Get instance flow detail."""
|
|
62
|
+
try:
|
|
63
|
+
session = ctx.get_session()
|
|
64
|
+
data = inst_mod.get_instance_detail(session, instance_id, work_id)
|
|
65
|
+
ctx.output(data, lambda d: output_json(d))
|
|
66
|
+
except Exception as e:
|
|
67
|
+
ctx.handle_error(e)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@instance.command("operations")
|
|
71
|
+
@click.argument("instance_id")
|
|
72
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
73
|
+
@pass_context
|
|
74
|
+
def instance_operations(ctx, instance_id, work_id):
|
|
75
|
+
"""Get available operations for a task."""
|
|
76
|
+
try:
|
|
77
|
+
session = ctx.get_session()
|
|
78
|
+
data = inst_mod.get_operation_detail(session, instance_id, work_id)
|
|
79
|
+
ctx.output(data, lambda d: output_json(d))
|
|
80
|
+
except Exception as e:
|
|
81
|
+
ctx.handle_error(e)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@instance.command("op-history")
|
|
85
|
+
@click.argument("instance_id")
|
|
86
|
+
@pass_context
|
|
87
|
+
def instance_op_history(ctx, instance_id):
|
|
88
|
+
"""Get operation history of an instance."""
|
|
89
|
+
try:
|
|
90
|
+
session = ctx.get_session()
|
|
91
|
+
data = inst_mod.get_operation_history(session, instance_id)
|
|
92
|
+
ctx.output(data, lambda d: output_json(d))
|
|
93
|
+
except Exception as e:
|
|
94
|
+
ctx.handle_error(e)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@instance.command("approve")
|
|
98
|
+
@click.argument("instance_id")
|
|
99
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
100
|
+
@click.option("--opinion", "-o", default="", help="Approval comment")
|
|
101
|
+
@pass_context
|
|
102
|
+
def instance_approve(ctx, instance_id, work_id, opinion):
|
|
103
|
+
"""Approve/pass a workflow task."""
|
|
104
|
+
try:
|
|
105
|
+
session = ctx.get_session()
|
|
106
|
+
data = inst_mod.approve(session, instance_id, work_id, opinion)
|
|
107
|
+
ctx.output(data, lambda d: click.echo("Approved."))
|
|
108
|
+
except Exception as e:
|
|
109
|
+
ctx.handle_error(e)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@instance.command("reject")
|
|
113
|
+
@click.argument("instance_id")
|
|
114
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
115
|
+
@click.option("--opinion", "-o", default="", help="Rejection reason")
|
|
116
|
+
@click.option("--back-to", default="", help="Node ID to return to")
|
|
117
|
+
@pass_context
|
|
118
|
+
def instance_reject(ctx, instance_id, work_id, opinion, back_to):
|
|
119
|
+
"""Reject/overrule a workflow task."""
|
|
120
|
+
try:
|
|
121
|
+
session = ctx.get_session()
|
|
122
|
+
data = inst_mod.reject(
|
|
123
|
+
session, instance_id, work_id, opinion, back_node_id=back_to,
|
|
124
|
+
)
|
|
125
|
+
ctx.output(data, lambda d: click.echo("Rejected."))
|
|
126
|
+
except Exception as e:
|
|
127
|
+
ctx.handle_error(e)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@instance.command("forward")
|
|
131
|
+
@click.argument("instance_id")
|
|
132
|
+
@click.option("--to", "forward_to", required=True, help="Target user account ID")
|
|
133
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
134
|
+
@click.option("--opinion", "-o", default="", help="Forward comment")
|
|
135
|
+
@pass_context
|
|
136
|
+
def instance_forward(ctx, instance_id, forward_to, work_id, opinion):
|
|
137
|
+
"""Forward a task to another user."""
|
|
138
|
+
try:
|
|
139
|
+
session = ctx.get_session()
|
|
140
|
+
data = inst_mod.forward(session, instance_id, forward_to, work_id, opinion)
|
|
141
|
+
ctx.output(data, lambda d: click.echo("Forwarded."))
|
|
142
|
+
except Exception as e:
|
|
143
|
+
ctx.handle_error(e)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@instance.command("sign")
|
|
147
|
+
@click.argument("instance_id")
|
|
148
|
+
@click.option("--to", "sign_to", required=True, help="Co-signer user ID")
|
|
149
|
+
@click.option("--before/--after", default=True, help="Sign before or after current user")
|
|
150
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
151
|
+
@click.option("--opinion", "-o", default="", help="Comment")
|
|
152
|
+
@pass_context
|
|
153
|
+
def instance_sign(ctx, instance_id, sign_to, before, work_id, opinion):
|
|
154
|
+
"""Add a co-signer to a task."""
|
|
155
|
+
try:
|
|
156
|
+
session = ctx.get_session()
|
|
157
|
+
data = inst_mod.sign_task(
|
|
158
|
+
session, instance_id, sign_to, before=before,
|
|
159
|
+
work_id=work_id, opinion=opinion,
|
|
160
|
+
)
|
|
161
|
+
ctx.output(data, lambda d: click.echo("Co-signer added."))
|
|
162
|
+
except Exception as e:
|
|
163
|
+
ctx.handle_error(e)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@instance.command("submit")
|
|
167
|
+
@click.argument("instance_id")
|
|
168
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
169
|
+
@click.option("--opinion", "-o", default="", help="Submit comment")
|
|
170
|
+
@pass_context
|
|
171
|
+
def instance_submit(ctx, instance_id, work_id, opinion):
|
|
172
|
+
"""Submit a fill-in task."""
|
|
173
|
+
try:
|
|
174
|
+
session = ctx.get_session()
|
|
175
|
+
data = inst_mod.submit(session, instance_id, work_id, opinion)
|
|
176
|
+
ctx.output(data, lambda d: click.echo("Submitted."))
|
|
177
|
+
except Exception as e:
|
|
178
|
+
ctx.handle_error(e)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@instance.command("revoke")
|
|
182
|
+
@click.argument("instance_id")
|
|
183
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
184
|
+
@pass_context
|
|
185
|
+
def instance_revoke(ctx, instance_id, work_id):
|
|
186
|
+
"""Revoke/withdraw a submitted instance."""
|
|
187
|
+
try:
|
|
188
|
+
session = ctx.get_session()
|
|
189
|
+
data = inst_mod.revoke(session, instance_id, work_id)
|
|
190
|
+
ctx.output(data, lambda d: click.echo("Revoked."))
|
|
191
|
+
except Exception as e:
|
|
192
|
+
ctx.handle_error(e)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@instance.command("urge")
|
|
196
|
+
@click.argument("instance_id")
|
|
197
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
198
|
+
@pass_context
|
|
199
|
+
def instance_urge(ctx, instance_id, work_id):
|
|
200
|
+
"""Send an urge/reminder for a pending task."""
|
|
201
|
+
try:
|
|
202
|
+
session = ctx.get_session()
|
|
203
|
+
data = inst_mod.urge(session, instance_id, work_id)
|
|
204
|
+
ctx.output(data, lambda d: click.echo("Urge sent."))
|
|
205
|
+
except Exception as e:
|
|
206
|
+
ctx.handle_error(e)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@instance.command("terminate")
|
|
210
|
+
@click.argument("instance_id")
|
|
211
|
+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation")
|
|
212
|
+
@pass_context
|
|
213
|
+
def instance_terminate(ctx, instance_id, yes):
|
|
214
|
+
"""Terminate a running instance."""
|
|
215
|
+
try:
|
|
216
|
+
if not yes:
|
|
217
|
+
click.confirm(f"Terminate instance {instance_id}?", abort=True)
|
|
218
|
+
session = ctx.get_session()
|
|
219
|
+
data = inst_mod.end_instance(session, instance_id)
|
|
220
|
+
ctx.output(data, lambda d: click.echo("Instance terminated."))
|
|
221
|
+
except Exception as e:
|
|
222
|
+
ctx.handle_error(e)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@instance.command("retry")
|
|
226
|
+
@click.argument("instance_id")
|
|
227
|
+
@pass_context
|
|
228
|
+
def instance_retry(ctx, instance_id):
|
|
229
|
+
"""Retry a failed instance."""
|
|
230
|
+
try:
|
|
231
|
+
session = ctx.get_session()
|
|
232
|
+
data = inst_mod.reset_instance(session, instance_id)
|
|
233
|
+
ctx.output(data, lambda d: click.echo("Instance retried."))
|
|
234
|
+
except Exception as e:
|
|
235
|
+
ctx.handle_error(e)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@instance.command("restart")
|
|
239
|
+
@click.argument("instance_id")
|
|
240
|
+
@click.option("--work-id", "-w", default="", help="Work item ID")
|
|
241
|
+
@pass_context
|
|
242
|
+
def instance_restart(ctx, instance_id, work_id):
|
|
243
|
+
"""Re-initiate a completed/rejected instance."""
|
|
244
|
+
try:
|
|
245
|
+
session = ctx.get_session()
|
|
246
|
+
data = inst_mod.restart_instance(session, instance_id, work_id)
|
|
247
|
+
ctx.output(data, lambda d: click.echo("Instance restarted."))
|
|
248
|
+
except Exception as e:
|
|
249
|
+
ctx.handle_error(e)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@instance.command("history")
|
|
253
|
+
@click.option("--process-id", default="", help="Filter by process")
|
|
254
|
+
@click.option("--status", "-s", default=0, type=int,
|
|
255
|
+
help="Status: 1=running, 2=completed, 3=rejected, 4=failed")
|
|
256
|
+
@click.option("--keyword", "-k", default="", help="Title search")
|
|
257
|
+
@click.option("--page-size", "-n", default=20, help="Items per page")
|
|
258
|
+
@click.option("--page", "-p", default=1, help="Page number")
|
|
259
|
+
@pass_context
|
|
260
|
+
def instance_history(ctx, process_id, status, keyword, page_size, page):
|
|
261
|
+
"""Get workflow execution history."""
|
|
262
|
+
try:
|
|
263
|
+
session = ctx.get_session()
|
|
264
|
+
result = inst_mod.get_history_list(
|
|
265
|
+
session, process_id=process_id, status=status,
|
|
266
|
+
title=keyword, page_index=page, page_size=page_size,
|
|
267
|
+
)
|
|
268
|
+
ctx.output(
|
|
269
|
+
result,
|
|
270
|
+
lambda d: output_table(
|
|
271
|
+
d.get("data", []),
|
|
272
|
+
["instanceId", "title", "status", "createDate", "completeDate"],
|
|
273
|
+
["Instance ID", "Title", "Status", "Created", "Completed"],
|
|
274
|
+
),
|
|
275
|
+
)
|
|
276
|
+
except Exception as e:
|
|
277
|
+
ctx.handle_error(e)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@instance.command("history-detail")
|
|
281
|
+
@click.argument("instance_id")
|
|
282
|
+
@pass_context
|
|
283
|
+
def instance_history_detail(ctx, instance_id):
|
|
284
|
+
"""Get execution history detail with node info."""
|
|
285
|
+
try:
|
|
286
|
+
session = ctx.get_session()
|
|
287
|
+
data = inst_mod.get_history_detail(session, instance_id)
|
|
288
|
+
ctx.output(data, lambda d: output_json(d))
|
|
289
|
+
except Exception as e:
|
|
290
|
+
ctx.handle_error(e)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@instance.command("batch")
|
|
294
|
+
@click.option("--action", "-a", required=True, type=int, help="4=batch approve, 5=batch reject")
|
|
295
|
+
@click.option("--type", "type_", default=-1, type=int, help="Task type filter")
|
|
296
|
+
@click.option("--process-id", default="", help="Filter by process")
|
|
297
|
+
@click.option("--select", "-s", multiple=True, help="Selected instance IDs")
|
|
298
|
+
@pass_context
|
|
299
|
+
def instance_batch(ctx, action, type_, process_id, select):
|
|
300
|
+
"""Batch approve or reject tasks."""
|
|
301
|
+
try:
|
|
302
|
+
session = ctx.get_session()
|
|
303
|
+
data = inst_mod.batch_operation(
|
|
304
|
+
session, action,
|
|
305
|
+
type_=type_, process_id=process_id,
|
|
306
|
+
selects=list(select) if select else None,
|
|
307
|
+
)
|
|
308
|
+
ctx.output(data, lambda d: click.echo(f"Batch operation completed: {d}"))
|
|
309
|
+
except Exception as e:
|
|
310
|
+
ctx.handle_error(e)
|