@opvs-ai/cli 0.1.0

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 (43) hide show
  1. package/dist/commands/auth.d.ts +5 -0
  2. package/dist/commands/auth.js +149 -0
  3. package/dist/commands/auth.js.map +1 -0
  4. package/dist/commands/boards.d.ts +5 -0
  5. package/dist/commands/boards.js +69 -0
  6. package/dist/commands/boards.js.map +1 -0
  7. package/dist/commands/comments.d.ts +5 -0
  8. package/dist/commands/comments.js +62 -0
  9. package/dist/commands/comments.js.map +1 -0
  10. package/dist/commands/config.d.ts +5 -0
  11. package/dist/commands/config.js +84 -0
  12. package/dist/commands/config.js.map +1 -0
  13. package/dist/commands/docs.d.ts +5 -0
  14. package/dist/commands/docs.js +145 -0
  15. package/dist/commands/docs.js.map +1 -0
  16. package/dist/commands/session.d.ts +5 -0
  17. package/dist/commands/session.js +43 -0
  18. package/dist/commands/session.js.map +1 -0
  19. package/dist/commands/tasks.d.ts +5 -0
  20. package/dist/commands/tasks.js +139 -0
  21. package/dist/commands/tasks.js.map +1 -0
  22. package/dist/index.d.ts +13 -0
  23. package/dist/index.js +35 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/lib/api.d.ts +27 -0
  26. package/dist/lib/api.js +128 -0
  27. package/dist/lib/api.js.map +1 -0
  28. package/dist/lib/auth-poll.d.ts +15 -0
  29. package/dist/lib/auth-poll.js +46 -0
  30. package/dist/lib/auth-poll.js.map +1 -0
  31. package/dist/lib/config.d.ts +8 -0
  32. package/dist/lib/config.js +39 -0
  33. package/dist/lib/config.js.map +1 -0
  34. package/dist/lib/fingerprint.d.ts +8 -0
  35. package/dist/lib/fingerprint.js +32 -0
  36. package/dist/lib/fingerprint.js.map +1 -0
  37. package/dist/lib/format.d.ts +19 -0
  38. package/dist/lib/format.js +55 -0
  39. package/dist/lib/format.js.map +1 -0
  40. package/dist/types.d.ts +35 -0
  41. package/dist/types.js +9 -0
  42. package/dist/types.js.map +1 -0
  43. package/package.json +36 -0
