@witchpot/devlog-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.
@@ -0,0 +1,23 @@
1
+ import type { CommandHandler } from "../types.js";
2
+ /**
3
+ * devlog draft list [projectId] - List post drafts
4
+ */
5
+ export declare const draftListCommand: CommandHandler;
6
+ /**
7
+ * devlog draft create [projectId] --platform=<platform> --body=<body>
8
+ * [--hook=<hook>] [--cta=<cta>] [--hashtags=<h1,h2>]
9
+ * [--rationale=<text>] [--post-type=<type>] [--emotional-hook=<type>]
10
+ * [--cta-type=<type>] [--media-style=<style>] [--language=<code>]
11
+ */
12
+ export declare const draftCreateCommand: CommandHandler;
13
+ /**
14
+ * devlog draft update <draftId> --project=<projectId>
15
+ * [--body=<body>] [--hook=<hook>] [--platform=<platform>] [--status=<status>]
16
+ * [--cta=<cta>] [--hashtags=<h1,h2>] [--rationale=<text>] [--post-type=<type>]
17
+ * [--emotional-hook=<type>] [--cta-type=<type>] [--media-style=<style>] [--language=<code>]
18
+ */
19
+ export declare const draftUpdateCommand: CommandHandler;
20
+ /**
21
+ * devlog draft delete <draftId> --project=<projectId>
22
+ */
23
+ export declare const draftDeleteCommand: CommandHandler;
@@ -0,0 +1,136 @@
1
+ import { printJson, printTable } from "../output.js";
2
+ import { getActiveProjectId } from "../config.js";
3
+ import { assertSafeId } from "../errors.js";
4
+ /**
5
+ * devlog draft list [projectId] - List post drafts
6
+ */
7
+ export const draftListCommand = async (client, args, _flags, format) => {
8
+ const projectId = args[0] || getActiveProjectId();
9
+ assertSafeId(projectId, "project ID");
10
+ const res = await client.get(`/projects/${projectId}/drafts`);
11
+ if (format === "table") {
12
+ printTable(res.data.map((d) => ({
13
+ id: d.id.slice(0, 8),
14
+ platform: d.platform,
15
+ status: d.status,
16
+ hook: d.hook ?? "-",
17
+ body: d.body.slice(0, 60),
18
+ created: d.created_at.slice(0, 10),
19
+ })));
20
+ }
21
+ else {
22
+ printJson(res.data);
23
+ }
24
+ };
25
+ /**
26
+ * devlog draft create [projectId] --platform=<platform> --body=<body>
27
+ * [--hook=<hook>] [--cta=<cta>] [--hashtags=<h1,h2>]
28
+ * [--rationale=<text>] [--post-type=<type>] [--emotional-hook=<type>]
29
+ * [--cta-type=<type>] [--media-style=<style>] [--language=<code>]
30
+ */
31
+ export const draftCreateCommand = async (client, args, flags, _format) => {
32
+ const projectId = args[0] || getActiveProjectId();
33
+ const platform = flags["platform"];
34
+ const body = flags["body"];
35
+ if (!platform) {
36
+ console.error("Usage: devlog draft create [projectId] --platform=<x|tiktok|instagram|youtube_shorts> --body=<text>");
37
+ process.exit(1);
38
+ }
39
+ if (!body) {
40
+ console.error("--body is required");
41
+ process.exit(1);
42
+ }
43
+ assertSafeId(projectId, "project ID");
44
+ const reqBody = { platform, body };
45
+ if (flags["hook"])
46
+ reqBody.hook = flags["hook"];
47
+ if (flags["cta"])
48
+ reqBody.cta = flags["cta"];
49
+ if (flags["hashtags"]) {
50
+ reqBody.hashtags = flags["hashtags"]
51
+ .split(",")
52
+ .map((h) => h.trim())
53
+ .filter(Boolean);
54
+ }
55
+ if (flags["rationale"])
56
+ reqBody.rationale = flags["rationale"];
57
+ if (flags["post-type"])
58
+ reqBody.post_type = flags["post-type"];
59
+ if (flags["emotional-hook"])
60
+ reqBody.emotional_hook = flags["emotional-hook"];
61
+ if (flags["cta-type"])
62
+ reqBody.cta_type = flags["cta-type"];
63
+ if (flags["media-style"])
64
+ reqBody.media_style = flags["media-style"];
65
+ if (flags["language"])
66
+ reqBody.language = flags["language"];
67
+ const res = await client.post(`/projects/${projectId}/drafts`, reqBody);
68
+ printJson(res.data);
69
+ };
70
+ /**
71
+ * devlog draft update <draftId> --project=<projectId>
72
+ * [--body=<body>] [--hook=<hook>] [--platform=<platform>] [--status=<status>]
73
+ * [--cta=<cta>] [--hashtags=<h1,h2>] [--rationale=<text>] [--post-type=<type>]
74
+ * [--emotional-hook=<type>] [--cta-type=<type>] [--media-style=<style>] [--language=<code>]
75
+ */
76
+ export const draftUpdateCommand = async (client, args, flags, _format) => {
77
+ const draftId = args[0];
78
+ if (!draftId) {
79
+ console.error("Usage: devlog draft update <draftId> [options]");
80
+ process.exit(1);
81
+ }
82
+ const projectId = flags["project"] || getActiveProjectId();
83
+ assertSafeId(draftId, "draft ID");
84
+ assertSafeId(projectId, "project ID");
85
+ const body = {};
86
+ if (flags["body"] !== undefined)
87
+ body.body = flags["body"];
88
+ if (flags["hook"] !== undefined)
89
+ body.hook = flags["hook"];
90
+ if (flags["cta"] !== undefined)
91
+ body.cta = flags["cta"];
92
+ if (flags["platform"] !== undefined)
93
+ body.platform = flags["platform"];
94
+ if (flags["status"] !== undefined)
95
+ body.status = flags["status"];
96
+ if (flags["hashtags"] !== undefined) {
97
+ body.hashtags = flags["hashtags"]
98
+ .split(",")
99
+ .map((h) => h.trim())
100
+ .filter(Boolean);
101
+ }
102
+ if (flags["rationale"] !== undefined)
103
+ body.rationale = flags["rationale"];
104
+ if (flags["post-type"] !== undefined)
105
+ body.post_type = flags["post-type"];
106
+ if (flags["emotional-hook"] !== undefined)
107
+ body.emotional_hook = flags["emotional-hook"];
108
+ if (flags["cta-type"] !== undefined)
109
+ body.cta_type = flags["cta-type"];
110
+ if (flags["media-style"] !== undefined)
111
+ body.media_style = flags["media-style"];
112
+ if (flags["language"] !== undefined)
113
+ body.language = flags["language"];
114
+ if (Object.keys(body).length === 0) {
115
+ console.error("No fields to update. Use --body, --hook, --cta, --platform, --status, --hashtags, --rationale, --post-type, --emotional-hook, --cta-type, --media-style, or --language.");
116
+ process.exit(1);
117
+ }
118
+ const res = await client.patch(`/projects/${projectId}/drafts/${draftId}`, body);
119
+ printJson(res.data);
120
+ };
121
+ /**
122
+ * devlog draft delete <draftId> --project=<projectId>
123
+ */
124
+ export const draftDeleteCommand = async (client, args, flags, _format) => {
125
+ const draftId = args[0];
126
+ if (!draftId) {
127
+ console.error("Usage: devlog draft delete <draftId>");
128
+ process.exit(1);
129
+ }
130
+ const projectId = flags["project"] || getActiveProjectId();
131
+ assertSafeId(draftId, "draft ID");
132
+ assertSafeId(projectId, "project ID");
133
+ await client.delete(`/projects/${projectId}/drafts/${draftId}`);
134
+ console.error("Draft deleted.");
135
+ };
136
+ //# sourceMappingURL=drafts.js.map
@@ -0,0 +1,13 @@
1
+ import type { CommandHandler } from "../types.js";
2
+ /**
3
+ * devlog events list [projectId] - List events
4
+ */
5
+ export declare const eventsListCommand: CommandHandler;
6
+ /**
7
+ * devlog events add [projectId] --name=<name> --date=<YYYY-MM-DD> [--importance=<n>]
8
+ */
9
+ export declare const eventsAddCommand: CommandHandler;
10
+ /**
11
+ * devlog events remove <eventId> --project=<projectId>
12
+ */
13
+ export declare const eventsRemoveCommand: CommandHandler;
@@ -0,0 +1,69 @@
1
+ import { printJson, printTable } from "../output.js";
2
+ import { getActiveProjectId } from "../config.js";
3
+ import { assertSafeId } from "../errors.js";
4
+ /**
5
+ * devlog events list [projectId] - List events
6
+ */
7
+ export const eventsListCommand = async (client, args, _flags, format) => {
8
+ const projectId = args[0] || getActiveProjectId();
9
+ assertSafeId(projectId, "project ID");
10
+ const res = await client.get(`/projects/${projectId}/events`);
11
+ if (format === "table") {
12
+ printTable(res.data.map((e) => ({
13
+ id: e.id.slice(0, 8),
14
+ name: e.event_name,
15
+ date: e.event_date,
16
+ importance: e.importance ?? "-",
17
+ })));
18
+ }
19
+ else {
20
+ printJson(res.data);
21
+ }
22
+ };
23
+ /**
24
+ * devlog events add [projectId] --name=<name> --date=<YYYY-MM-DD> [--importance=<n>]
25
+ */
26
+ export const eventsAddCommand = async (client, args, flags, _format) => {
27
+ const projectId = args[0] || getActiveProjectId();
28
+ assertSafeId(projectId, "project ID");
29
+ const eventName = flags["name"];
30
+ const eventDate = flags["date"];
31
+ if (!eventName) {
32
+ console.error("Usage: devlog events add [projectId] --name=<name> --date=<YYYY-MM-DD>");
33
+ process.exit(1);
34
+ }
35
+ if (!eventDate) {
36
+ console.error("--date is required (YYYY-MM-DD)");
37
+ process.exit(1);
38
+ }
39
+ const body = {
40
+ event_name: eventName,
41
+ event_date: eventDate,
42
+ };
43
+ if (flags["importance"]) {
44
+ const importance = parseInt(flags["importance"], 10);
45
+ if (isNaN(importance) || importance < 1) {
46
+ console.error("--importance must be a positive integer");
47
+ process.exit(1);
48
+ }
49
+ body.importance = importance;
50
+ }
51
+ const res = await client.post(`/projects/${projectId}/events`, body);
52
+ printJson(res.data);
53
+ };
54
+ /**
55
+ * devlog events remove <eventId> --project=<projectId>
56
+ */
57
+ export const eventsRemoveCommand = async (client, args, flags, _format) => {
58
+ const eventId = args[0];
59
+ if (!eventId) {
60
+ console.error("Usage: devlog events remove <eventId>");
61
+ process.exit(1);
62
+ }
63
+ const projectId = flags["project"] || getActiveProjectId();
64
+ assertSafeId(eventId, "event ID");
65
+ assertSafeId(projectId, "project ID");
66
+ await client.delete(`/projects/${projectId}/events`, { eventId });
67
+ console.error("Event removed.");
68
+ };
69
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1,13 @@
1
+ import type { CommandHandler } from "../types.js";
2
+ /**
3
+ * devlog games list [projectId] - List similar games
4
+ */
5
+ export declare const gamesListCommand: CommandHandler;
6
+ /**
7
+ * devlog games add [projectId] --name=<name> [--note=<note>] [--appid=<appid>]
8
+ */
9
+ export declare const gamesAddCommand: CommandHandler;
10
+ /**
11
+ * devlog games remove [projectId] --name=<name>
12
+ */
13
+ export declare const gamesRemoveCommand: CommandHandler;
@@ -0,0 +1,64 @@
1
+ import { printJson, printTable } from "../output.js";
2
+ import { getActiveProjectId } from "../config.js";
3
+ import { assertSafeId } from "../errors.js";
4
+ /**
5
+ * devlog games list [projectId] - List similar games
6
+ */
7
+ export const gamesListCommand = async (client, args, _flags, format) => {
8
+ const projectId = args[0] || getActiveProjectId();
9
+ assertSafeId(projectId, "project ID");
10
+ const res = await client.get(`/projects/${projectId}/games`);
11
+ if (format === "table") {
12
+ printTable(res.data.map((g) => ({
13
+ name: g.game_name,
14
+ appid: g.steam_appid ?? "-",
15
+ reviews: g.total_reviews ?? "-",
16
+ rating: g.rating_percent != null ? `${g.rating_percent}%` : "-",
17
+ developer: g.developer ?? "-",
18
+ note: g.note ?? "-",
19
+ })));
20
+ }
21
+ else {
22
+ printJson(res.data);
23
+ }
24
+ };
25
+ /**
26
+ * devlog games add [projectId] --name=<name> [--note=<note>] [--appid=<appid>]
27
+ */
28
+ export const gamesAddCommand = async (client, args, flags, _format) => {
29
+ const projectId = args[0] || getActiveProjectId();
30
+ const name = flags["name"];
31
+ if (!name) {
32
+ console.error("Usage: devlog games add [projectId] --name=<name>");
33
+ process.exit(1);
34
+ }
35
+ assertSafeId(projectId, "project ID");
36
+ const body = { name };
37
+ if (flags["note"])
38
+ body.note = flags["note"];
39
+ if (flags["appid"]) {
40
+ const appid = parseInt(flags["appid"], 10);
41
+ if (isNaN(appid) || appid < 0) {
42
+ console.error("--appid must be a positive integer");
43
+ process.exit(1);
44
+ }
45
+ body.steam_appid = appid;
46
+ }
47
+ const res = await client.post(`/projects/${projectId}/games`, body);
48
+ printJson(res.data);
49
+ };
50
+ /**
51
+ * devlog games remove [projectId] --name=<name>
52
+ */
53
+ export const gamesRemoveCommand = async (client, args, flags, _format) => {
54
+ const projectId = args[0] || getActiveProjectId();
55
+ const name = flags["name"];
56
+ if (!name) {
57
+ console.error("Usage: devlog games remove [projectId] --name=<name>");
58
+ process.exit(1);
59
+ }
60
+ assertSafeId(projectId, "project ID");
61
+ await client.delete(`/projects/${projectId}/games`, { name });
62
+ console.error(`Removed game: ${name}`);
63
+ };
64
+ //# sourceMappingURL=games.js.map
@@ -0,0 +1,9 @@
1
+ import type { CommandHandler } from "../types.js";
2
+ /**
3
+ * devlog history list [projectId] - List history cards
4
+ */
5
+ export declare const historyListCommand: CommandHandler;
6
+ /**
7
+ * devlog history add [projectId] --title=<title> [--type=note|milestone] [--summary=<text>] [--date=<YYYY-MM-DD>]
8
+ */
9
+ export declare const historyAddCommand: CommandHandler;
@@ -0,0 +1,44 @@
1
+ import { printJson, printTable } from "../output.js";
2
+ import { getActiveProjectId } from "../config.js";
3
+ import { assertSafeId } from "../errors.js";
4
+ /**
5
+ * devlog history list [projectId] - List history cards
6
+ */
7
+ export const historyListCommand = async (client, args, _flags, format) => {
8
+ const projectId = args[0] || getActiveProjectId();
9
+ assertSafeId(projectId, "project ID");
10
+ const res = await client.get(`/projects/${projectId}/history`);
11
+ if (format === "table") {
12
+ printTable(res.data.map((c) => ({
13
+ id: c.id.slice(0, 8),
14
+ type: c.source_type,
15
+ title: c.title,
16
+ date: c.occurred_at.slice(0, 10),
17
+ })));
18
+ }
19
+ else {
20
+ printJson(res.data);
21
+ }
22
+ };
23
+ /**
24
+ * devlog history add [projectId] --title=<title> [--type=note|milestone] [--summary=<text>] [--date=<YYYY-MM-DD>]
25
+ */
26
+ export const historyAddCommand = async (client, args, flags, _format) => {
27
+ const projectId = args[0] || getActiveProjectId();
28
+ const title = flags["title"];
29
+ if (!title) {
30
+ console.error("Usage: devlog history add [projectId] --title=<title>");
31
+ process.exit(1);
32
+ }
33
+ assertSafeId(projectId, "project ID");
34
+ const body = { title };
35
+ if (flags["type"])
36
+ body.sourceType = flags["type"];
37
+ if (flags["summary"])
38
+ body.summary = flags["summary"];
39
+ if (flags["date"])
40
+ body.occurredAt = flags["date"];
41
+ const res = await client.post(`/projects/${projectId}/history`, body);
42
+ printJson(res.data);
43
+ };
44
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1,26 @@
1
+ import type { CommandHandler } from "../types.js";
2
+ /**
3
+ * devlog project list - List all projects
4
+ */
5
+ export declare const projectListCommand: CommandHandler;
6
+ /**
7
+ * devlog project show <id> - Show project details
8
+ */
9
+ export declare const projectShowCommand: CommandHandler;
10
+ /**
11
+ * devlog project create - Create a new project
12
+ */
13
+ export declare const projectCreateCommand: CommandHandler;
14
+ /**
15
+ * devlog project update <id> - Update project fields
16
+ */
17
+ export declare const projectUpdateCommand: CommandHandler;
18
+ /**
19
+ * devlog project delete <id> - Delete a project
20
+ */
21
+ export declare const projectDeleteCommand: CommandHandler;
22
+ /**
23
+ * devlog project use <id> - Set active project
24
+ * Accepts full UUID or short prefix (e.g. first 8 chars from table output).
25
+ */
26
+ export declare const projectUseCommand: CommandHandler;
@@ -0,0 +1,120 @@
1
+ import { printJson, printTable } from "../output.js";
2
+ import { setActiveProjectId, getActiveProjectIdOptional } from "../config.js";
3
+ import { assertSafeId } from "../errors.js";
4
+ /**
5
+ * devlog project list - List all projects
6
+ */
7
+ export const projectListCommand = async (client, _args, _flags, format) => {
8
+ const res = await client.get("/projects");
9
+ if (format === "table") {
10
+ printTable(res.data.map((p) => ({
11
+ id: p.id.slice(0, 8),
12
+ title: p.title || "(untitled)",
13
+ phase: p.phase || "-",
14
+ status: p.status,
15
+ created: p.created_at.slice(0, 10),
16
+ })));
17
+ }
18
+ else {
19
+ printJson(res.data);
20
+ }
21
+ };
22
+ /**
23
+ * devlog project show <id> - Show project details
24
+ */
25
+ export const projectShowCommand = async (client, args, _flags, _format) => {
26
+ const id = args[0] || getActiveProjectIdOptional();
27
+ if (!id) {
28
+ console.error('Usage: devlog project show <id>\nOr set an active project with "devlog project use <id>".');
29
+ process.exit(1);
30
+ }
31
+ assertSafeId(id, "project ID");
32
+ const res = await client.get(`/projects/${id}`);
33
+ printJson(res.data);
34
+ };
35
+ /**
36
+ * devlog project create - Create a new project
37
+ */
38
+ export const projectCreateCommand = async (client, _args, flags, _format) => {
39
+ const body = {};
40
+ if (flags["title"])
41
+ body.title = flags["title"];
42
+ if (flags["summary"])
43
+ body.summary = flags["summary"];
44
+ if (flags["phase"])
45
+ body.phase = flags["phase"];
46
+ // Parse similar games from --games="Game1,Game2" flag
47
+ if (flags["games"]) {
48
+ body.similarGames = flags["games"]
49
+ .split(",")
50
+ .map((name) => name.trim())
51
+ .filter(Boolean)
52
+ .map((name) => ({ name }));
53
+ }
54
+ const res = await client.post("/projects", body);
55
+ console.log(res.data.id);
56
+ };
57
+ /**
58
+ * devlog project update <id> - Update project fields
59
+ */
60
+ export const projectUpdateCommand = async (client, args, flags, _format) => {
61
+ const id = args[0] || getActiveProjectIdOptional();
62
+ if (!id) {
63
+ console.error('Usage: devlog project update <id> --title=<title> --summary=<summary>');
64
+ process.exit(1);
65
+ }
66
+ assertSafeId(id, "project ID");
67
+ const body = {};
68
+ if (flags["title"] !== undefined)
69
+ body.title = flags["title"];
70
+ if (flags["summary"] !== undefined)
71
+ body.summary = flags["summary"];
72
+ if (Object.keys(body).length === 0) {
73
+ console.error("No fields to update. Use --title and/or --summary.");
74
+ process.exit(1);
75
+ }
76
+ const res = await client.patch(`/projects/${id}`, body);
77
+ printJson(res.data);
78
+ };
79
+ /**
80
+ * devlog project delete <id> - Delete a project
81
+ */
82
+ export const projectDeleteCommand = async (client, args, _flags, _format) => {
83
+ const id = args[0];
84
+ if (!id) {
85
+ console.error("Usage: devlog project delete <id>");
86
+ process.exit(1);
87
+ }
88
+ assertSafeId(id, "project ID");
89
+ const res = await client.delete(`/projects/${id}`);
90
+ console.error("Project deleted.");
91
+ if (res.data.nextProjectId) {
92
+ console.error(`Next project: ${res.data.nextProjectId}`);
93
+ }
94
+ };
95
+ /**
96
+ * devlog project use <id> - Set active project
97
+ * Accepts full UUID or short prefix (e.g. first 8 chars from table output).
98
+ */
99
+ export const projectUseCommand = async (client, args, _flags, _format) => {
100
+ const input = args[0];
101
+ if (!input) {
102
+ console.error("Usage: devlog project use <id>");
103
+ process.exit(1);
104
+ }
105
+ // Resolve short prefix to full UUID
106
+ const res = await client.get("/projects");
107
+ const match = res.data.filter((p) => p.id.toLowerCase().startsWith(input.toLowerCase()));
108
+ if (match.length === 0) {
109
+ console.error(`No project found matching: ${input}`);
110
+ process.exit(1);
111
+ }
112
+ if (match.length > 1) {
113
+ console.error(`Ambiguous ID prefix "${input}" matches ${match.length} projects. Use a longer prefix.`);
114
+ process.exit(1);
115
+ }
116
+ const fullId = match[0].id;
117
+ setActiveProjectId(fullId);
118
+ console.error(`Active project set to: ${fullId}`);
119
+ };
120
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1,12 @@
1
+ import type { CommandHandler } from "../types.js";
2
+ /**
3
+ * devlog steam search --q=<query> [--tags=<t1,t2>] [--sort=<option>] [--limit=<n>]
4
+ * Search Steam games via the DevLog proxy to SteamDashboard.
5
+ */
6
+ export declare const steamSearchCommand: CommandHandler;
7
+ /**
8
+ * devlog steam details <appid>
9
+ * Get details for a specific Steam game.
10
+ * (Proxied through DevLog -> SteamDashboard)
11
+ */
12
+ export declare const steamDetailsCommand: CommandHandler;
@@ -0,0 +1,82 @@
1
+ import { printJson, printTable } from "../output.js";
2
+ /**
3
+ * devlog steam search --q=<query> [--tags=<t1,t2>] [--sort=<option>] [--limit=<n>]
4
+ * Search Steam games via the DevLog proxy to SteamDashboard.
5
+ */
6
+ export const steamSearchCommand = async (client, _args, flags, format) => {
7
+ const params = {};
8
+ if (flags["q"])
9
+ params.q = flags["q"];
10
+ if (flags["tags"])
11
+ params.tags = flags["tags"];
12
+ if (flags["tagMode"])
13
+ params.tagMode = flags["tagMode"];
14
+ if (flags["sort"])
15
+ params.sort = flags["sort"];
16
+ if (flags["limit"])
17
+ params.limit = flags["limit"];
18
+ if (flags["reviewsMin"])
19
+ params.reviewsMin = flags["reviewsMin"];
20
+ if (flags["reviewsMax"])
21
+ params.reviewsMax = flags["reviewsMax"];
22
+ if (flags["ratingMin"])
23
+ params.ratingMin = flags["ratingMin"];
24
+ if (flags["priceMin"])
25
+ params.priceMin = flags["priceMin"];
26
+ if (flags["priceMax"])
27
+ params.priceMax = flags["priceMax"];
28
+ if (flags["releaseFrom"])
29
+ params.releaseFrom = flags["releaseFrom"];
30
+ if (flags["releaseTo"])
31
+ params.releaseTo = flags["releaseTo"];
32
+ if (flags["cursor"])
33
+ params.cursor = flags["cursor"];
34
+ // This endpoint is at /api/steam/search, not /api/cli/steam/search
35
+ const res = await client.getAbsolute("/api/steam/search", params);
36
+ if (format === "table") {
37
+ printTable(res.games.map((g) => ({
38
+ appid: String(g.appid),
39
+ name: g.name,
40
+ reviews: g.totalReviews != null ? String(g.totalReviews) : "-",
41
+ rating: g.ratingPercent != null ? `${g.ratingPercent}%` : "-",
42
+ price: formatPrice(g.priceFinal),
43
+ tags: (g.tags || []).slice(0, 3).join(", "),
44
+ })));
45
+ console.log(`\n${res.total} total${res.hasMore ? " | more available" : ""}`);
46
+ }
47
+ else {
48
+ printJson(res);
49
+ }
50
+ };
51
+ /**
52
+ * devlog steam details <appid>
53
+ * Get details for a specific Steam game.
54
+ * (Proxied through DevLog -> SteamDashboard)
55
+ */
56
+ export const steamDetailsCommand = async (client, args, _flags, _format) => {
57
+ const appid = args[0];
58
+ if (!appid) {
59
+ console.error("Usage: devlog steam details <appid>");
60
+ process.exit(1);
61
+ }
62
+ const id = parseInt(appid, 10);
63
+ if (isNaN(id) || id <= 0) {
64
+ console.error(`Invalid appid: ${appid}`);
65
+ process.exit(1);
66
+ }
67
+ const res = await client.getAbsolute("/api/steam/search", { q: appid, limit: 10 });
68
+ const match = res.games.find((g) => g.appid === id);
69
+ if (!match) {
70
+ console.error(`No game found with appid: ${appid}`);
71
+ process.exit(3);
72
+ }
73
+ printJson(match);
74
+ };
75
+ function formatPrice(priceInCents) {
76
+ if (priceInCents == null)
77
+ return "-";
78
+ if (priceInCents === 0)
79
+ return "Free";
80
+ return `$${(priceInCents / 100).toFixed(2)}`;
81
+ }
82
+ //# sourceMappingURL=steam.js.map
@@ -0,0 +1,36 @@
1
+ export declare const CONFIG_DIR: string;
2
+ export interface Config {
3
+ apiUrl: string;
4
+ token: string | undefined;
5
+ }
6
+ /**
7
+ * Resolve configuration from flags, env vars, config file, and stored token.
8
+ *
9
+ * Priority:
10
+ * 1. --token flag / DEVLOG_TOKEN env var (explicit token)
11
+ * 2. Stored token (from `devlog login`)
12
+ * 3. Neither -- error at request time
13
+ */
14
+ export declare function resolveConfig(flags: Record<string, string>): Config;
15
+ /**
16
+ * Get the active project ID from config.
17
+ * Returns the ID or exits with a helpful error message.
18
+ */
19
+ export declare function getActiveProjectId(): string;
20
+ /**
21
+ * Set the active project ID in config.
22
+ */
23
+ export declare function setActiveProjectId(projectId: string): void;
24
+ /**
25
+ * Get the active project ID from config, or undefined if not set.
26
+ * Does not exit on missing -- use when the ID is optional.
27
+ */
28
+ export declare function getActiveProjectIdOptional(): string | undefined;
29
+ /**
30
+ * Parse CLI arguments into command, positional args, and flags.
31
+ */
32
+ export declare function parseArgs(argv: string[]): {
33
+ command: string;
34
+ args: string[];
35
+ flags: Record<string, string>;
36
+ };