@awiki/cli 0.0.1-beta.2
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.
- package/.github/workflows/release.yml +44 -0
- package/.goreleaser.yml +44 -0
- package/AGENTS.md +60 -0
- package/CLAUDE.md +192 -0
- package/README.md +2 -0
- package/docs/architecture/awiki-command-v2.md +955 -0
- package/docs/architecture/awiki-skill-architecture.md +475 -0
- package/docs/architecture/awiki-v2-architecture.md +1063 -0
- package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/cli-init.md +1008 -0
- package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/output-format.md +407 -0
- package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/overall-init.md +741 -0
- package/docs/harness/review-spec.md +474 -0
- package/docs/installation.md +372 -0
- package/docs/plan/awiki-v2-implementation-plan.md +903 -0
- package/docs/plan/phase-0/adr-index.md +56 -0
- package/docs/plan/phase-0/audit-findings.md +251 -0
- package/docs/plan/phase-0/capability-mapping.md +108 -0
- package/docs/plan/phase-0/implementation-constraints.md +363 -0
- package/docs/publish.md +169 -0
- package/go.mod +29 -0
- package/go.sum +73 -0
- package/internal/anpsdk/registry.go +63 -0
- package/internal/authsdk/session.go +351 -0
- package/internal/buildinfo/buildinfo.go +34 -0
- package/internal/cli/app.go +136 -0
- package/internal/cli/app_test.go +88 -0
- package/internal/cli/debug.go +104 -0
- package/internal/cli/group.go +263 -0
- package/internal/cli/id.go +473 -0
- package/internal/cli/init.go +134 -0
- package/internal/cli/msg.go +228 -0
- package/internal/cli/page.go +267 -0
- package/internal/cli/root.go +499 -0
- package/internal/cli/runtime.go +232 -0
- package/internal/cli/upgrade.go +60 -0
- package/internal/cmdmeta/catalog.go +203 -0
- package/internal/cmdmeta/catalog_test.go +21 -0
- package/internal/config/config.go +399 -0
- package/internal/config/config_test.go +104 -0
- package/internal/config/write.go +37 -0
- package/internal/content/service.go +314 -0
- package/internal/content/service_test.go +165 -0
- package/internal/content/types.go +44 -0
- package/internal/docs/topics.go +110 -0
- package/internal/doctor/doctor.go +306 -0
- package/internal/identity/client.go +267 -0
- package/internal/identity/did.go +85 -0
- package/internal/identity/did_test.go +50 -0
- package/internal/identity/layout.go +206 -0
- package/internal/identity/legacy.go +378 -0
- package/internal/identity/public.go +70 -0
- package/internal/identity/public_test.go +73 -0
- package/internal/identity/readiness.go +74 -0
- package/internal/identity/service.go +826 -0
- package/internal/identity/store.go +385 -0
- package/internal/identity/store_test.go +180 -0
- package/internal/identity/types.go +204 -0
- package/internal/message/auth.go +167 -0
- package/internal/message/group_service.go +838 -0
- package/internal/message/group_wire.go +350 -0
- package/internal/message/group_wire_test.go +67 -0
- package/internal/message/helpers.go +61 -0
- package/internal/message/http_client.go +334 -0
- package/internal/message/proof.go +156 -0
- package/internal/message/proof_test.go +61 -0
- package/internal/message/service.go +696 -0
- package/internal/message/service_test.go +97 -0
- package/internal/message/types.go +155 -0
- package/internal/message/wire.go +100 -0
- package/internal/message/wire_test.go +49 -0
- package/internal/message/ws_proxy_client.go +151 -0
- package/internal/output/output.go +350 -0
- package/internal/output/output_test.go +48 -0
- package/internal/runtime/config.go +117 -0
- package/internal/runtime/config_test.go +46 -0
- package/internal/runtime/listener/files.go +65 -0
- package/internal/runtime/listener/manager.go +142 -0
- package/internal/runtime/listener/server.go +983 -0
- package/internal/runtime/listener/server_test.go +319 -0
- package/internal/runtime/listener/sysproc_unix.go +17 -0
- package/internal/runtime/listener/sysproc_windows.go +13 -0
- package/internal/runtime/listener/types.go +21 -0
- package/internal/runtime/listener/wsclient.go +299 -0
- package/internal/runtime/listener/wsclient_test.go +41 -0
- package/internal/store/dao.go +632 -0
- package/internal/store/dao_test.go +87 -0
- package/internal/store/helpers.go +197 -0
- package/internal/store/import.go +499 -0
- package/internal/store/import_test.go +103 -0
- package/internal/store/open.go +71 -0
- package/internal/store/query.go +151 -0
- package/internal/store/schema.go +277 -0
- package/internal/store/schema_test.go +56 -0
- package/internal/store/types.go +177 -0
- package/internal/update/update.go +368 -0
- package/package.json +17 -0
- package/scripts/install.js +171 -0
- package/scripts/release/release-prerelease.sh +86 -0
- package/scripts/release/tag-release.sh +66 -0
- package/scripts/release/withdraw-release.sh +78 -0
- package/scripts/run.js +69 -0
- package/skills/README.md +32 -0
- package/skills/awiki-bundle/SKILL.md +76 -0
- package/skills/awiki-debug/SKILL.md +80 -0
- package/skills/awiki-group/SKILL.md +111 -0
- package/skills/awiki-id/SKILL.md +123 -0
- package/skills/awiki-msg/SKILL.md +131 -0
- package/skills/awiki-page/SKILL.md +93 -0
- package/skills/awiki-people/SKILL.md +66 -0
- package/skills/awiki-runtime/SKILL.md +137 -0
- package/skills/awiki-shared/SKILL.md +124 -0
- package/skills/awiki-workflow-discovery/SKILL.md +93 -0
- package/skills/awiki-workflow-onboarding/SKILL.md +119 -0
- package/skills/manifests/skills.yaml +260 -0
- package/skills/templates/bundle-skill-template.md +42 -0
- package/skills/templates/debug-skill-template.md +44 -0
- package/skills/templates/domain-skill-template.md +56 -0
- package/skills/templates/shared-skill-template.md +46 -0
- package/skills/templates/workflow-skill-template.md +46 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
package cli
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"database/sql"
|
|
6
|
+
"errors"
|
|
7
|
+
"strings"
|
|
8
|
+
|
|
9
|
+
appconfig "github.com/agentconnect/awiki-cli/internal/config"
|
|
10
|
+
"github.com/agentconnect/awiki-cli/internal/identity"
|
|
11
|
+
"github.com/agentconnect/awiki-cli/internal/output"
|
|
12
|
+
"github.com/agentconnect/awiki-cli/internal/store"
|
|
13
|
+
"github.com/spf13/cobra"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
func (a *App) openStore() (*appconfig.Resolved, *sql.DB, output.Format, error) {
|
|
17
|
+
resolved, err := a.resolveConfig()
|
|
18
|
+
if err != nil {
|
|
19
|
+
return nil, nil, output.FormatJSON, err
|
|
20
|
+
}
|
|
21
|
+
format := normalizedFormat(resolved.OutputFormat)
|
|
22
|
+
db, err := store.Open(resolved.Paths)
|
|
23
|
+
if err != nil {
|
|
24
|
+
return resolved, nil, format, err
|
|
25
|
+
}
|
|
26
|
+
return resolved, db, format, nil
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func (a *App) storeExit(err error, hint string) error {
|
|
30
|
+
if err == nil {
|
|
31
|
+
return nil
|
|
32
|
+
}
|
|
33
|
+
switch {
|
|
34
|
+
case errors.Is(err, store.ErrLegacyDatabaseNotFound), errors.Is(err, sql.ErrNoRows):
|
|
35
|
+
return output.NewExitError("not_found", 5, err.Error(), hint)
|
|
36
|
+
case errors.Is(err, store.ErrUnsafeSQL), errors.Is(err, store.ErrUnsupportedLegacySchema):
|
|
37
|
+
return output.NewExitError("invalid_argument", 2, err.Error(), hint)
|
|
38
|
+
default:
|
|
39
|
+
return output.NewExitError("internal_error", 1, err.Error(), hint)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
func (a *App) runDebugDBQuery(cmd *cobra.Command, args []string) error {
|
|
44
|
+
if len(args) != 1 {
|
|
45
|
+
return output.NewExitError("invalid_argument", 2, "debug db query requires exactly one SQL statement.", "Usage: awiki-cli debug db query \"SELECT * FROM messages LIMIT 5\"")
|
|
46
|
+
}
|
|
47
|
+
resolved, db, format, err := a.openStore()
|
|
48
|
+
if err != nil {
|
|
49
|
+
return a.storeExit(err, "Run `awiki-cli doctor` to inspect the database path and configuration.")
|
|
50
|
+
}
|
|
51
|
+
defer db.Close()
|
|
52
|
+
if err := store.EnsureSchema(context.Background(), db); err != nil {
|
|
53
|
+
return a.storeExit(err, "Initialize the local store before querying it.")
|
|
54
|
+
}
|
|
55
|
+
rows, err := store.ExecuteSQL(context.Background(), db, args[0])
|
|
56
|
+
if err != nil {
|
|
57
|
+
return a.storeExit(err, "Only single-statement safe SQL is allowed. Avoid destructive statements.")
|
|
58
|
+
}
|
|
59
|
+
data := map[string]any{
|
|
60
|
+
"database_file": resolved.Paths.DatabaseFile,
|
|
61
|
+
"rows": rows,
|
|
62
|
+
}
|
|
63
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, data, "SQLite query executed", nil, identityMetaFromResolved(resolved))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
func (a *App) runDebugDBImportV1(cmd *cobra.Command, args []string) error {
|
|
67
|
+
pathOverride, _ := cmd.Flags().GetString("path")
|
|
68
|
+
resolved, db, format, err := a.openStore()
|
|
69
|
+
if err != nil {
|
|
70
|
+
return a.storeExit(err, "Run `awiki-cli doctor` to inspect the database path and configuration.")
|
|
71
|
+
}
|
|
72
|
+
defer db.Close()
|
|
73
|
+
if err := store.EnsureSchema(context.Background(), db); err != nil {
|
|
74
|
+
return a.storeExit(err, "Initialize the local store before importing legacy data.")
|
|
75
|
+
}
|
|
76
|
+
paths := resolved.Paths
|
|
77
|
+
if strings.TrimSpace(pathOverride) != "" {
|
|
78
|
+
paths.LegacyDataDir = strings.TrimSpace(pathOverride)
|
|
79
|
+
}
|
|
80
|
+
manager := identity.NewManager(paths)
|
|
81
|
+
if a.globals.DryRun {
|
|
82
|
+
scan, err := store.ScanLegacyDatabase(context.Background(), paths)
|
|
83
|
+
if err != nil {
|
|
84
|
+
return a.storeExit(err, "Make sure the legacy database path is correct.")
|
|
85
|
+
}
|
|
86
|
+
data := map[string]any{
|
|
87
|
+
"plan": map[string]any{
|
|
88
|
+
"action": "import_v1_sqlite",
|
|
89
|
+
"source_scan": scan,
|
|
90
|
+
"target": resolved.Paths.DatabaseFile,
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, data, "Dry run: legacy SQLite import planned", nil, identityMetaFromResolved(resolved))
|
|
94
|
+
}
|
|
95
|
+
report, err := store.ImportLegacyDatabase(context.Background(), db, paths, manager)
|
|
96
|
+
if err != nil {
|
|
97
|
+
return a.storeExit(err, "Make sure the v1 database exists and identities were imported first.")
|
|
98
|
+
}
|
|
99
|
+
data := map[string]any{
|
|
100
|
+
"database_file": resolved.Paths.DatabaseFile,
|
|
101
|
+
"import_report": report,
|
|
102
|
+
}
|
|
103
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, data, "Legacy SQLite import completed", report.Warnings, identityMetaFromResolved(resolved))
|
|
104
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
package cli
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"strconv"
|
|
6
|
+
"strings"
|
|
7
|
+
|
|
8
|
+
"github.com/agentconnect/awiki-cli/internal/message"
|
|
9
|
+
"github.com/spf13/cobra"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
func (a *App) runGroupCreate(cmd *cobra.Command, args []string) error {
|
|
13
|
+
name, _ := cmd.Flags().GetString("name")
|
|
14
|
+
description, _ := cmd.Flags().GetString("description")
|
|
15
|
+
discoverability, _ := cmd.Flags().GetString("discoverability")
|
|
16
|
+
admissionMode, _ := cmd.Flags().GetString("admission-mode")
|
|
17
|
+
slug, _ := cmd.Flags().GetString("slug")
|
|
18
|
+
goal, _ := cmd.Flags().GetString("goal")
|
|
19
|
+
rules, _ := cmd.Flags().GetString("rules")
|
|
20
|
+
messagePrompt, _ := cmd.Flags().GetString("message-prompt")
|
|
21
|
+
docURL, _ := cmd.Flags().GetString("doc-url")
|
|
22
|
+
maxMembers, _ := cmd.Flags().GetString("max-members")
|
|
23
|
+
attachmentsAllowed := boolFlagPtr(cmd, "attachments-allowed")
|
|
24
|
+
memberMaxMessages := int64FlagPtr(cmd, "member-max-messages")
|
|
25
|
+
memberMaxTotalChars := int64FlagPtr(cmd, "member-max-total-chars")
|
|
26
|
+
service, format, err := a.messageService()
|
|
27
|
+
if err != nil {
|
|
28
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
29
|
+
}
|
|
30
|
+
request := message.GroupCreateRequest{
|
|
31
|
+
IdentityName: a.globals.Identity,
|
|
32
|
+
Name: name,
|
|
33
|
+
Description: description,
|
|
34
|
+
Discoverability: discoverability,
|
|
35
|
+
AdmissionMode: admissionMode,
|
|
36
|
+
Slug: slug,
|
|
37
|
+
Goal: goal,
|
|
38
|
+
Rules: rules,
|
|
39
|
+
MessagePrompt: messagePrompt,
|
|
40
|
+
DocURL: docURL,
|
|
41
|
+
AttachmentsAllowed: attachmentsAllowed,
|
|
42
|
+
MaxMembers: maxMembers,
|
|
43
|
+
MemberMaxMessages: memberMaxMessages,
|
|
44
|
+
MemberMaxTotalChars: memberMaxTotalChars,
|
|
45
|
+
}
|
|
46
|
+
if a.globals.DryRun {
|
|
47
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group.create", "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "request": request}}, "Dry run: group create planned", nil, a.identityMeta())
|
|
48
|
+
}
|
|
49
|
+
result, err := service.CreateGroup(context.Background(), request)
|
|
50
|
+
if err != nil {
|
|
51
|
+
return a.messageExit(err, "Ensure the active identity is registered and the message service is reachable.")
|
|
52
|
+
}
|
|
53
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
func (a *App) runGroupShow(cmd *cobra.Command, args []string) error {
|
|
57
|
+
group, _ := cmd.Flags().GetString("group")
|
|
58
|
+
service, format, err := a.messageService()
|
|
59
|
+
if err != nil {
|
|
60
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
61
|
+
}
|
|
62
|
+
request := message.GroupGetRequest{IdentityName: a.globals.Identity, Group: group}
|
|
63
|
+
if a.globals.DryRun {
|
|
64
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group.show", "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "group": group}}, "Dry run: group show planned", nil, a.identityMeta())
|
|
65
|
+
}
|
|
66
|
+
result, err := service.GetGroup(context.Background(), request)
|
|
67
|
+
if err != nil {
|
|
68
|
+
return a.messageExit(err, "Make sure the group exists and the active identity can access it.")
|
|
69
|
+
}
|
|
70
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
func (a *App) runGroupJoin(cmd *cobra.Command, args []string) error {
|
|
74
|
+
group, _ := cmd.Flags().GetString("group")
|
|
75
|
+
reason, _ := cmd.Flags().GetString("reason")
|
|
76
|
+
service, format, err := a.messageService()
|
|
77
|
+
if err != nil {
|
|
78
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
79
|
+
}
|
|
80
|
+
request := message.GroupJoinRequest{IdentityName: a.globals.Identity, Group: group, ReasonText: reason}
|
|
81
|
+
if a.globals.DryRun {
|
|
82
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group.join", "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "request": request}}, "Dry run: group join planned", nil, a.identityMeta())
|
|
83
|
+
}
|
|
84
|
+
result, err := service.JoinGroup(context.Background(), request)
|
|
85
|
+
if err != nil {
|
|
86
|
+
return a.messageExit(err, "Make sure the group exists and allows open join for the active identity.")
|
|
87
|
+
}
|
|
88
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func (a *App) runGroupAdd(cmd *cobra.Command, args []string) error {
|
|
92
|
+
return a.runGroupMemberMutation(cmd, "add", "add")
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
func (a *App) runGroupKick(cmd *cobra.Command, args []string) error {
|
|
96
|
+
return a.runGroupMemberMutation(cmd, "kick", "remove")
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
func (a *App) runGroupMemberMutation(cmd *cobra.Command, publicAction string, memberAction string) error {
|
|
100
|
+
group, _ := cmd.Flags().GetString("group")
|
|
101
|
+
member, _ := cmd.Flags().GetString("member")
|
|
102
|
+
role, _ := cmd.Flags().GetString("role")
|
|
103
|
+
reason, _ := cmd.Flags().GetString("reason")
|
|
104
|
+
service, format, err := a.messageService()
|
|
105
|
+
if err != nil {
|
|
106
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
107
|
+
}
|
|
108
|
+
request := message.GroupMemberRequest{IdentityName: a.globals.Identity, Group: group, Member: member, Role: role, ReasonText: reason}
|
|
109
|
+
if a.globals.DryRun {
|
|
110
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group." + publicAction, "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "request": request}}, "Dry run: group membership change planned", nil, a.identityMeta())
|
|
111
|
+
}
|
|
112
|
+
var result *message.CommandResult
|
|
113
|
+
if memberAction == "add" {
|
|
114
|
+
result, err = service.AddGroupMember(context.Background(), request)
|
|
115
|
+
} else {
|
|
116
|
+
result, err = service.RemoveGroupMember(context.Background(), request)
|
|
117
|
+
}
|
|
118
|
+
if err != nil {
|
|
119
|
+
return a.messageExit(err, "Make sure the group and member exist and the active identity has the required role.")
|
|
120
|
+
}
|
|
121
|
+
switch publicAction {
|
|
122
|
+
case "add":
|
|
123
|
+
result.Summary = "Added member to group"
|
|
124
|
+
case "kick":
|
|
125
|
+
result.Summary = "Removed member from group"
|
|
126
|
+
}
|
|
127
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
func (a *App) runGroupLeave(cmd *cobra.Command, args []string) error {
|
|
131
|
+
group, _ := cmd.Flags().GetString("group")
|
|
132
|
+
service, format, err := a.messageService()
|
|
133
|
+
if err != nil {
|
|
134
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
135
|
+
}
|
|
136
|
+
request := message.GroupLeaveRequest{IdentityName: a.globals.Identity, Group: group}
|
|
137
|
+
if a.globals.DryRun {
|
|
138
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group.leave", "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "request": request}}, "Dry run: group leave planned", nil, a.identityMeta())
|
|
139
|
+
}
|
|
140
|
+
result, err := service.LeaveGroup(context.Background(), request)
|
|
141
|
+
if err != nil {
|
|
142
|
+
return a.messageExit(err, "Make sure the group exists and the active identity is still a member.")
|
|
143
|
+
}
|
|
144
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
func (a *App) runGroupUpdate(cmd *cobra.Command, args []string) error {
|
|
148
|
+
group, _ := cmd.Flags().GetString("group")
|
|
149
|
+
name, _ := cmd.Flags().GetString("name")
|
|
150
|
+
description, _ := cmd.Flags().GetString("description")
|
|
151
|
+
discoverability, _ := cmd.Flags().GetString("discoverability")
|
|
152
|
+
admissionMode, _ := cmd.Flags().GetString("admission-mode")
|
|
153
|
+
slug, _ := cmd.Flags().GetString("slug")
|
|
154
|
+
goal, _ := cmd.Flags().GetString("goal")
|
|
155
|
+
rules, _ := cmd.Flags().GetString("rules")
|
|
156
|
+
messagePrompt, _ := cmd.Flags().GetString("message-prompt")
|
|
157
|
+
docURL, _ := cmd.Flags().GetString("doc-url")
|
|
158
|
+
maxMembers, _ := cmd.Flags().GetString("max-members")
|
|
159
|
+
attachmentsAllowed := boolFlagPtr(cmd, "attachments-allowed")
|
|
160
|
+
memberMaxMessages := int64FlagPtr(cmd, "member-max-messages")
|
|
161
|
+
memberMaxTotalChars := int64FlagPtr(cmd, "member-max-total-chars")
|
|
162
|
+
service, format, err := a.messageService()
|
|
163
|
+
if err != nil {
|
|
164
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
165
|
+
}
|
|
166
|
+
request := message.GroupUpdateRequest{
|
|
167
|
+
IdentityName: a.globals.Identity,
|
|
168
|
+
Group: group,
|
|
169
|
+
Name: name,
|
|
170
|
+
Description: description,
|
|
171
|
+
Discoverability: discoverability,
|
|
172
|
+
AdmissionMode: admissionMode,
|
|
173
|
+
Slug: slug,
|
|
174
|
+
Goal: goal,
|
|
175
|
+
Rules: rules,
|
|
176
|
+
MessagePrompt: messagePrompt,
|
|
177
|
+
DocURL: docURL,
|
|
178
|
+
AttachmentsAllowed: attachmentsAllowed,
|
|
179
|
+
MaxMembers: maxMembers,
|
|
180
|
+
MemberMaxMessages: memberMaxMessages,
|
|
181
|
+
MemberMaxTotalChars: memberMaxTotalChars,
|
|
182
|
+
}
|
|
183
|
+
if a.globals.DryRun {
|
|
184
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group.update", "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "request": request}}, "Dry run: group update planned", nil, a.identityMeta())
|
|
185
|
+
}
|
|
186
|
+
result, err := service.UpdateGroup(context.Background(), request)
|
|
187
|
+
if err != nil {
|
|
188
|
+
return a.messageExit(err, "Make sure the active identity has permission to update the target group.")
|
|
189
|
+
}
|
|
190
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
func (a *App) runGroupMembers(cmd *cobra.Command, args []string) error {
|
|
194
|
+
group, _ := cmd.Flags().GetString("group")
|
|
195
|
+
limit, _ := cmd.Flags().GetInt("limit")
|
|
196
|
+
service, format, err := a.messageService()
|
|
197
|
+
if err != nil {
|
|
198
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
199
|
+
}
|
|
200
|
+
request := message.GroupMembersRequest{IdentityName: a.globals.Identity, Group: group, Limit: limit}
|
|
201
|
+
if a.globals.DryRun {
|
|
202
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group.list_members", "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "request": request}}, "Dry run: group members planned", nil, a.identityMeta())
|
|
203
|
+
}
|
|
204
|
+
result, err := service.GroupMembers(context.Background(), request)
|
|
205
|
+
if err != nil {
|
|
206
|
+
return a.messageExit(err, "Make sure the group exists and the active identity can access its member list.")
|
|
207
|
+
}
|
|
208
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
func (a *App) runGroupMessages(cmd *cobra.Command, args []string) error {
|
|
212
|
+
group, _ := cmd.Flags().GetString("group")
|
|
213
|
+
limit, _ := cmd.Flags().GetInt("limit")
|
|
214
|
+
cursor, _ := cmd.Flags().GetString("cursor")
|
|
215
|
+
service, format, err := a.messageService()
|
|
216
|
+
if err != nil {
|
|
217
|
+
return a.messageExit(err, "Run `awiki-cli doctor` to inspect configuration and identity state.")
|
|
218
|
+
}
|
|
219
|
+
request := message.GroupMessagesRequest{IdentityName: a.globals.Identity, Group: group, Limit: limit, Cursor: cursor}
|
|
220
|
+
if a.globals.DryRun {
|
|
221
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, map[string]any{"plan": map[string]any{"action": "group.list_messages", "identity": a.globals.Identity, "runtime_mode": service.Config().RuntimeMode, "request": request}}, "Dry run: group messages planned", nil, a.identityMeta())
|
|
222
|
+
}
|
|
223
|
+
result, err := service.GroupMessages(context.Background(), request)
|
|
224
|
+
if err != nil {
|
|
225
|
+
return a.messageExit(err, "Make sure the group exists and the active identity can access its messages.")
|
|
226
|
+
}
|
|
227
|
+
return a.renderSuccess(cmd.CommandPath(), format, a.globals.JQ, result.Data, result.Summary, result.Warnings, a.identityMeta())
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
func boolFlagPtr(cmd *cobra.Command, name string) *bool {
|
|
231
|
+
if !cmd.Flags().Changed(name) {
|
|
232
|
+
return nil
|
|
233
|
+
}
|
|
234
|
+
value, err := cmd.Flags().GetBool(name)
|
|
235
|
+
if err != nil {
|
|
236
|
+
return nil
|
|
237
|
+
}
|
|
238
|
+
return &value
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
func int64FlagPtr(cmd *cobra.Command, name string) *int64 {
|
|
242
|
+
if !cmd.Flags().Changed(name) {
|
|
243
|
+
return nil
|
|
244
|
+
}
|
|
245
|
+
value, err := cmd.Flags().GetInt(name)
|
|
246
|
+
if err != nil {
|
|
247
|
+
return nil
|
|
248
|
+
}
|
|
249
|
+
result := int64(value)
|
|
250
|
+
return &result
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
func parseInt64OrEmpty(value string) *int64 {
|
|
254
|
+
value = strings.TrimSpace(value)
|
|
255
|
+
if value == "" {
|
|
256
|
+
return nil
|
|
257
|
+
}
|
|
258
|
+
parsed, err := strconv.ParseInt(value, 10, 64)
|
|
259
|
+
if err != nil {
|
|
260
|
+
return nil
|
|
261
|
+
}
|
|
262
|
+
return &parsed
|
|
263
|
+
}
|