@nocoo/zhe 1.18.0 → 1.19.3
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/commands/idea/add.d.ts +22 -0
- package/dist/commands/idea/add.d.ts.map +1 -0
- package/dist/commands/idea/add.js +55 -0
- package/dist/commands/idea/add.js.map +1 -0
- package/dist/commands/idea/delete.d.ts +17 -0
- package/dist/commands/idea/delete.d.ts.map +1 -0
- package/dist/commands/idea/delete.js +47 -0
- package/dist/commands/idea/delete.js.map +1 -0
- package/dist/commands/idea/get.d.ts +12 -0
- package/dist/commands/idea/get.d.ts.map +1 -0
- package/dist/commands/idea/get.js +45 -0
- package/dist/commands/idea/get.js.map +1 -0
- package/dist/commands/idea/helpers.d.ts +13 -0
- package/dist/commands/idea/helpers.d.ts.map +1 -0
- package/dist/commands/idea/helpers.js +78 -0
- package/dist/commands/idea/helpers.js.map +1 -0
- package/dist/commands/idea/list.d.ts +22 -0
- package/dist/commands/idea/list.d.ts.map +1 -0
- package/dist/commands/idea/list.js +64 -0
- package/dist/commands/idea/list.js.map +1 -0
- package/dist/commands/idea/update.d.ts +27 -0
- package/dist/commands/idea/update.d.ts.map +1 -0
- package/dist/commands/idea/update.js +78 -0
- package/dist/commands/idea/update.js.map +1 -0
- package/dist/commands/idea.d.ts +6 -2
- package/dist/commands/idea.d.ts.map +1 -1
- package/dist/commands/idea.js +12 -393
- package/dist/commands/idea.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +97 -96
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +56 -59
- package/dist/commands/update.js.map +1 -1
- package/dist/utils/format.d.ts +27 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +157 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/resolve.d.ts +41 -0
- package/dist/utils/resolve.d.ts.map +1 -0
- package/dist/utils/resolve.js +69 -0
- package/dist/utils/resolve.js.map +1 -0
- package/dist/utils.d.ts +17 -90
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +20 -250
- package/dist/utils.js.map +1 -1
- package/package.json +10 -6
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const addSubcommand: import("citty").CommandDef<{
|
|
2
|
+
readonly content: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Idea content (Markdown)";
|
|
5
|
+
readonly required: true;
|
|
6
|
+
};
|
|
7
|
+
readonly title: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly alias: "t";
|
|
10
|
+
readonly description: "Optional title";
|
|
11
|
+
};
|
|
12
|
+
readonly tag: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly alias: "T";
|
|
15
|
+
readonly description: "Add tag by name";
|
|
16
|
+
};
|
|
17
|
+
readonly json: {
|
|
18
|
+
readonly type: "boolean";
|
|
19
|
+
readonly description: "Output as JSON";
|
|
20
|
+
};
|
|
21
|
+
}>;
|
|
22
|
+
//# sourceMappingURL=add.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/idea/add.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;EAuDxB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { defineCommand, pc } from "@nocoo/cli-base";
|
|
2
|
+
import { ApiClient, EXIT_INVALID_ARGS } from "../../api/client.js";
|
|
3
|
+
import { resolveTagName } from "../../utils.js";
|
|
4
|
+
import { formatDate, handleApiError, requireAuth } from "./helpers.js";
|
|
5
|
+
export const addSubcommand = defineCommand({
|
|
6
|
+
meta: {
|
|
7
|
+
name: "add",
|
|
8
|
+
description: "Create a new idea",
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
content: {
|
|
12
|
+
type: "positional",
|
|
13
|
+
description: "Idea content (Markdown)",
|
|
14
|
+
required: true,
|
|
15
|
+
},
|
|
16
|
+
title: { type: "string", alias: "t", description: "Optional title" },
|
|
17
|
+
tag: { type: "string", alias: "T", description: "Add tag by name" },
|
|
18
|
+
json: { type: "boolean", description: "Output as JSON" },
|
|
19
|
+
},
|
|
20
|
+
async run({ args }) {
|
|
21
|
+
const apiKey = requireAuth();
|
|
22
|
+
const client = new ApiClient(apiKey);
|
|
23
|
+
const content = args.content;
|
|
24
|
+
if (!content.trim()) {
|
|
25
|
+
console.log(pc.red("Content cannot be empty."));
|
|
26
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
let tagIds;
|
|
30
|
+
if (args.tag) {
|
|
31
|
+
const tagId = await resolveTagName(client, args.tag);
|
|
32
|
+
if (tagId === null)
|
|
33
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
34
|
+
tagIds = [tagId];
|
|
35
|
+
}
|
|
36
|
+
const request = {
|
|
37
|
+
content,
|
|
38
|
+
...(args.title && { title: args.title }),
|
|
39
|
+
...(tagIds && { tagIds }),
|
|
40
|
+
};
|
|
41
|
+
const response = await client.createIdea(request);
|
|
42
|
+
if (args.json) {
|
|
43
|
+
console.log(JSON.stringify(response, null, 2));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const { idea } = response;
|
|
47
|
+
const title = idea.title || formatDate(idea.createdAt);
|
|
48
|
+
console.log(pc.green(`✓ Created idea ${pc.cyan(`#${idea.id}`)} (${title})`));
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
handleApiError(error);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/commands/idea/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEvE,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IAC1C,IAAI,EAAE;QACL,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,mBAAmB;KAChC;IACD,IAAI,EAAE;QACL,OAAO,EAAE;YACR,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,IAAI;SACd;QACD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,gBAAgB,EAAE;QACpE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,iBAAiB,EAAE;QACnE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE;KACxD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAiB,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACJ,IAAI,MAA4B,CAAC;YACjC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACd,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrD,IAAI,KAAK,KAAK,IAAI;oBAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBACpD,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,OAAO,GAAsB;gBAClC,OAAO;gBACP,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACxC,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;aACzB,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAElD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/C,OAAO;YACR,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CACV,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,CAC/D,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const deleteSubcommand: import("citty").CommandDef<{
|
|
2
|
+
readonly id: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Idea ID";
|
|
5
|
+
readonly required: true;
|
|
6
|
+
};
|
|
7
|
+
readonly yes: {
|
|
8
|
+
readonly type: "boolean";
|
|
9
|
+
readonly alias: "y";
|
|
10
|
+
readonly description: "Skip confirmation";
|
|
11
|
+
};
|
|
12
|
+
readonly json: {
|
|
13
|
+
readonly type: "boolean";
|
|
14
|
+
readonly description: "Output as JSON";
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/idea/delete.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;EA8C3B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineCommand, pc } from "@nocoo/cli-base";
|
|
2
|
+
import { ApiClient, EXIT_INVALID_ARGS } from "../../api/client.js";
|
|
3
|
+
import { parsePositiveInt } from "../../utils.js";
|
|
4
|
+
import { confirm, formatDate, handleApiError, requireAuth } from "./helpers.js";
|
|
5
|
+
export const deleteSubcommand = defineCommand({
|
|
6
|
+
meta: {
|
|
7
|
+
name: "delete",
|
|
8
|
+
description: "Delete an idea",
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
id: { type: "positional", description: "Idea ID", required: true },
|
|
12
|
+
yes: { type: "boolean", alias: "y", description: "Skip confirmation" },
|
|
13
|
+
json: { type: "boolean", description: "Output as JSON" },
|
|
14
|
+
},
|
|
15
|
+
async run({ args }) {
|
|
16
|
+
const apiKey = requireAuth();
|
|
17
|
+
const client = new ApiClient(apiKey);
|
|
18
|
+
const id = parsePositiveInt(args.id);
|
|
19
|
+
if (id === null) {
|
|
20
|
+
console.log(pc.red("Invalid idea ID."));
|
|
21
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
// Only fetch idea for confirmation prompt (requires ideas:read).
|
|
25
|
+
// With --yes flag, skip prefetch to allow write-only keys.
|
|
26
|
+
if (!args.yes) {
|
|
27
|
+
const { idea } = await client.getIdea(id);
|
|
28
|
+
const title = idea.title || formatDate(idea.createdAt);
|
|
29
|
+
const confirmed = await confirm(`Delete idea #${id} (${title})?`);
|
|
30
|
+
if (!confirmed) {
|
|
31
|
+
console.log(pc.dim("Cancelled."));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
await client.deleteIdea(id);
|
|
36
|
+
if (args.json) {
|
|
37
|
+
console.log(JSON.stringify({ success: true, id }, null, 2));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log(pc.green(`✓ Deleted idea ${pc.cyan(`#${id}`)}`));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
handleApiError(error);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/commands/idea/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhF,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;IAC7C,IAAI,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,gBAAgB;KAC7B;IACD,IAAI,EAAE;QACL,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;QAClE,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,mBAAmB,EAAE;QACtE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE;KACxD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAY,CAAC,CAAC;QAC/C,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACJ,iEAAiE;YACjE,2DAA2D;YAC3D,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACf,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEvD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,gBAAgB,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC;gBAClE,IAAI,CAAC,SAAS,EAAE,CAAC;oBAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;oBAClC,OAAO;gBACR,CAAC;YACF,CAAC;YAED,MAAM,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAE5B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5D,OAAO;YACR,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const getSubcommand: import("citty").CommandDef<{
|
|
2
|
+
readonly id: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Idea ID";
|
|
5
|
+
readonly required: true;
|
|
6
|
+
};
|
|
7
|
+
readonly json: {
|
|
8
|
+
readonly type: "boolean";
|
|
9
|
+
readonly description: "Output as JSON";
|
|
10
|
+
};
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=get.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/idea/get.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa;;;;;;;;;;EA0CxB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { defineCommand, pc } from "@nocoo/cli-base";
|
|
2
|
+
import { ApiClient, EXIT_INVALID_ARGS } from "../../api/client.js";
|
|
3
|
+
import { parsePositiveInt } from "../../utils.js";
|
|
4
|
+
import { buildTagMap, formatDate, formatTags, handleApiError, requireAuth, } from "./helpers.js";
|
|
5
|
+
export const getSubcommand = defineCommand({
|
|
6
|
+
meta: {
|
|
7
|
+
name: "get",
|
|
8
|
+
description: "Get full content of an idea",
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
id: { type: "positional", description: "Idea ID", required: true },
|
|
12
|
+
json: { type: "boolean", description: "Output as JSON" },
|
|
13
|
+
},
|
|
14
|
+
async run({ args }) {
|
|
15
|
+
const apiKey = requireAuth();
|
|
16
|
+
const client = new ApiClient(apiKey);
|
|
17
|
+
const id = parsePositiveInt(args.id);
|
|
18
|
+
if (id === null) {
|
|
19
|
+
console.log(pc.red("Invalid idea ID."));
|
|
20
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const response = await client.getIdea(id);
|
|
24
|
+
if (args.json) {
|
|
25
|
+
console.log(JSON.stringify(response, null, 2));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const { idea } = response;
|
|
29
|
+
const tagMap = await buildTagMap(client, idea.tagIds ?? []);
|
|
30
|
+
const tags = formatTags(idea.tagIds, tagMap);
|
|
31
|
+
const title = idea.title || formatDate(idea.createdAt);
|
|
32
|
+
console.log(pc.dim("─".repeat(40)));
|
|
33
|
+
console.log(`Idea ${pc.cyan(`#${idea.id}`)} — ${pc.bold(title)}`);
|
|
34
|
+
if (tags)
|
|
35
|
+
console.log(`Tags: ${pc.yellow(tags)}`);
|
|
36
|
+
console.log(pc.dim("─".repeat(40)));
|
|
37
|
+
console.log();
|
|
38
|
+
console.log(idea.content);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
handleApiError(error);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/commands/idea/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACN,WAAW,EACX,UAAU,EACV,UAAU,EACV,cAAc,EACd,WAAW,GACX,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IAC1C,IAAI,EAAE;QACL,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,6BAA6B;KAC1C;IACD,IAAI,EAAE;QACL,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;QAClE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE;KACxD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,MAAM,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAY,CAAC,CAAC;QAC/C,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAE1C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/C,OAAO;YACR,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;YAC5D,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClE,IAAI,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Shared helpers for the `zhe idea` subcommands. */
|
|
2
|
+
import { type ApiClient } from "../../api/client.js";
|
|
3
|
+
export declare function requireAuth(): string;
|
|
4
|
+
export declare function handleApiError(error: unknown): never;
|
|
5
|
+
export declare function formatDate(isoDate: string): string;
|
|
6
|
+
export declare function formatTags(tagIds: string[] | null | undefined, tagMap?: Map<string, string>): string;
|
|
7
|
+
/**
|
|
8
|
+
* Build a tagId→name map by fetching all tags from API.
|
|
9
|
+
* Returns undefined on failure (display degrades to truncated IDs).
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildTagMap(client: ApiClient, tagIds: string[]): Promise<Map<string, string> | undefined>;
|
|
12
|
+
export declare function confirm(message: string): Promise<boolean>;
|
|
13
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/commands/idea/helpers.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAIrD,OAAO,EACN,KAAK,SAAS,EAMd,MAAM,qBAAqB,CAAC;AAI7B,wBAAgB,WAAW,IAAI,MAAM,CAOpC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAoBpD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASlD;AAED,wBAAgB,UAAU,CACzB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,EACnC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,MAAM,CAGR;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAChC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAQ1C;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAY/D"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** Shared helpers for the `zhe idea` subcommands. */
|
|
2
|
+
import * as readline from "node:readline";
|
|
3
|
+
import { pc } from "@nocoo/cli-base";
|
|
4
|
+
import { ApiClientError, EXIT_AUTH_REQUIRED, EXIT_ERROR, EXIT_NOT_FOUND, EXIT_RATE_LIMITED, } from "../../api/client.js";
|
|
5
|
+
import { getApiKey } from "../../config.js";
|
|
6
|
+
export function requireAuth() {
|
|
7
|
+
const apiKey = getApiKey();
|
|
8
|
+
if (!apiKey) {
|
|
9
|
+
console.log(pc.red("Not authenticated. Run `zhe login` first."));
|
|
10
|
+
process.exit(EXIT_AUTH_REQUIRED);
|
|
11
|
+
}
|
|
12
|
+
return apiKey;
|
|
13
|
+
}
|
|
14
|
+
export function handleApiError(error) {
|
|
15
|
+
if (error instanceof ApiClientError) {
|
|
16
|
+
if (error.status === 400) {
|
|
17
|
+
console.log(pc.red(`Error: ${error.message}`));
|
|
18
|
+
}
|
|
19
|
+
else if (error.status === 404) {
|
|
20
|
+
console.log(pc.red("Idea not found."));
|
|
21
|
+
process.exit(EXIT_NOT_FOUND);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.log(pc.red(`Error: ${error.message}`));
|
|
25
|
+
}
|
|
26
|
+
if (error.status === 401) {
|
|
27
|
+
process.exit(EXIT_AUTH_REQUIRED);
|
|
28
|
+
}
|
|
29
|
+
if (error.status === 429) {
|
|
30
|
+
process.exit(EXIT_RATE_LIMITED);
|
|
31
|
+
}
|
|
32
|
+
process.exit(EXIT_ERROR);
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
export function formatDate(isoDate) {
|
|
37
|
+
const date = new Date(isoDate);
|
|
38
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
39
|
+
month: "short",
|
|
40
|
+
day: "numeric",
|
|
41
|
+
year: "numeric",
|
|
42
|
+
hour: "numeric",
|
|
43
|
+
minute: "2-digit",
|
|
44
|
+
}).format(date);
|
|
45
|
+
}
|
|
46
|
+
export function formatTags(tagIds, tagMap) {
|
|
47
|
+
if (!tagIds || tagIds.length === 0)
|
|
48
|
+
return "";
|
|
49
|
+
return tagIds.map((id) => `[${tagMap?.get(id) ?? id.slice(0, 8)}]`).join(" ");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build a tagId→name map by fetching all tags from API.
|
|
53
|
+
* Returns undefined on failure (display degrades to truncated IDs).
|
|
54
|
+
*/
|
|
55
|
+
export async function buildTagMap(client, tagIds) {
|
|
56
|
+
if (tagIds.length === 0)
|
|
57
|
+
return undefined;
|
|
58
|
+
try {
|
|
59
|
+
const { tags } = await client.listTags();
|
|
60
|
+
return new Map(tags.map((t) => [t.id, t.name]));
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function confirm(message) {
|
|
67
|
+
return new Promise((resolve) => {
|
|
68
|
+
const rl = readline.createInterface({
|
|
69
|
+
input: process.stdin,
|
|
70
|
+
output: process.stdout,
|
|
71
|
+
});
|
|
72
|
+
rl.question(`${message} [y/N] `, (answer) => {
|
|
73
|
+
rl.close();
|
|
74
|
+
resolve(answer.toLowerCase() === "y");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/commands/idea/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const listSubcommand: import("citty").CommandDef<{
|
|
2
|
+
readonly limit: {
|
|
3
|
+
readonly type: "string";
|
|
4
|
+
readonly alias: "l";
|
|
5
|
+
readonly description: "Max results (default: 20)";
|
|
6
|
+
};
|
|
7
|
+
readonly tag: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly alias: "t";
|
|
10
|
+
readonly description: "Filter by tag name";
|
|
11
|
+
};
|
|
12
|
+
readonly query: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly alias: "q";
|
|
15
|
+
readonly description: "Search title and excerpt";
|
|
16
|
+
};
|
|
17
|
+
readonly json: {
|
|
18
|
+
readonly type: "boolean";
|
|
19
|
+
readonly description: "Output as JSON";
|
|
20
|
+
};
|
|
21
|
+
}>;
|
|
22
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/idea/list.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;EAsEzB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineCommand, pc } from "@nocoo/cli-base";
|
|
2
|
+
import { ApiClient, EXIT_INVALID_ARGS } from "../../api/client.js";
|
|
3
|
+
import { resolveTagName } from "../../utils.js";
|
|
4
|
+
import { buildTagMap, formatDate, formatTags, handleApiError, requireAuth, } from "./helpers.js";
|
|
5
|
+
export const listSubcommand = defineCommand({
|
|
6
|
+
meta: {
|
|
7
|
+
name: "list",
|
|
8
|
+
description: "List all ideas",
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
limit: {
|
|
12
|
+
type: "string",
|
|
13
|
+
alias: "l",
|
|
14
|
+
description: "Max results (default: 20)",
|
|
15
|
+
},
|
|
16
|
+
tag: { type: "string", alias: "t", description: "Filter by tag name" },
|
|
17
|
+
query: {
|
|
18
|
+
type: "string",
|
|
19
|
+
alias: "q",
|
|
20
|
+
description: "Search title and excerpt",
|
|
21
|
+
},
|
|
22
|
+
json: { type: "boolean", description: "Output as JSON" },
|
|
23
|
+
},
|
|
24
|
+
async run({ args }) {
|
|
25
|
+
const apiKey = requireAuth();
|
|
26
|
+
const client = new ApiClient(apiKey);
|
|
27
|
+
try {
|
|
28
|
+
let tagId;
|
|
29
|
+
if (args.tag) {
|
|
30
|
+
const resolved = await resolveTagName(client, args.tag);
|
|
31
|
+
if (resolved === null)
|
|
32
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
33
|
+
tagId = resolved;
|
|
34
|
+
}
|
|
35
|
+
const response = await client.listIdeas({
|
|
36
|
+
limit: args.limit ? Number.parseInt(args.limit, 10) : 20,
|
|
37
|
+
tagId,
|
|
38
|
+
q: args.query,
|
|
39
|
+
});
|
|
40
|
+
if (args.json) {
|
|
41
|
+
console.log(JSON.stringify(response, null, 2));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (response.ideas.length === 0) {
|
|
45
|
+
console.log(pc.yellow("No ideas found."));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const allTagIds = response.ideas.flatMap((i) => i.tagIds ?? []);
|
|
49
|
+
const tagMap = await buildTagMap(client, allTagIds);
|
|
50
|
+
console.log(pc.dim("ID TIME TITLE TAGS"));
|
|
51
|
+
console.log(pc.dim("─".repeat(56)));
|
|
52
|
+
for (const idea of response.ideas) {
|
|
53
|
+
const time = formatDate(idea.createdAt);
|
|
54
|
+
const title = (idea.title || idea.excerpt || "(no content)").slice(0, 24);
|
|
55
|
+
const tags = formatTags(idea.tagIds, tagMap);
|
|
56
|
+
console.log(`${pc.cyan(String(idea.id).padEnd(6))}${time.padEnd(17)}${title.padEnd(25)}${pc.yellow(tags)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
handleApiError(error);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/idea/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const updateSubcommand: import("citty").CommandDef<{
|
|
2
|
+
readonly id: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Idea ID";
|
|
5
|
+
readonly required: true;
|
|
6
|
+
};
|
|
7
|
+
readonly content: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly alias: "c";
|
|
10
|
+
readonly description: "New content";
|
|
11
|
+
};
|
|
12
|
+
readonly title: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly alias: "t";
|
|
15
|
+
readonly description: "New title (use empty string to clear)";
|
|
16
|
+
};
|
|
17
|
+
readonly tag: {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
readonly alias: "T";
|
|
20
|
+
readonly description: "Set tag by name (replaces all existing tags)";
|
|
21
|
+
};
|
|
22
|
+
readonly json: {
|
|
23
|
+
readonly type: "boolean";
|
|
24
|
+
readonly description: "Output as JSON";
|
|
25
|
+
};
|
|
26
|
+
}>;
|
|
27
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/idea/update.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;EA0D3B,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { defineCommand, pc } from "@nocoo/cli-base";
|
|
2
|
+
import { ApiClient, EXIT_INVALID_ARGS } from "../../api/client.js";
|
|
3
|
+
import { parsePositiveInt, resolveTagName } from "../../utils.js";
|
|
4
|
+
import { formatDate, handleApiError, requireAuth } from "./helpers.js";
|
|
5
|
+
/** Parse CLI args into an UpdateIdeaRequest, exiting on invalid tag input. */
|
|
6
|
+
async function buildUpdateRequest(client, args) {
|
|
7
|
+
const request = {};
|
|
8
|
+
if (args.content !== undefined)
|
|
9
|
+
request.content = args.content;
|
|
10
|
+
if (args.title !== undefined) {
|
|
11
|
+
request.title = args.title === "" ? null : args.title;
|
|
12
|
+
}
|
|
13
|
+
if (args.tag !== undefined) {
|
|
14
|
+
if (args.tag === "") {
|
|
15
|
+
request.tagIds = [];
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const tagId = await resolveTagName(client, args.tag);
|
|
19
|
+
if (tagId === null)
|
|
20
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
21
|
+
request.tagIds = [tagId];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return request;
|
|
25
|
+
}
|
|
26
|
+
export const updateSubcommand = defineCommand({
|
|
27
|
+
meta: {
|
|
28
|
+
name: "update",
|
|
29
|
+
description: "Update an existing idea",
|
|
30
|
+
},
|
|
31
|
+
args: {
|
|
32
|
+
id: { type: "positional", description: "Idea ID", required: true },
|
|
33
|
+
content: { type: "string", alias: "c", description: "New content" },
|
|
34
|
+
title: {
|
|
35
|
+
type: "string",
|
|
36
|
+
alias: "t",
|
|
37
|
+
description: "New title (use empty string to clear)",
|
|
38
|
+
},
|
|
39
|
+
tag: {
|
|
40
|
+
type: "string",
|
|
41
|
+
alias: "T",
|
|
42
|
+
description: "Set tag by name (replaces all existing tags)",
|
|
43
|
+
},
|
|
44
|
+
json: { type: "boolean", description: "Output as JSON" },
|
|
45
|
+
},
|
|
46
|
+
async run({ args }) {
|
|
47
|
+
const apiKey = requireAuth();
|
|
48
|
+
const client = new ApiClient(apiKey);
|
|
49
|
+
const id = parsePositiveInt(args.id);
|
|
50
|
+
if (id === null) {
|
|
51
|
+
console.log(pc.red("Invalid idea ID."));
|
|
52
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
53
|
+
}
|
|
54
|
+
const request = await buildUpdateRequest(client, {
|
|
55
|
+
content: args.content,
|
|
56
|
+
title: args.title,
|
|
57
|
+
tag: args.tag,
|
|
58
|
+
});
|
|
59
|
+
if (Object.keys(request).length === 0) {
|
|
60
|
+
console.log(pc.yellow("No changes specified."));
|
|
61
|
+
process.exit(EXIT_INVALID_ARGS);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const response = await client.updateIdea(id, request);
|
|
65
|
+
if (args.json) {
|
|
66
|
+
console.log(JSON.stringify(response, null, 2));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const { idea } = response;
|
|
70
|
+
const title = idea.title || formatDate(idea.createdAt);
|
|
71
|
+
console.log(pc.green(`✓ Updated idea ${pc.cyan(`#${idea.id}`)} (${title})`));
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
handleApiError(error);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/commands/idea/update.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/idea.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* zhe idea — Manage ideas (Markdown notes)
|
|
2
|
+
* zhe idea — Manage ideas (Markdown notes).
|
|
3
|
+
*
|
|
4
|
+
* Subcommand implementations live in ./idea/*.ts to keep this file small.
|
|
5
|
+
* `formatTags` is re-exported here for tests that import from
|
|
6
|
+
* `commands/idea.js`.
|
|
3
7
|
*/
|
|
4
|
-
export
|
|
8
|
+
export { formatTags } from "./idea/helpers.js";
|
|
5
9
|
export declare const ideaCommand: import("citty").CommandDef<import("citty").ArgsDef>;
|
|
6
10
|
//# sourceMappingURL=idea.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idea.d.ts","sourceRoot":"","sources":["../../src/commands/idea.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"idea.d.ts","sourceRoot":"","sources":["../../src/commands/idea.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,eAAO,MAAM,WAAW,qDAYtB,CAAC"}
|