@benglo/storu-cli 1.0.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,80 @@
1
+ export interface ApiResponse<T> {
2
+ success: boolean;
3
+ data?: T;
4
+ error?: string;
5
+ meta?: {
6
+ total: number;
7
+ page: number;
8
+ limit: number;
9
+ };
10
+ }
11
+ export interface ListEpicsFilters {
12
+ app_id?: string;
13
+ status?: string;
14
+ }
15
+ export interface ListStoriesFilters {
16
+ app_id?: string;
17
+ epic_id?: string;
18
+ status?: string;
19
+ assignee_id?: string;
20
+ label_id?: string;
21
+ priority?: string;
22
+ no_epic?: boolean;
23
+ sort?: string;
24
+ page?: number;
25
+ limit?: number;
26
+ }
27
+ export interface CreateEpicData {
28
+ application_id: string;
29
+ title: string;
30
+ description?: string;
31
+ status?: string;
32
+ sort_order?: number;
33
+ }
34
+ export interface CreateStoryData {
35
+ application_id: string;
36
+ epic_id?: string;
37
+ title: string;
38
+ description?: string;
39
+ acceptance_criteria?: string[];
40
+ status?: string;
41
+ priority?: string;
42
+ assignee_id?: string;
43
+ sort_order?: number;
44
+ label_ids?: string[];
45
+ }
46
+ export interface UpdateStoryData {
47
+ version: number;
48
+ title?: string;
49
+ description?: string;
50
+ acceptance_criteria?: string[];
51
+ status?: string;
52
+ priority?: string;
53
+ assignee_id?: string;
54
+ epic_id?: string | null;
55
+ sort_order?: number;
56
+ label_ids?: string[];
57
+ }
58
+ export interface CreateReleaseData {
59
+ application_id: string;
60
+ title: string;
61
+ description?: string;
62
+ story_ids?: string[];
63
+ }
64
+ export declare class StoruApiClient {
65
+ private readonly baseUrl;
66
+ private readonly apiKey;
67
+ constructor(baseUrl: string, apiKey: string);
68
+ private request;
69
+ listApps(): Promise<ApiResponse<unknown[]>>;
70
+ listEpics(filters?: ListEpicsFilters): Promise<ApiResponse<unknown[]>>;
71
+ listStories(filters?: ListStoriesFilters): Promise<ApiResponse<unknown[]>>;
72
+ getStory(id: string): Promise<ApiResponse<unknown>>;
73
+ createEpic(data: CreateEpicData): Promise<ApiResponse<unknown>>;
74
+ createStory(data: CreateStoryData): Promise<ApiResponse<unknown>>;
75
+ updateStory(id: string, data: UpdateStoryData): Promise<ApiResponse<unknown>>;
76
+ batchStories(stories: CreateStoryData[]): Promise<ApiResponse<unknown[]>>;
77
+ createRelease(data: CreateReleaseData): Promise<ApiResponse<unknown>>;
78
+ publishRelease(id: string): Promise<ApiResponse<unknown>>;
79
+ }
80
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;YAK7B,OAAO;IAkBf,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAI3C,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAQ1E,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAgB9E,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAInD,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAO/D,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAOjE,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAO7E,YAAY,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAOzE,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAOrE,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;CAKhE"}
@@ -0,0 +1,97 @@
1
+ export class StoruApiClient {
2
+ baseUrl;
3
+ apiKey;
4
+ constructor(baseUrl, apiKey) {
5
+ this.baseUrl = baseUrl.replace(/\/$/, "");
6
+ this.apiKey = apiKey;
7
+ }
8
+ async request(path, options = {}) {
9
+ const url = `${this.baseUrl}${path}`;
10
+ const response = await fetch(url, {
11
+ ...options,
12
+ headers: {
13
+ "Content-Type": "application/json",
14
+ "X-API-Key": this.apiKey,
15
+ ...(options.headers ?? {}),
16
+ },
17
+ });
18
+ const json = (await response.json());
19
+ return json;
20
+ }
21
+ async listApps() {
22
+ return this.request("/api/apps");
23
+ }
24
+ async listEpics(filters = {}) {
25
+ const params = new URLSearchParams();
26
+ if (filters.app_id)
27
+ params.set("app_id", filters.app_id);
28
+ if (filters.status)
29
+ params.set("status", filters.status);
30
+ const query = params.toString() ? `?${params.toString()}` : "";
31
+ return this.request(`/api/epics${query}`);
32
+ }
33
+ async listStories(filters = {}) {
34
+ const params = new URLSearchParams();
35
+ if (filters.app_id)
36
+ params.set("app_id", filters.app_id);
37
+ if (filters.epic_id)
38
+ params.set("epic_id", filters.epic_id);
39
+ if (filters.status)
40
+ params.set("status", filters.status);
41
+ if (filters.assignee_id)
42
+ params.set("assignee_id", filters.assignee_id);
43
+ if (filters.label_id)
44
+ params.set("label_id", filters.label_id);
45
+ if (filters.priority)
46
+ params.set("priority", filters.priority);
47
+ if (filters.no_epic)
48
+ params.set("no_epic", "true");
49
+ if (filters.sort)
50
+ params.set("sort", filters.sort);
51
+ if (filters.page !== undefined)
52
+ params.set("page", String(filters.page));
53
+ if (filters.limit !== undefined)
54
+ params.set("limit", String(filters.limit));
55
+ const query = params.toString() ? `?${params.toString()}` : "";
56
+ return this.request(`/api/stories${query}`);
57
+ }
58
+ async getStory(id) {
59
+ return this.request(`/api/stories/${id}`);
60
+ }
61
+ async createEpic(data) {
62
+ return this.request("/api/epics", {
63
+ method: "POST",
64
+ body: JSON.stringify(data),
65
+ });
66
+ }
67
+ async createStory(data) {
68
+ return this.request("/api/stories", {
69
+ method: "POST",
70
+ body: JSON.stringify(data),
71
+ });
72
+ }
73
+ async updateStory(id, data) {
74
+ return this.request(`/api/stories/${id}`, {
75
+ method: "PATCH",
76
+ body: JSON.stringify(data),
77
+ });
78
+ }
79
+ async batchStories(stories) {
80
+ return this.request("/api/stories/batch", {
81
+ method: "POST",
82
+ body: JSON.stringify({ stories }),
83
+ });
84
+ }
85
+ async createRelease(data) {
86
+ return this.request("/api/releases", {
87
+ method: "POST",
88
+ body: JSON.stringify(data),
89
+ });
90
+ }
91
+ async publishRelease(id) {
92
+ return this.request(`/api/releases/${id}/publish`, {
93
+ method: "POST",
94
+ });
95
+ }
96
+ }
97
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import { StoruApiClient } from "../api-client.js";
3
+ export declare function registerAppsCommand(program: Command, client: StoruApiClient): void;
4
+ //# sourceMappingURL=apps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAUlD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CA4BlF"}
@@ -0,0 +1,25 @@
1
+ export function registerAppsCommand(program, client) {
2
+ program
3
+ .command("apps")
4
+ .description("List all applications")
5
+ .action(async () => {
6
+ const result = await client.listApps();
7
+ if (!result.success || !result.data) {
8
+ process.stderr.write(`Error: ${result.error ?? "Failed to list apps"}\n`);
9
+ process.exit(1);
10
+ }
11
+ const rows = result.data;
12
+ if (rows.length === 0) {
13
+ process.stdout.write("No applications found.\n");
14
+ return;
15
+ }
16
+ const tableData = rows.map((app) => ({
17
+ ID: app.id,
18
+ Name: app.name,
19
+ Slug: app.slug,
20
+ Description: app.description ?? "",
21
+ }));
22
+ console.table(tableData);
23
+ });
24
+ }
25
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,mBAAmB,CAAC,OAAgB,EAAE,MAAsB;IAC1E,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,uBAAuB,CAAC;SACpC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAEvC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,IAAI,qBAAqB,IAAI,CAAC,CAAC;YAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAgB,CAAC;QAErC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACnC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE;SACnC,CAAC,CAAC,CAAC;QAEJ,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import { StoruApiClient } from "../api-client.js";
3
+ export declare function registerEpicsCommand(program: Command, client: StoruApiClient): void;
4
+ //# sourceMappingURL=epics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epics.d.ts","sourceRoot":"","sources":["../../src/commands/epics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAWlD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAiCnF"}
@@ -0,0 +1,30 @@
1
+ export function registerEpicsCommand(program, client) {
2
+ program
3
+ .command("epics")
4
+ .description("List epics for an application")
5
+ .requiredOption("--app <slug-or-id>", "Application slug or ID")
6
+ .option("--status <status>", "Filter by status (backlog|in_progress|done)")
7
+ .action(async (options) => {
8
+ const result = await client.listEpics({
9
+ app_id: options.app,
10
+ status: options.status,
11
+ });
12
+ if (!result.success || !result.data) {
13
+ process.stderr.write(`Error: ${result.error ?? "Failed to list epics"}\n`);
14
+ process.exit(1);
15
+ }
16
+ const rows = result.data;
17
+ if (rows.length === 0) {
18
+ process.stdout.write("No epics found.\n");
19
+ return;
20
+ }
21
+ const tableData = rows.map((epic) => ({
22
+ ID: epic.id,
23
+ Title: epic.title,
24
+ Status: epic.status,
25
+ Stories: epic.story_count ?? 0,
26
+ }));
27
+ console.table(tableData);
28
+ });
29
+ }
30
+ //# sourceMappingURL=epics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epics.js","sourceRoot":"","sources":["../../src/commands/epics.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,oBAAoB,CAAC,OAAgB,EAAE,MAAsB;IAC3E,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,cAAc,CAAC,oBAAoB,EAAE,wBAAwB,CAAC;SAC9D,MAAM,CAAC,mBAAmB,EAAE,6CAA6C,CAAC;SAC1E,MAAM,CAAC,KAAK,EAAE,OAAyC,EAAE,EAAE;QAC1D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC;YACpC,MAAM,EAAE,OAAO,CAAC,GAAG;YACnB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,IAAI,sBAAsB,IAAI,CAAC,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAiB,CAAC;QAEtC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpC,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC;SAC/B,CAAC,CAAC,CAAC;QAEJ,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import { StoruApiClient } from "../api-client.js";
3
+ export declare function registerReleasesCommand(program: Command, client: StoruApiClient): void;
4
+ //# sourceMappingURL=releases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releases.d.ts","sourceRoot":"","sources":["../../src/commands/releases.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAYlD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAyDtF"}
@@ -0,0 +1,45 @@
1
+ export function registerReleasesCommand(program, client) {
2
+ const releaseCmd = program.command("release").description("Manage releases");
3
+ releaseCmd
4
+ .command("create")
5
+ .description("Create a new release")
6
+ .requiredOption("--app <id>", "Application UUID")
7
+ .requiredOption("--title <title>", "Release title")
8
+ .option("--description <text>", "Release description")
9
+ .option("--stories <ids>", "Comma-separated story UUIDs to include")
10
+ .action(async (options) => {
11
+ const storyIds = options.stories
12
+ ? options.stories.split(",").map((s) => s.trim()).filter(Boolean)
13
+ : undefined;
14
+ const result = await client.createRelease({
15
+ application_id: options.app,
16
+ title: options.title,
17
+ description: options.description,
18
+ story_ids: storyIds,
19
+ });
20
+ if (!result.success || !result.data) {
21
+ process.stderr.write(`Error: ${result.error ?? "Failed to create release"}\n`);
22
+ process.exit(1);
23
+ }
24
+ const release = result.data;
25
+ process.stdout.write(`Release created: ${release.id}\n`);
26
+ process.stdout.write(` Title: ${release.title}\n`);
27
+ process.stdout.write(` Status: ${release.status}\n`);
28
+ });
29
+ releaseCmd
30
+ .command("publish <id>")
31
+ .description("Publish a draft release")
32
+ .action(async (id) => {
33
+ const result = await client.publishRelease(id);
34
+ if (!result.success || !result.data) {
35
+ process.stderr.write(`Error: ${result.error ?? "Failed to publish release"}\n`);
36
+ process.exit(1);
37
+ }
38
+ const release = result.data;
39
+ process.stdout.write(`Release published: ${release.id}\n`);
40
+ process.stdout.write(` Title: ${release.title}\n`);
41
+ process.stdout.write(` Status: ${release.status}\n`);
42
+ process.stdout.write(` Published at: ${release.published_at ?? "unknown"}\n`);
43
+ });
44
+ }
45
+ //# sourceMappingURL=releases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releases.js","sourceRoot":"","sources":["../../src/commands/releases.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,uBAAuB,CAAC,OAAgB,EAAE,MAAsB;IAC9E,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAE7E,UAAU;SACP,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,sBAAsB,CAAC;SACnC,cAAc,CAAC,YAAY,EAAE,kBAAkB,CAAC;SAChD,cAAc,CAAC,iBAAiB,EAAE,eAAe,CAAC;SAClD,MAAM,CAAC,sBAAsB,EAAE,qBAAqB,CAAC;SACrD,MAAM,CAAC,iBAAiB,EAAE,wCAAwC,CAAC;SACnE,MAAM,CACL,KAAK,EAAE,OAKN,EAAE,EAAE;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO;YAC9B,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YACjE,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC;YACxC,cAAc,EAAE,OAAO,CAAC,GAAG;YAC3B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS,EAAE,QAAQ;SACpB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,IAAI,0BAA0B,IAAI,CAAC,CAAC;YAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAkB,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;QACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IACxD,CAAC,CACF,CAAC;IAEJ,UAAU;SACP,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAE/C,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,KAAK,IAAI,2BAA2B,IAAI,CAAC,CAAC;YAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAkB,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QAC5D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,OAAO,CAAC,YAAY,IAAI,SAAS,IAAI,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Command } from "commander";
2
+ import { StoruApiClient } from "../api-client.js";
3
+ export declare function registerStoriesCommand(program: Command, client: StoruApiClient): void;
4
+ //# sourceMappingURL=stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stories.d.ts","sourceRoot":"","sources":["../../src/commands/stories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAmBlD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAqKrF"}
@@ -0,0 +1,126 @@
1
+ export function registerStoriesCommand(program, client) {
2
+ const storiesCmd = program
3
+ .command("stories")
4
+ .description("List stories for an application")
5
+ .requiredOption("--app <slug-or-id>", "Application slug or ID")
6
+ .option("--status <status>", "Filter by status (backlog|in_progress|in_review|done)")
7
+ .option("--assignee <id>", "Filter by assignee profile UUID")
8
+ .option("--priority <priority>", "Filter by priority (low|medium|high|critical)")
9
+ .option("--epic <id>", "Filter by epic UUID")
10
+ .action(async (options) => {
11
+ const result = await client.listStories({
12
+ app_id: options.app,
13
+ status: options.status,
14
+ assignee_id: options.assignee,
15
+ priority: options.priority,
16
+ epic_id: options.epic,
17
+ });
18
+ if (!result.success || !result.data) {
19
+ process.stderr.write(`Error: ${result.error ?? "Failed to list stories"}\n`);
20
+ process.exit(1);
21
+ }
22
+ const rows = result.data;
23
+ if (rows.length === 0) {
24
+ process.stdout.write("No stories found.\n");
25
+ return;
26
+ }
27
+ const tableData = rows.map((story) => ({
28
+ ID: story.id,
29
+ Title: story.title,
30
+ Status: story.status,
31
+ Priority: story.priority,
32
+ Assignee: story.assignee_id ?? "",
33
+ Epic: story.epic_id ?? "",
34
+ }));
35
+ console.table(tableData);
36
+ });
37
+ const storyCmd = program.command("story").description("Manage a single story");
38
+ storyCmd
39
+ .command("get <id>")
40
+ .description("Get full details for a story")
41
+ .action(async (id) => {
42
+ const result = await client.getStory(id);
43
+ if (!result.success || !result.data) {
44
+ process.stderr.write(`Error: ${result.error ?? "Failed to get story"}\n`);
45
+ process.exit(1);
46
+ }
47
+ const story = result.data;
48
+ process.stdout.write(`\nStory: ${story.title}\n`);
49
+ process.stdout.write(`${"─".repeat(60)}\n`);
50
+ process.stdout.write(`ID: ${story.id}\n`);
51
+ process.stdout.write(`Status: ${story.status}\n`);
52
+ process.stdout.write(`Priority: ${story.priority}\n`);
53
+ process.stdout.write(`App: ${story.application_id}\n`);
54
+ process.stdout.write(`Epic: ${story.epic_id ?? "(none)"}\n`);
55
+ process.stdout.write(`Assignee: ${story.assignee_id ?? "(none)"}\n`);
56
+ process.stdout.write(`Version: ${story.version}\n`);
57
+ if (story.description) {
58
+ process.stdout.write(`\nDescription:\n${story.description}\n`);
59
+ }
60
+ if (story.acceptance_criteria && story.acceptance_criteria.length > 0) {
61
+ process.stdout.write(`\nAcceptance Criteria:\n`);
62
+ for (const criterion of story.acceptance_criteria) {
63
+ process.stdout.write(` - ${criterion}\n`);
64
+ }
65
+ }
66
+ if (Array.isArray(story.labels) && story.labels.length > 0) {
67
+ process.stdout.write(`\nLabels: ${JSON.stringify(story.labels)}\n`);
68
+ }
69
+ if (Array.isArray(story.activity) && story.activity.length > 0) {
70
+ process.stdout.write(`\nRecent Activity (${story.activity.length} entries)\n`);
71
+ }
72
+ });
73
+ storyCmd
74
+ .command("create")
75
+ .description("Create a new story")
76
+ .requiredOption("--app <id>", "Application UUID")
77
+ .requiredOption("--title <title>", "Story title")
78
+ .option("--epic <id>", "Parent epic UUID")
79
+ .option("--priority <priority>", "Priority (low|medium|high|critical)")
80
+ .option("--assignee <id>", "Assignee profile UUID")
81
+ .option("--description <text>", "Story description")
82
+ .action(async (options) => {
83
+ const result = await client.createStory({
84
+ application_id: options.app,
85
+ title: options.title,
86
+ epic_id: options.epic,
87
+ priority: options.priority,
88
+ assignee_id: options.assignee,
89
+ description: options.description,
90
+ });
91
+ if (!result.success || !result.data) {
92
+ process.stderr.write(`Error: ${result.error ?? "Failed to create story"}\n`);
93
+ process.exit(1);
94
+ }
95
+ const story = result.data;
96
+ process.stdout.write(`Story created: ${story.id}\n`);
97
+ process.stdout.write(` Title: ${story.title}\n`);
98
+ process.stdout.write(` Status: ${story.status}\n`);
99
+ process.stdout.write(` Priority: ${story.priority}\n`);
100
+ });
101
+ storyCmd
102
+ .command("move <id> <status>")
103
+ .description("Change the status of a story")
104
+ .action(async (id, status) => {
105
+ // Fetch current version first
106
+ const getResult = await client.getStory(id);
107
+ if (!getResult.success || !getResult.data) {
108
+ process.stderr.write(`Error: ${getResult.error ?? "Story not found"}\n`);
109
+ process.exit(1);
110
+ }
111
+ const current = getResult.data;
112
+ const result = await client.updateStory(id, {
113
+ version: current.version,
114
+ status,
115
+ });
116
+ if (!result.success || !result.data) {
117
+ process.stderr.write(`Error: ${result.error ?? "Failed to move story"}\n`);
118
+ process.exit(1);
119
+ }
120
+ const story = result.data;
121
+ process.stdout.write(`Story ${story.id} moved to '${story.status}'\n`);
122
+ });
123
+ // Silence unused variable warning
124
+ void storiesCmd;
125
+ }
126
+ //# sourceMappingURL=stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stories.js","sourceRoot":"","sources":["../../src/commands/stories.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface StoruConfig {
2
+ api_url: string;
3
+ api_key: string;
4
+ }
5
+ export declare function configPath(): string;
6
+ export declare function configExists(): boolean;
7
+ /**
8
+ * Resolve config from (in order):
9
+ * 1. Environment variables (STORU_API_URL + STORU_API_KEY)
10
+ * 2. Config file (~/.storu/config.json)
11
+ */
12
+ export declare function readConfig(): StoruConfig;
13
+ export declare function writeConfig(config: StoruConfig): void;
14
+ export declare function runInit(): Promise<void>;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAKD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,WAAW,CAmCxC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAIrD;AAaD,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAiD7C"}
package/dist/config.js ADDED
@@ -0,0 +1,104 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ import { createInterface } from "readline";
5
+ const CONFIG_DIR = join(homedir(), ".storu");
6
+ const CONFIG_FILE = join(CONFIG_DIR, "config.json");
7
+ export function configPath() {
8
+ return CONFIG_FILE;
9
+ }
10
+ export function configExists() {
11
+ return existsSync(CONFIG_FILE);
12
+ }
13
+ /**
14
+ * Resolve config from (in order):
15
+ * 1. Environment variables (STORU_API_URL + STORU_API_KEY)
16
+ * 2. Config file (~/.storu/config.json)
17
+ */
18
+ export function readConfig() {
19
+ // Env vars take priority (useful for CI, MCP server, etc.)
20
+ const envUrl = process.env.STORU_API_URL;
21
+ const envKey = process.env.STORU_API_KEY;
22
+ if (envUrl && envKey) {
23
+ return { api_url: envUrl, api_key: envKey };
24
+ }
25
+ let raw;
26
+ try {
27
+ raw = readFileSync(CONFIG_FILE, "utf-8");
28
+ }
29
+ catch {
30
+ throw new Error(`Not configured. Run 'storu init' to set up.`);
31
+ }
32
+ let parsed;
33
+ try {
34
+ parsed = JSON.parse(raw);
35
+ }
36
+ catch {
37
+ throw new Error(`Config at ${CONFIG_FILE} contains invalid JSON. Run 'storu init' to fix.`);
38
+ }
39
+ const cfg = parsed;
40
+ if (typeof cfg.api_url !== "string" || cfg.api_url.length === 0) {
41
+ throw new Error(`Config is missing 'api_url'. Run 'storu init' to fix.`);
42
+ }
43
+ if (typeof cfg.api_key !== "string" || cfg.api_key.length === 0) {
44
+ throw new Error(`Config is missing 'api_key'. Run 'storu init' to fix.`);
45
+ }
46
+ return { api_url: cfg.api_url, api_key: cfg.api_key };
47
+ }
48
+ export function writeConfig(config) {
49
+ mkdirSync(CONFIG_DIR, { recursive: true });
50
+ const content = JSON.stringify(config, null, 2) + "\n";
51
+ writeFileSync(CONFIG_FILE, content, { mode: 0o600 });
52
+ }
53
+ function prompt(question, defaultValue) {
54
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
55
+ const suffix = defaultValue ? ` (${defaultValue})` : "";
56
+ return new Promise((resolve) => {
57
+ rl.question(`${question}${suffix}: `, (answer) => {
58
+ rl.close();
59
+ resolve(answer.trim() || defaultValue || "");
60
+ });
61
+ });
62
+ }
63
+ export async function runInit() {
64
+ console.log("\n Storu CLI Setup\n");
65
+ const existing = configExists();
66
+ let defaults = {};
67
+ if (existing) {
68
+ try {
69
+ defaults = readConfig();
70
+ console.log(` Existing config found at ${CONFIG_FILE}\n`);
71
+ }
72
+ catch {
73
+ // Ignore — broken config, we'll overwrite
74
+ }
75
+ }
76
+ const apiUrl = await prompt(" API URL", defaults.api_url || "https://storu.netlify.app");
77
+ const apiKey = await prompt(" API Key", defaults.api_key);
78
+ if (!apiUrl || !apiKey) {
79
+ console.error("\n Both API URL and API Key are required.\n");
80
+ process.exit(1);
81
+ }
82
+ writeConfig({ api_url: apiUrl, api_key: apiKey });
83
+ console.log(`\n Config saved to ${CONFIG_FILE}`);
84
+ console.log(` Permissions set to owner-only (600)\n`);
85
+ // Test the connection
86
+ console.log(" Testing connection...");
87
+ try {
88
+ const res = await fetch(`${apiUrl}/api/apps`, {
89
+ headers: { "X-API-Key": apiKey },
90
+ });
91
+ if (res.ok) {
92
+ const data = await res.json();
93
+ const count = data.data?.length ?? 0;
94
+ console.log(` Connected! Found ${count} application${count !== 1 ? "s" : ""}.\n`);
95
+ }
96
+ else {
97
+ console.log(` Warning: API returned ${res.status}. Check your URL and key.\n`);
98
+ }
99
+ }
100
+ catch {
101
+ console.log(` Warning: Could not reach ${apiUrl}. Check the URL.\n`);
102
+ }
103
+ }
104
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { readConfig, runInit } from "./config.js";
4
+ import { StoruApiClient } from "./api-client.js";
5
+ import { registerAppsCommand } from "./commands/apps.js";
6
+ import { registerEpicsCommand } from "./commands/epics.js";
7
+ import { registerStoriesCommand } from "./commands/stories.js";
8
+ import { registerReleasesCommand } from "./commands/releases.js";
9
+ const program = new Command();
10
+ program
11
+ .name("storu")
12
+ .description("Storu — agile focus tool CLI")
13
+ .version("1.0.0");
14
+ // Init doesn't need an API client
15
+ program
16
+ .command("init")
17
+ .description("Set up Storu CLI with your API URL and key")
18
+ .action(async () => {
19
+ await runInit();
20
+ });
21
+ // All other commands need a configured client
22
+ function getClient() {
23
+ try {
24
+ const config = readConfig();
25
+ return new StoruApiClient(config.api_url, config.api_key);
26
+ }
27
+ catch (err) {
28
+ const message = err instanceof Error ? err.message : "Configuration error";
29
+ process.stderr.write(`${message}\n`);
30
+ process.exit(1);
31
+ }
32
+ }
33
+ // Lazy-init: only resolve config when a command actually runs
34
+ const client = new Proxy({}, {
35
+ get(_target, prop) {
36
+ const real = getClient();
37
+ return real[prop].bind(real);
38
+ },
39
+ });
40
+ registerAppsCommand(program, client);
41
+ registerEpicsCommand(program, client);
42
+ registerStoriesCommand(program, client);
43
+ registerReleasesCommand(program, client);
44
+ program.parse(process.argv);
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,8BAA8B,CAAC;KAC3C,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,kCAAkC;AAClC,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,EAAE,CAAC;AAClB,CAAC,CAAC,CAAC;AAEL,8CAA8C;AAC9C,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;QAC3E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,8DAA8D;AAC9D,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,EAAoB,EAAE;IAC7C,GAAG,CAAC,OAAO,EAAE,IAAI;QACf,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;QACzB,OAAQ,IAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CACF,CAAC,CAAC;AAEH,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACrC,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACtC,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACxC,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAEzC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@benglo/storu-cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI for Storu project management",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "storu": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "dev": "node --watch dist/index.js",
16
+ "prepublishOnly": "npm run build",
17
+ "test": "vitest run",
18
+ "test:watch": "vitest"
19
+ },
20
+ "keywords": ["storu", "agile", "cli", "project-management"],
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/RealShift/storu.git",
25
+ "directory": "packages/cli"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "dependencies": {
31
+ "commander": "^12.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "typescript": "^5.0.0",
35
+ "vitest": "^3.0.0"
36
+ }
37
+ }