@geoly-ai/social-hub-cli 0.0.1
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/dist/client.d.ts +5 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +23 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +96 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +13 -0
- package/dist/config.test.js.map +1 -0
- package/dist/context-state.d.ts +9 -0
- package/dist/context-state.d.ts.map +1 -0
- package/dist/context-state.js +29 -0
- package/dist/context-state.js.map +1 -0
- package/dist/dry-run.d.ts +12 -0
- package/dist/dry-run.d.ts.map +1 -0
- package/dist/dry-run.js +18 -0
- package/dist/dry-run.js.map +1 -0
- package/dist/dry-run.test.d.ts +2 -0
- package/dist/dry-run.test.d.ts.map +1 -0
- package/dist/dry-run.test.js +21 -0
- package/dist/dry-run.test.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1342 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +303 -0
- package/dist/index.test.js.map +1 -0
- package/dist/output.d.ts +9 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +75 -0
- package/dist/output.js.map +1 -0
- package/dist/permissions.d.ts +32 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +101 -0
- package/dist/permissions.js.map +1 -0
- package/dist/permissions.test.d.ts +2 -0
- package/dist/permissions.test.d.ts.map +1 -0
- package/dist/permissions.test.js +17 -0
- package/dist/permissions.test.js.map +1 -0
- package/dist/register-admin.d.ts +3 -0
- package/dist/register-admin.d.ts.map +1 -0
- package/dist/register-admin.js +100 -0
- package/dist/register-admin.js.map +1 -0
- package/dist/register-batch.d.ts +3 -0
- package/dist/register-batch.d.ts.map +1 -0
- package/dist/register-batch.js +85 -0
- package/dist/register-batch.js.map +1 -0
- package/dist/register-extensions.d.ts +9 -0
- package/dist/register-extensions.d.ts.map +1 -0
- package/dist/register-extensions.js +550 -0
- package/dist/register-extensions.js.map +1 -0
- package/dist/register-ops.d.ts +4 -0
- package/dist/register-ops.d.ts.map +1 -0
- package/dist/register-ops.js +152 -0
- package/dist/register-ops.js.map +1 -0
- package/dist/register-shared.d.ts +3 -0
- package/dist/register-shared.d.ts.map +1 -0
- package/dist/register-shared.js +145 -0
- package/dist/register-shared.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { buildPermissionMatrix, canPerformAction, } from "@geoly-ai/social-hub-authz";
|
|
2
|
+
/** Representative write/high-risk commands mapped to authz resources. */
|
|
3
|
+
export const CLI_PERMISSION_GATES = [
|
|
4
|
+
{ command: "accounts list", resource: "socialAccount", action: "list" },
|
|
5
|
+
{ command: "accounts get", resource: "socialAccount", action: "read" },
|
|
6
|
+
{ command: "accounts create", resource: "socialAccount", action: "create" },
|
|
7
|
+
{ command: "accounts update", resource: "socialAccount", action: "update" },
|
|
8
|
+
{ command: "accounts delete", resource: "socialAccount", action: "delete" },
|
|
9
|
+
{
|
|
10
|
+
command: "accounts brand-bindings list",
|
|
11
|
+
resource: "socialAccount",
|
|
12
|
+
action: "read",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
command: "accounts brand-bindings add",
|
|
16
|
+
resource: "socialAccount",
|
|
17
|
+
action: "update",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
command: "accounts brand-bindings remove",
|
|
21
|
+
resource: "socialAccount",
|
|
22
|
+
action: "update",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
command: "accounts status-snapshots list",
|
|
26
|
+
resource: "socialAccount",
|
|
27
|
+
action: "read",
|
|
28
|
+
},
|
|
29
|
+
{ command: "reddit list", resource: "postSnapshot", action: "list" },
|
|
30
|
+
{ command: "reddit create-snapshot", resource: "postSnapshot", action: "create" },
|
|
31
|
+
{ command: "reddit update", resource: "postSnapshot", action: "update" },
|
|
32
|
+
{ command: "reddit delete", resource: "postSnapshot", action: "delete" },
|
|
33
|
+
{ command: "reddit stats", resource: "postSnapshotStats", action: "read" },
|
|
34
|
+
{
|
|
35
|
+
command: "reddit refresh-status",
|
|
36
|
+
resource: "postSnapshotStats",
|
|
37
|
+
action: "read",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
command: "reddit refresh-all",
|
|
41
|
+
resource: "postSnapshotRefresh",
|
|
42
|
+
action: "create",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
command: "reddit refresh",
|
|
46
|
+
resource: "postSnapshotRefresh",
|
|
47
|
+
action: "create",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
command: "reddit refresh-progress",
|
|
51
|
+
resource: "postSnapshotStats",
|
|
52
|
+
action: "read",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
command: "reddit import-feishu",
|
|
56
|
+
resource: "postSnapshotImport",
|
|
57
|
+
action: "create",
|
|
58
|
+
},
|
|
59
|
+
{ command: "events append", resource: "task", action: "create" },
|
|
60
|
+
{ command: "jobs create", resource: "task", action: "create" },
|
|
61
|
+
{ command: "api-keys list", resource: "apiKey", action: "list" },
|
|
62
|
+
{ command: "api-keys create", resource: "apiKey", action: "create" },
|
|
63
|
+
{ command: "permissions", resource: "apiKey", action: "list" },
|
|
64
|
+
{ command: "permissions-update", resource: "systemMember", action: "update", note: "admin only" },
|
|
65
|
+
];
|
|
66
|
+
export function roleAllows(role, resource, action) {
|
|
67
|
+
return canPerformAction({ role, resource, action });
|
|
68
|
+
}
|
|
69
|
+
export function formatPermissionDenied(input) {
|
|
70
|
+
const lines = [
|
|
71
|
+
`Permission denied for \`${input.command}\`.`,
|
|
72
|
+
`Current role \`${input.role}\` cannot perform ${input.resource}:${input.action}.`,
|
|
73
|
+
"Fix: use an API Key with a higher role (manager/supervisor/admin), or ask a team admin to create one.",
|
|
74
|
+
"Run `social-hub auth explain` to see allowed commands for your role.",
|
|
75
|
+
];
|
|
76
|
+
return lines.join("\n");
|
|
77
|
+
}
|
|
78
|
+
export function explainCliPermissions(role) {
|
|
79
|
+
const matrix = buildPermissionMatrix();
|
|
80
|
+
const allowedCommands = [];
|
|
81
|
+
const deniedCommands = [];
|
|
82
|
+
for (const gate of CLI_PERMISSION_GATES) {
|
|
83
|
+
if (roleAllows(role, gate.resource, gate.action)) {
|
|
84
|
+
allowedCommands.push(gate.command);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
deniedCommands.push(gate.command);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { role, matrix, allowedCommands, deniedCommands };
|
|
91
|
+
}
|
|
92
|
+
export function assertCliPermission(input) {
|
|
93
|
+
if (roleAllows(input.role, input.resource, input.action))
|
|
94
|
+
return;
|
|
95
|
+
console.error(formatPermissionDenied(input));
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
export function findGateForCommand(commandPath) {
|
|
99
|
+
return CLI_PERMISSION_GATES.find((g) => g.command === commandPath);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.test.d.ts","sourceRoot":"","sources":["../src/permissions.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { explainCliPermissions, roleAllows } from "./permissions.js";
|
|
3
|
+
describe("permissions", () => {
|
|
4
|
+
it("client can list accounts but not delete", () => {
|
|
5
|
+
expect(roleAllows("client", "socialAccount", "list")).toBe(true);
|
|
6
|
+
expect(roleAllows("client", "socialAccount", "delete")).toBe(false);
|
|
7
|
+
});
|
|
8
|
+
it("manager can refresh reddit snapshots", () => {
|
|
9
|
+
expect(roleAllows("manager", "postSnapshotRefresh", "create")).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
it("explain lists allowed and denied commands", () => {
|
|
12
|
+
const explained = explainCliPermissions("client");
|
|
13
|
+
expect(explained.allowedCommands).toContain("accounts list");
|
|
14
|
+
expect(explained.deniedCommands).toContain("accounts delete");
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=permissions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.test.js","sourceRoot":"","sources":["../src/permissions.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAErE,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,SAAS,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC7D,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-admin.d.ts","sourceRoot":"","sources":["../src/register-admin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuH5D"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { requireClient, resolveTeamId } from "./client.js";
|
|
2
|
+
import { assertApplyOrDryRun } from "./dry-run.js";
|
|
3
|
+
import { printResult, withCliErrorBoundary } from "./output.js";
|
|
4
|
+
export function registerAdminCommands(program) {
|
|
5
|
+
const settings = program.command("settings").description("系统设置(admin)");
|
|
6
|
+
settings
|
|
7
|
+
.command("list")
|
|
8
|
+
.action(async () => {
|
|
9
|
+
await withCliErrorBoundary(async () => {
|
|
10
|
+
printResult(await requireClient().listSettings());
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
settings
|
|
14
|
+
.command("get")
|
|
15
|
+
.argument("<key>", "Setting key")
|
|
16
|
+
.action(async (key) => {
|
|
17
|
+
await withCliErrorBoundary(async () => {
|
|
18
|
+
printResult(await requireClient().getSetting(key));
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
settings
|
|
22
|
+
.command("set")
|
|
23
|
+
.argument("<key>", "Setting key")
|
|
24
|
+
.requiredOption("--value <value>", "Value")
|
|
25
|
+
.option("--dry-run", "预览", false)
|
|
26
|
+
.option("--apply", "执行写入", false)
|
|
27
|
+
.action(async (key, opts) => {
|
|
28
|
+
await withCliErrorBoundary(async () => {
|
|
29
|
+
if (!assertApplyOrDryRun(opts, {
|
|
30
|
+
command: "settings set",
|
|
31
|
+
danger: "admin",
|
|
32
|
+
summary: { key, value: opts.value },
|
|
33
|
+
})) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
printResult(await requireClient().upsertSetting(key, { value: opts.value }));
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
const invites = program.command("invites").description("团队邀请");
|
|
40
|
+
invites
|
|
41
|
+
.command("list")
|
|
42
|
+
.requiredOption("-t, --team <teamId>", "Team UUID")
|
|
43
|
+
.action(async (opts) => {
|
|
44
|
+
await withCliErrorBoundary(async () => {
|
|
45
|
+
printResult(await requireClient().listTeamInvites(resolveTeamId(opts.team)));
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
invites
|
|
49
|
+
.command("create")
|
|
50
|
+
.requiredOption("-t, --team <teamId>", "Team UUID")
|
|
51
|
+
.requiredOption("--email <email>", "邮箱")
|
|
52
|
+
.requiredOption("--role <role>", "角色")
|
|
53
|
+
.option("--dry-run", "预览", false)
|
|
54
|
+
.option("--apply", "执行写入", false)
|
|
55
|
+
.action(async (opts) => {
|
|
56
|
+
await withCliErrorBoundary(async () => {
|
|
57
|
+
const teamId = resolveTeamId(opts.team);
|
|
58
|
+
if (!assertApplyOrDryRun(opts, {
|
|
59
|
+
command: "invites create",
|
|
60
|
+
danger: "write",
|
|
61
|
+
summary: { teamId, email: opts.email, role: opts.role },
|
|
62
|
+
})) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
printResult(await requireClient().createTeamInvite(teamId, {
|
|
66
|
+
email: opts.email,
|
|
67
|
+
role: opts.role,
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
invites
|
|
72
|
+
.command("revoke")
|
|
73
|
+
.requiredOption("-t, --team <teamId>", "Team UUID")
|
|
74
|
+
.requiredOption("--id <inviteId>", "邀请 ID")
|
|
75
|
+
.option("--dry-run", "预览", false)
|
|
76
|
+
.option("--apply", "执行写入", false)
|
|
77
|
+
.action(async (opts) => {
|
|
78
|
+
await withCliErrorBoundary(async () => {
|
|
79
|
+
const teamId = resolveTeamId(opts.team);
|
|
80
|
+
if (!assertApplyOrDryRun(opts, {
|
|
81
|
+
command: "invites revoke",
|
|
82
|
+
danger: "delete",
|
|
83
|
+
summary: { teamId, inviteId: opts.id },
|
|
84
|
+
})) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
printResult(await requireClient().revokeTeamInvite(teamId, opts.id));
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
const members = program.command("members").description("成员管理");
|
|
91
|
+
members
|
|
92
|
+
.command("list")
|
|
93
|
+
.option("-t, --team <teamId>", "Team UUID(可选,默认 system)")
|
|
94
|
+
.action(async (opts) => {
|
|
95
|
+
await withCliErrorBoundary(async () => {
|
|
96
|
+
printResult(await requireClient().listSystemMembers());
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=register-admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-admin.js","sourceRoot":"","sources":["../src/register-admin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-batch.d.ts","sourceRoot":"","sources":["../src/register-batch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwF7D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { requireClient, resolveTeamId } from "./client.js";
|
|
3
|
+
import { printResult, withCliErrorBoundary } from "./output.js";
|
|
4
|
+
export function registerBatchAndExport(program) {
|
|
5
|
+
const runbook = program.command("runbook").description("可回放脚本");
|
|
6
|
+
runbook
|
|
7
|
+
.command("replay")
|
|
8
|
+
.description("按 JSONL 顺序重放 CLI 等价的 API 调用(events append)")
|
|
9
|
+
.requiredOption("-t, --team <teamId>", "Team UUID")
|
|
10
|
+
.requiredOption("-f, --file <path>", "JSONL 文件,每行 { \"type\", \"payload\" }")
|
|
11
|
+
.option("--dry-run", "只打印将执行的操作", false)
|
|
12
|
+
.action(async (opts) => {
|
|
13
|
+
await withCliErrorBoundary(async () => {
|
|
14
|
+
const teamId = resolveTeamId(opts.team);
|
|
15
|
+
const lines = readFileSync(opts.file, "utf8")
|
|
16
|
+
.split("\n")
|
|
17
|
+
.map((l) => l.trim())
|
|
18
|
+
.filter(Boolean);
|
|
19
|
+
const results = [];
|
|
20
|
+
for (const line of lines) {
|
|
21
|
+
const row = JSON.parse(line);
|
|
22
|
+
if (opts.dryRun) {
|
|
23
|
+
results.push({ dryRun: true, ...row });
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const res = await requireClient().appendEvent(teamId, {
|
|
27
|
+
type: row.type,
|
|
28
|
+
payload: row.payload ?? {},
|
|
29
|
+
});
|
|
30
|
+
results.push(res);
|
|
31
|
+
}
|
|
32
|
+
printResult({ replayed: results.length, results });
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
const exportCmd = program.command("export").description("导出");
|
|
36
|
+
exportCmd
|
|
37
|
+
.command("agent-context")
|
|
38
|
+
.requiredOption("-t, --team <teamId>", "Team UUID")
|
|
39
|
+
.requiredOption("--account <ref>", "账号 ref")
|
|
40
|
+
.option("--format <fmt>", "json|md", "json")
|
|
41
|
+
.option("-o, --output <path>", "输出文件")
|
|
42
|
+
.action(async (opts) => {
|
|
43
|
+
await withCliErrorBoundary(async () => {
|
|
44
|
+
const teamId = resolveTeamId(opts.team);
|
|
45
|
+
const data = await requireClient().getAccountAgentContext(teamId, opts.account, { expand: "pools,jobs,persona,risk,env,guardrails" });
|
|
46
|
+
let text;
|
|
47
|
+
if (opts.format === "md") {
|
|
48
|
+
text = `# Agent context: ${opts.account}\n\n\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\`\n`;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
text = `${JSON.stringify(data, null, 2)}\n`;
|
|
52
|
+
}
|
|
53
|
+
if (opts.output) {
|
|
54
|
+
writeFileSync(opts.output, text);
|
|
55
|
+
printResult({ ok: true, path: opts.output });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log(text);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
exportCmd
|
|
63
|
+
.command("events-jsonl")
|
|
64
|
+
.requiredOption("-t, --team <teamId>", "Team UUID")
|
|
65
|
+
.option("-n, --limit <n>", "条数", "100")
|
|
66
|
+
.option("-o, --output <path>", "输出文件(默认 stdout)")
|
|
67
|
+
.action(async (opts) => {
|
|
68
|
+
await withCliErrorBoundary(async () => {
|
|
69
|
+
const teamId = resolveTeamId(opts.team);
|
|
70
|
+
const res = await requireClient().listEventsFiltered(teamId, {
|
|
71
|
+
limit: Number(opts.limit),
|
|
72
|
+
});
|
|
73
|
+
const items = res.items ?? [];
|
|
74
|
+
const lines = items.map((row) => JSON.stringify(row)).join("\n");
|
|
75
|
+
if (opts.output) {
|
|
76
|
+
writeFileSync(opts.output, `${lines}\n`);
|
|
77
|
+
printResult({ ok: true, count: items.length, path: opts.output });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.log(lines);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=register-batch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-batch.js","sourceRoot":"","sources":["../src/register-batch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { Role } from "@geoly-ai/social-hub-authz";
|
|
3
|
+
export declare function registerAuthAndConfig(program: Command): void;
|
|
4
|
+
export declare function registerPermissionsExplain(permissionsCmd: Command): void;
|
|
5
|
+
export declare function registerRedditExtensions(reddit: Command): void;
|
|
6
|
+
export declare function registerAccountsExtensions(accounts: Command): void;
|
|
7
|
+
/** Optional helper for existing commands — gate by command path if registered. */
|
|
8
|
+
export declare function maybeAssertCliPermission(commandPath: string, role: Role): void;
|
|
9
|
+
//# sourceMappingURL=register-extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-extensions.d.ts","sourceRoot":"","sources":["../src/register-extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAoB,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAoDzE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyT5D;AAED,wBAAgB,0BAA0B,CAAC,cAAc,EAAE,OAAO,GAAG,IAAI,CAiBxE;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAuQ9D;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAkJlE;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,IAAI,GACT,IAAI,CASN"}
|