@@ -0,0 +1,5 @@
1
+ /**
2
+ * opvs auth — AI-native token provisioning + management
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerAuthCommands(program: Command): void;
@@ -0,0 +1,149 @@
1
+ /**
2
+ * opvs auth — AI-native token provisioning + management
3
+ */
4
+ import { loadConfig, saveConfig } from "../lib/config.js";
5
+ import { apiUnauthPost, createClient } from "../lib/api.js";
6
+ import { buildFingerprint } from "../lib/fingerprint.js";
7
+ import { pollForApproval } from "../lib/auth-poll.js";
8
+ import { printJson } from "../lib/format.js";
9
+ export function registerAuthCommands(program) {
10
+ const auth = program.command("auth").description("Token authentication");
11
+ auth
12
+ .command("request")
13
+ .description("Request a PAT token (sends approval email to workspace owner)")
14
+ .requiredOption("-w, --workspace <slug>", "Workspace slug")
15
+ .requiredOption("-e, --email <email>", "Owner email (admin who approves)")
16
+ .option("-p, --project <name>", "Project name (shown in approval email)")
17
+ .option("-s, --scopes <scopes>", "Comma-separated scopes", "board:read,board:write")
18
+ .option("-t, --ttl <hours>", "Token TTL in hours", "72")
19
+ .option("--api-url <url>", "API base URL (overrides config)")
20
+ .action(async (opts) => {
21
+ const cfg = loadConfig();
22
+ const baseUrl = opts.apiUrl || cfg.api_url;
23
+ const fingerprint = buildFingerprint();
24
+ const scopes = opts.scopes.split(",").map((s) => s.trim());
25
+ console.log(`Requesting access to workspace "${opts.workspace}"...`);
26
+ console.log(`Approval email will be sent to ${opts.email}`);
27
+ try {
28
+ const res = await apiUnauthPost(baseUrl, "/api/v1/auth/pat/request", {
29
+ workspace_slug: opts.workspace,
30
+ owner_email: opts.email,
31
+ project_name: opts.project || null,
32
+ requested_scopes: scopes,
33
+ ttl_hours: parseInt(opts.ttl, 10),
34
+ fingerprint,
35
+ });
36
+ const data = await res.json();
37
+ const { request_id, poll_token, expires_at } = data;
38
+ console.log(`Request ID: ${request_id}`);
39
+ console.log(`Expires: ${expires_at}`);
40
+ // Start polling
41
+ const result = await pollForApproval(baseUrl, request_id, poll_token);
42
+ if (result.status === "active" && result.token) {
43
+ // Save token + brand info to config
44
+ saveConfig({
45
+ api_url: baseUrl,
46
+ token: result.token,
47
+ brand_id: result.brand_id ?? null,
48
+ brand_name: result.brand_name ?? "",
49
+ });
50
+ console.log(`\nAuthenticated! Token saved to config.`);
51
+ console.log(`Brand: ${result.brand_name} (ID: ${result.brand_id})`);
52
+ console.log(`Scopes: ${result.scopes?.join(", ")}`);
53
+ }
54
+ else if (result.status === "denied") {
55
+ console.error("\nAccess denied by workspace owner.");
56
+ process.exit(1);
57
+ }
58
+ else if (result.status === "expired") {
59
+ console.error("\nRequest expired. Try again.");
60
+ process.exit(1);
61
+ }
62
+ else {
63
+ console.error("\nRequest timed out. The owner may not have seen the email.");
64
+ process.exit(1);
65
+ }
66
+ }
67
+ catch (err) {
68
+ const e = err;
69
+ console.error(`Error: ${e.detail || "Request failed"}`);
70
+ process.exit(1);
71
+ }
72
+ });
73
+ auth
74
+ .command("status")
75
+ .description("Show current authentication status")
76
+ .action(async () => {
77
+ const cfg = loadConfig();
78
+ if (!cfg.token) {
79
+ console.log("Not authenticated. Run `opvs auth request` to get a token.");
80
+ return;
81
+ }
82
+ try {
83
+ const client = createClient();
84
+ const res = await client.get("/api/v1/auth/me");
85
+ const data = await res.json();
86
+ printJson(data);
87
+ }
88
+ catch (err) {
89
+ const e = err;
90
+ if (e.status === 401) {
91
+ console.error("Token is invalid or expired. Run `opvs auth request` to re-authenticate.");
92
+ }
93
+ else {
94
+ console.error(`Error: ${e.detail || "Failed to check status"}`);
95
+ }
96
+ process.exit(1);
97
+ }
98
+ });
99
+ auth
100
+ .command("revoke")
101
+ .description("Revoke the current token")
102
+ .action(async () => {
103
+ const cfg = loadConfig();
104
+ if (!cfg.token) {
105
+ console.log("Not authenticated — nothing to revoke.");
106
+ return;
107
+ }
108
+ try {
109
+ const client = createClient();
110
+ // Find the token ID by matching prefix from the tokens list
111
+ const prefix = cfg.token.slice(0, 16);
112
+ const listRes = await client.get("/api/v1/tokens");
113
+ const listData = await listRes.json();
114
+ const match = listData.tokens?.find((t) => t.token_prefix === prefix && t.is_active);
115
+ if (match) {
116
+ await client.delete(`/api/v1/tokens/${match.id}`);
117
+ console.log("Token revoked on server.");
118
+ }
119
+ else {
120
+ console.log("Token not found on server (may already be revoked).");
121
+ }
122
+ saveConfig({ token: "", brand_id: null, brand_name: "" });
123
+ console.log("Local config cleared.");
124
+ }
125
+ catch (err) {
126
+ const e = err;
127
+ // Clear local config even if server revoke fails
128
+ saveConfig({ token: "", brand_id: null, brand_name: "" });
129
+ console.error(`Server revoke failed (${e.detail}), but local config cleared.`);
130
+ }
131
+ });
132
+ auth
133
+ .command("list")
134
+ .description("List all agent tokens for the workspace (admin)")
135
+ .action(async () => {
136
+ try {
137
+ const client = createClient();
138
+ const res = await client.get("/api/v1/auth/pat/agents");
139
+ const data = await res.json();
140
+ printJson(data);
141
+ }
142
+ catch (err) {
143
+ const e = err;
144
+ console.error(`Error: ${e.detail || "Failed to list agents"}`);
145
+ process.exit(1);
146
+ }
147
+ });
148
+ }
149
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * opvs boards — board CRUD
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerBoardCommands(program: Command): void;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * opvs boards — board CRUD
3
+ */
4
+ import { loadConfig } from "../lib/config.js";
5
+ import { createClient } from "../lib/api.js";
6
+ import { buildUrl, printResponse, printJson } from "../lib/format.js";
7
+ export function registerBoardCommands(program) {
8
+ const boards = program.command("boards").description("AgentBoard management");
9
+ boards
10
+ .command("list")
11
+ .description("List boards")
12
+ .option("--status <status>", "Filter by status")
13
+ .action(async (opts) => {
14
+ const cfg = loadConfig();
15
+ try {
16
+ const client = createClient();
17
+ const params = {};
18
+ if (opts.status)
19
+ params.status = opts.status;
20
+ const url = buildUrl("/api/v1/board/boards", params, cfg.format);
21
+ const res = await client.get(url);
22
+ await printResponse(res);
23
+ }
24
+ catch (err) {
25
+ const e = err;
26
+ console.error(`Error: ${e.detail || "Failed to list boards"}`);
27
+ process.exit(1);
28
+ }
29
+ });
30
+ boards
31
+ .command("get <id>")
32
+ .description("Get board details")
33
+ .action(async (id) => {
34
+ const cfg = loadConfig();
35
+ try {
36
+ const client = createClient();
37
+ const url = buildUrl(`/api/v1/board/boards/${id}`, undefined, cfg.format);
38
+ const res = await client.get(url);
39
+ await printResponse(res);
40
+ }
41
+ catch (err) {
42
+ const e = err;
43
+ console.error(`Error: ${e.detail || "Failed to get board"}`);
44
+ process.exit(1);
45
+ }
46
+ });
47
+ boards
48
+ .command("create")
49
+ .description("Create a new board")
50
+ .requiredOption("-n, --name <name>", "Board name")
51
+ .option("-d, --description <desc>", "Board description")
52
+ .action(async (opts) => {
53
+ try {
54
+ const client = createClient();
55
+ const body = { name: opts.name };
56
+ if (opts.description)
57
+ body.description = opts.description;
58
+ const res = await client.post("/api/v1/board/boards", body);
59
+ const data = await res.json();
60
+ printJson(data);
61
+ }
62
+ catch (err) {
63
+ const e = err;
64
+ console.error(`Error: ${e.detail || "Failed to create board"}`);
65
+ process.exit(1);
66
+ }
67
+ });
68
+ }
69
+ //# sourceMappingURL=boards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boards.js","sourceRoot":"","sources":["../../src/commands/boards.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * opvs comments — task comments (activity feed)
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerCommentCommands(program: Command): void;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * opvs comments — task comments (activity feed)
3
+ */
4
+ import { readFileSync } from "node:fs";
5
+ import { loadConfig } from "../lib/config.js";
6
+ import { createClient } from "../lib/api.js";
7
+ import { buildUrl, printResponse, printJson } from "../lib/format.js";
8
+ export function registerCommentCommands(program) {
9
+ const comments = program.command("comments").description("Task comments");
10
+ comments
11
+ .command("list <taskId>")
12
+ .description("List comments on a task")
13
+ .option("--limit <n>", "Max results", "25")
14
+ .action(async (taskId, opts) => {
15
+ const cfg = loadConfig();
16
+ try {
17
+ const client = createClient();
18
+ const params = {};
19
+ if (opts.limit)
20
+ params.limit = opts.limit;
21
+ const url = buildUrl(`/api/v1/board/tasks/${taskId}/comments`, params, cfg.format);
22
+ const res = await client.get(url);
23
+ await printResponse(res);
24
+ }
25
+ catch (err) {
26
+ const e = err;
27
+ console.error(`Error: ${e.detail || "Failed to list comments"}`);
28
+ process.exit(1);
29
+ }
30
+ });
31
+ comments
32
+ .command("add <taskId> [message]")
33
+ .description("Add a comment to a task")
34
+ .option("-f, --file <path>", "Read comment body from file")
35
+ .action(async (taskId, message, opts) => {
36
+ try {
37
+ const client = createClient();
38
+ let body;
39
+ if (opts.file) {
40
+ body = readFileSync(opts.file, "utf-8");
41
+ }
42
+ else if (message) {
43
+ body = message;
44
+ }
45
+ else {
46
+ console.error("Provide a message or --file <path>");
47
+ process.exit(1);
48
+ }
49
+ const res = await client.post(`/api/v1/board/tasks/${taskId}/comments`, {
50
+ content: body,
51
+ });
52
+ const data = await res.json();
53
+ printJson(data);
54
+ }
55
+ catch (err) {
56
+ const e = err;
57
+ console.error(`Error: ${e.detail || "Failed to add comment"}`);
58
+ process.exit(1);
59
+ }
60
+ });
61
+ }
62
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/commands/comments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEtE,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IAE1E,QAAQ;SACL,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,IAAI,CAAC;SAC1C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;YAC9B,MAAM,MAAM,GAA2B,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,KAAK;gBAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,uBAAuB,MAAM,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACnF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,GAA0B,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,IAAI,yBAAyB,EAAE,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,wBAAwB,CAAC;SACjC,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,mBAAmB,EAAE,6BAA6B,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,OAA2B,EAAE,IAAI,EAAE,EAAE;QAClE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;YAC9B,IAAI,IAAY,CAAC;YACjB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC1C,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,IAAI,GAAG,OAAO,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,uBAAuB,MAAM,WAAW,EAAE;gBACtE,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,SAAS,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,GAA0B,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,IAAI,uBAAuB,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * opvs config — manage CLI configuration + opvs init
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerConfigCommands(program: Command): void;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * opvs config — manage CLI configuration + opvs init
3
+ */
4
+ import { loadConfig, saveConfig, resetConfig, getConfigPath } from "../lib/config.js";
5
+ export function registerConfigCommands(program) {
6
+ const config = program.command("config").description("Manage CLI configuration");
7
+ config
8
+ .command("set <key> <value>")
9
+ .description("Set a config value (api_url, token, brand_id, brand_name, format)")
10
+ .action((key, value) => {
11
+ const valid = ["api_url", "token", "brand_id", "brand_name", "format"];
12
+ if (!valid.includes(key)) {
13
+ console.error(`Unknown config key: ${key}`);
14
+ console.error(`Valid keys: ${valid.join(", ")}`);
15
+ process.exit(1);
16
+ }
17
+ const parsed = key === "brand_id" ? Number(value) : value;
18
+ saveConfig({ [key]: parsed });
19
+ console.log(`${key} = ${value}`);
20
+ });
21
+ config
22
+ .command("get [key]")
23
+ .description("Show current config (or a specific key)")
24
+ .action((key) => {
25
+ const cfg = loadConfig();
26
+ if (key) {
27
+ const val = cfg[key];
28
+ if (val === undefined) {
29
+ console.error(`Unknown config key: ${key}`);
30
+ process.exit(1);
31
+ }
32
+ console.log(val);
33
+ }
34
+ else {
35
+ // Mask token for display
36
+ const display = { ...cfg, token: cfg.token ? `${cfg.token.slice(0, 12)}...` : "(not set)" };
37
+ console.log(JSON.stringify(display, null, 2));
38
+ }
39
+ });
40
+ config
41
+ .command("reset")
42
+ .description("Reset config to defaults")
43
+ .action(() => {
44
+ resetConfig();
45
+ console.log("Config reset to defaults.");
46
+ });
47
+ config
48
+ .command("path")
49
+ .description("Show config file path")
50
+ .action(() => {
51
+ console.log(getConfigPath());
52
+ });
53
+ // opvs init — generate a CLAUDE.md snippet
54
+ program
55
+ .command("init")
56
+ .description("Print a CLAUDE.md snippet for AI agent integration")
57
+ .action(() => {
58
+ const cfg = loadConfig();
59
+ const snippet = `# OPVS AgentBoard + Docs
60
+
61
+ ## Setup
62
+ Run \`opvs auth request --workspace <slug> --email <your-email>\` if not authenticated.
63
+
64
+ ## Board Commands
65
+ - \`opvs session get --self\` — Board context + assigned tasks
66
+ - \`opvs tasks list --self --status pending\` — Pending tasks
67
+ - \`opvs task update <id> --status review --result-file ./output.md\` — Complete a task
68
+ - \`opvs comment add <id> "message"\` — Add a comment
69
+
70
+ ## Docs Commands
71
+ - \`opvs docs list\` — List doc projects
72
+ - \`opvs docs get <project> <slug>\` — Read a page
73
+ - \`opvs docs update <project> <slug> --file ./output.md\` — Update a page
74
+ - \`opvs docs search "query"\` — Search docs
75
+
76
+ ## Config
77
+ - API: ${cfg.api_url}
78
+ - Brand: ${cfg.brand_name || "(not set)"}
79
+ - Format: ${cfg.format}
80
+ `;
81
+ console.log(snippet);
82
+ });
83
+ }
84
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * opvs docs — AgentDocs versioned documentation
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerDocsCommands(program: Command): void;
@@ -0,0 +1,145 @@
1
+ /**
2
+ * opvs docs — AgentDocs versioned documentation
3
+ */
4
+ import { readFileSync } from "node:fs";
5
+ import { loadConfig } from "../lib/config.js";
6
+ import { createClient } from "../lib/api.js";
7
+ import { buildUrl, printResponse, printJson } from "../lib/format.js";
8
+ export function registerDocsCommands(program) {
9
+ const docs = program.command("docs").description("AgentDocs documentation");
10
+ docs
11
+ .command("list")
12
+ .description("List documentation projects")
13
+ .action(async () => {
14
+ const cfg = loadConfig();
15
+ try {
16
+ const client = createClient();
17
+ const url = buildUrl("/api/v1/docs/projects", undefined, cfg.format);
18
+ const res = await client.get(url);
19
+ await printResponse(res);
20
+ }
21
+ catch (err) {
22
+ const e = err;
23
+ console.error(`Error: ${e.detail || "Failed to list projects"}`);
24
+ process.exit(1);
25
+ }
26
+ });
27
+ docs
28
+ .command("get <project> <slug>")
29
+ .description("Get a documentation page by project and slug")
30
+ .option("--version <version>", "Specific version")
31
+ .action(async (project, slug, opts) => {
32
+ const cfg = loadConfig();
33
+ try {
34
+ const client = createClient();
35
+ const params = {};
36
+ if (opts.version)
37
+ params.version = opts.version;
38
+ const url = buildUrl(`/api/v1/docs/projects/${project}/pages/${slug}`, params, cfg.format);
39
+ const res = await client.get(url);
40
+ await printResponse(res);
41
+ }
42
+ catch (err) {
43
+ const e = err;
44
+ console.error(`Error: ${e.detail || "Failed to get page"}`);
45
+ process.exit(1);
46
+ }
47
+ });
48
+ docs
49
+ .command("create <project>")
50
+ .description("Create a documentation page")
51
+ .requiredOption("-t, --title <title>", "Page title")
52
+ .requiredOption("-s, --slug <slug>", "Page slug")
53
+ .option("-f, --file <path>", "Read content from file")
54
+ .option("-c, --content <text>", "Inline content")
55
+ .option("-m, --message <msg>", "Commit message", "Created via CLI")
56
+ .action(async (project, opts) => {
57
+ try {
58
+ const client = createClient();
59
+ let content = "";
60
+ if (opts.file) {
61
+ content = readFileSync(opts.file, "utf-8");
62
+ }
63
+ else if (opts.content) {
64
+ content = opts.content;
65
+ }
66
+ const body = {
67
+ title: opts.title,
68
+ slug: opts.slug,
69
+ commit_message: opts.message,
70
+ };
71
+ if (content)
72
+ body.content_md = content;
73
+ const res = await client.post(`/api/v1/docs/projects/${project}/pages`, body);
74
+ const data = await res.json();
75
+ printJson(data);
76
+ }
77
+ catch (err) {
78
+ const e = err;
79
+ console.error(`Error: ${e.detail || "Failed to create page"}`);
80
+ process.exit(1);
81
+ }
82
+ });
83
+ docs
84
+ .command("update <project> <slug>")
85
+ .description("Update a documentation page")
86
+ .option("-t, --title <title>", "New title")
87
+ .option("-f, --file <path>", "Read content from file")
88
+ .option("-c, --content <text>", "Inline content")
89
+ .option("-m, --message <msg>", "Commit message", "Updated via CLI")
90
+ .action(async (project, slug, opts) => {
91
+ try {
92
+ const client = createClient();
93
+ let content_md = "";
94
+ if (opts.file) {
95
+ content_md = readFileSync(opts.file, "utf-8");
96
+ }
97
+ else if (opts.content) {
98
+ content_md = opts.content;
99
+ }
100
+ if (!content_md) {
101
+ console.error("Content required. Provide --content or --file");
102
+ process.exit(1);
103
+ }
104
+ const body = {
105
+ content_md,
106
+ commit_message: opts.message,
107
+ };
108
+ if (opts.title)
109
+ body.title = opts.title;
110
+ const res = await client.put(`/api/v1/docs/projects/${project}/pages/${slug}`, body);
111
+ const data = await res.json();
112
+ printJson(data);
113
+ }
114
+ catch (err) {
115
+ const e = err;
116
+ console.error(`Error: ${e.detail || "Failed to update page"}`);
117
+ process.exit(1);
118
+ }
119
+ });
120
+ docs
121
+ .command("search <query>")
122
+ .description("Search documentation")
123
+ .option("--project <project>", "Filter by project")
124
+ .option("--limit <n>", "Max results", "10")
125
+ .action(async (query, opts) => {
126
+ const cfg = loadConfig();
127
+ try {
128
+ const client = createClient();
129
+ const params = { q: query };
130
+ if (opts.project)
131
+ params.project = opts.project;
132
+ if (opts.limit)
133
+ params.limit = opts.limit;
134
+ const url = buildUrl("/api/v1/docs/search", params, cfg.format);
135
+ const res = await client.get(url);
136
+ await printResponse(res);
137
+ }
138
+ catch (err) {
139
+ const e = err;
140
+ console.error(`Error: ${e.detail || "Failed to search docs"}`);
141
+ process.exit(1);
142
+ }
143
+ });
144
+ }
145
+ //# sourceMappingURL=docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * opvs session — board context and agent session info
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerSessionCommands(program: Command): void;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * opvs session — board context and agent session info
3
+ */
4
+ import { loadConfig } from "../lib/config.js";
5
+ import { createClient } from "../lib/api.js";
6
+ import { buildUrl, printResponse } from "../lib/format.js";
7
+ export function registerSessionCommands(program) {
8
+ const session = program.command("session").description("Board session context");
9
+ session
10
+ .command("get")
11
+ .description("Get board context (agent session info + assigned tasks)")
12
+ .option("--self", "Show only your own context")
13
+ .option("--board <id>", "Board ID")
14
+ .action(async (opts) => {
15
+ const cfg = loadConfig();
16
+ try {
17
+ const client = createClient();
18
+ if (opts.self) {
19
+ // Use the agent convenience endpoint
20
+ const url = buildUrl("/api/v1/board/agent-api/my-tasks", undefined, cfg.format);
21
+ const res = await client.get(url);
22
+ await printResponse(res);
23
+ }
24
+ else if (opts.board) {
25
+ const url = buildUrl(`/api/v1/board/boards/${opts.board}`, undefined, cfg.format);
26
+ const res = await client.get(url);
27
+ await printResponse(res);
28
+ }
29
+ else {
30
+ // Default: list boards to show available context
31
+ const url = buildUrl("/api/v1/board/boards", undefined, cfg.format);
32
+ const res = await client.get(url);
33
+ await printResponse(res);
34
+ }
35
+ }
36
+ catch (err) {
37
+ const e = err;
38
+ console.error(`Error: ${e.detail || "Failed to get session"}`);
39
+ process.exit(1);
40
+ }
41
+ });
42
+ }
43
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3D,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAEhF,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,yDAAyD,CAAC;SACtE,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;SAC9C,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC;SAClC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,qCAAqC;gBACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,kCAAkC,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAChF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;iBAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtB,MAAM,GAAG,GAAG,QAAQ,CAAC,wBAAwB,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAClF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,iDAAiD;gBACjD,MAAM,GAAG,GAAG,QAAQ,CAAC,sBAAsB,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBACpE,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAClC,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,GAA0B,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,IAAI,uBAAuB,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AAEP,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * opvs tasks — task CRUD + agent convenience endpoints
3
+ */
4
+ import { Command } from "commander";
5
+ export declare function registerTaskCommands(program: Command): void;