ai-project-manage-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.
Files changed (74) hide show
  1. package/README.md +29 -0
  2. package/dist/api/client.d.ts +14 -0
  3. package/dist/api/client.d.ts.map +1 -0
  4. package/dist/api/client.js +32 -0
  5. package/dist/api/client.js.map +1 -0
  6. package/dist/api/http.d.ts +21 -0
  7. package/dist/api/http.d.ts.map +1 -0
  8. package/dist/api/http.js +108 -0
  9. package/dist/api/http.js.map +1 -0
  10. package/dist/api/index.d.ts +6 -0
  11. package/dist/api/index.d.ts.map +1 -0
  12. package/dist/api/index.js +13 -0
  13. package/dist/api/index.js.map +1 -0
  14. package/dist/api/request-config.d.ts +16 -0
  15. package/dist/api/request-config.d.ts.map +1 -0
  16. package/dist/api/request-config.js +40 -0
  17. package/dist/api/request-config.js.map +1 -0
  18. package/dist/api/requirement.d.ts +112 -0
  19. package/dist/api/requirement.d.ts.map +1 -0
  20. package/dist/api/requirement.js +6 -0
  21. package/dist/api/requirement.js.map +1 -0
  22. package/dist/cli/commands/auth.d.ts +3 -0
  23. package/dist/cli/commands/auth.d.ts.map +1 -0
  24. package/dist/cli/commands/auth.js +72 -0
  25. package/dist/cli/commands/auth.js.map +1 -0
  26. package/dist/cli/commands/comment.d.ts +3 -0
  27. package/dist/cli/commands/comment.d.ts.map +1 -0
  28. package/dist/cli/commands/comment.js +57 -0
  29. package/dist/cli/commands/comment.js.map +1 -0
  30. package/dist/cli/commands/config.d.ts +3 -0
  31. package/dist/cli/commands/config.d.ts.map +1 -0
  32. package/dist/cli/commands/config.js +59 -0
  33. package/dist/cli/commands/config.js.map +1 -0
  34. package/dist/cli/commands/requirement.d.ts +3 -0
  35. package/dist/cli/commands/requirement.d.ts.map +1 -0
  36. package/dist/cli/commands/requirement.js +118 -0
  37. package/dist/cli/commands/requirement.js.map +1 -0
  38. package/dist/cli/commands/ws.d.ts +3 -0
  39. package/dist/cli/commands/ws.d.ts.map +1 -0
  40. package/dist/cli/commands/ws.js +67 -0
  41. package/dist/cli/commands/ws.js.map +1 -0
  42. package/dist/cli/credentials.d.ts +25 -0
  43. package/dist/cli/credentials.d.ts.map +1 -0
  44. package/dist/cli/credentials.js +52 -0
  45. package/dist/cli/credentials.js.map +1 -0
  46. package/dist/cli/exit-api-error.d.ts +2 -0
  47. package/dist/cli/exit-api-error.d.ts.map +1 -0
  48. package/dist/cli/exit-api-error.js +12 -0
  49. package/dist/cli/exit-api-error.js.map +1 -0
  50. package/dist/cli/session.d.ts +26 -0
  51. package/dist/cli/session.d.ts.map +1 -0
  52. package/dist/cli/session.js +41 -0
  53. package/dist/cli/session.js.map +1 -0
  54. package/dist/cli/ws-run-command.d.ts +10 -0
  55. package/dist/cli/ws-run-command.d.ts.map +1 -0
  56. package/dist/cli/ws-run-command.js +118 -0
  57. package/dist/cli/ws-run-command.js.map +1 -0
  58. package/dist/cli.d.ts +3 -0
  59. package/dist/cli.d.ts.map +1 -0
  60. package/dist/cli.js +38 -0
  61. package/dist/cli.js.map +1 -0
  62. package/dist/config-store.d.ts +19 -0
  63. package/dist/config-store.d.ts.map +1 -0
  64. package/dist/config-store.js +82 -0
  65. package/dist/config-store.js.map +1 -0
  66. package/dist/employee-ws-client.d.ts +42 -0
  67. package/dist/employee-ws-client.d.ts.map +1 -0
  68. package/dist/employee-ws-client.js +99 -0
  69. package/dist/employee-ws-client.js.map +1 -0
  70. package/dist/index.d.ts +6 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +22 -0
  73. package/dist/index.js.map +1 -0
  74. package/package.json +46 -0
package/dist/cli.js ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const config_store_1 = require("./config-store");
6
+ const auth_1 = require("./cli/commands/auth");
7
+ const comment_1 = require("./cli/commands/comment");
8
+ const config_1 = require("./cli/commands/config");
9
+ const requirement_1 = require("./cli/commands/requirement");
10
+ const ws_1 = require("./cli/commands/ws");
11
+ const credentials_1 = require("./cli/credentials");
12
+ const program = new commander_1.Command()
13
+ .name("apm")
14
+ .description("AI 项目管理后端 CLI")
15
+ .hook("preAction", () => {
16
+ const argv = process.argv.slice(2);
17
+ const first = argv.find((a) => !a.startsWith("-"));
18
+ if (first === "config" || first === "login" || first === "logout") {
19
+ return;
20
+ }
21
+ const cred = (0, credentials_1.resolveEffectiveCredentials)();
22
+ if ("error" in cred) {
23
+ console.error(cred.error);
24
+ console.error(`配置文件:${(0, config_store_1.getApmConfigPath)()}`);
25
+ process.exit(1);
26
+ }
27
+ (0, credentials_1.setActiveCliCredentials)(cred);
28
+ });
29
+ (0, config_1.registerConfigCommands)(program);
30
+ (0, auth_1.registerAuthCommands)(program);
31
+ (0, comment_1.registerCommentCommands)(program);
32
+ (0, requirement_1.registerRequirementCommands)(program);
33
+ (0, ws_1.registerWsCommands)(program);
34
+ program.parseAsync(process.argv).catch((err) => {
35
+ console.error(err);
36
+ process.exit(1);
37
+ });
38
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,iDAAkD;AAClD,8CAA2D;AAC3D,oDAAiE;AACjE,kDAA+D;AAC/D,4DAAyE;AACzE,0CAAuD;AACvD,mDAG2B;AAE3B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE;KAC1B,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,eAAe,CAAC;KAC5B,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;IACtB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QAClE,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,yCAA2B,GAAE,CAAC;IAC3C,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAA,+BAAgB,GAAE,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAA,qCAAuB,EAAC,IAAI,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEL,IAAA,+BAAsB,EAAC,OAAO,CAAC,CAAC;AAChC,IAAA,2BAAoB,EAAC,OAAO,CAAC,CAAC;AAC9B,IAAA,iCAAuB,EAAC,OAAO,CAAC,CAAC;AACjC,IAAA,yCAA2B,EAAC,OAAO,CAAC,CAAC;AACrC,IAAA,uBAAkB,EAAC,OAAO,CAAC,CAAC;AAE5B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ export type ApmConfigFile = {
2
+ baseUrl?: string;
3
+ token?: string;
4
+ employeeId?: number;
5
+ /** 员工 WebSocket 端口;缺省时连接逻辑使用 {@link FALLBACK_EMPLOYEE_WS_PORT} */
6
+ wsPort?: number | string;
7
+ };
8
+ /** 未配置或无效 `wsPort` 时的回退值(与后端 `AppWebSocketGateway` 默认一致) */
9
+ export declare const FALLBACK_EMPLOYEE_WS_PORT = 4000;
10
+ /**
11
+ * 读取配置文件中的 `wsPort`;未设置或非法时返回 {@link FALLBACK_EMPLOYEE_WS_PORT}。
12
+ */
13
+ export declare function resolveEmployeeWsPortFromConfig(): number;
14
+ export declare function getApmConfigPath(): string;
15
+ export declare function normalizeBaseUrl(url: string): string;
16
+ export declare function readApmConfigSync(): ApmConfigFile;
17
+ export declare function readApmConfig(): Promise<ApmConfigFile>;
18
+ export declare function writeApmConfig(cfg: ApmConfigFile): Promise<void>;
19
+ //# sourceMappingURL=config-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,MAAM,CAWxD;AAUD,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,iBAAiB,IAAI,aAAa,CASjD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAQ5D;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAUtE"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FALLBACK_EMPLOYEE_WS_PORT = void 0;
7
+ exports.resolveEmployeeWsPortFromConfig = resolveEmployeeWsPortFromConfig;
8
+ exports.getApmConfigPath = getApmConfigPath;
9
+ exports.normalizeBaseUrl = normalizeBaseUrl;
10
+ exports.readApmConfigSync = readApmConfigSync;
11
+ exports.readApmConfig = readApmConfig;
12
+ exports.writeApmConfig = writeApmConfig;
13
+ const promises_1 = require("node:fs/promises");
14
+ const node_fs_1 = require("node:fs");
15
+ const node_os_1 = __importDefault(require("node:os"));
16
+ const node_path_1 = __importDefault(require("node:path"));
17
+ /** 未配置或无效 `wsPort` 时的回退值(与后端 `AppWebSocketGateway` 默认一致) */
18
+ exports.FALLBACK_EMPLOYEE_WS_PORT = 4000;
19
+ /**
20
+ * 读取配置文件中的 `wsPort`;未设置或非法时返回 {@link FALLBACK_EMPLOYEE_WS_PORT}。
21
+ */
22
+ function resolveEmployeeWsPortFromConfig() {
23
+ const cfg = readApmConfigSync();
24
+ const raw = cfg.wsPort;
25
+ if (typeof raw === "number" && Number.isInteger(raw) && raw >= 1 && raw <= 65535) {
26
+ return raw;
27
+ }
28
+ if (typeof raw === "string") {
29
+ const n = Number.parseInt(raw.trim(), 10);
30
+ if (Number.isFinite(n) && n >= 1 && n <= 65535)
31
+ return n;
32
+ }
33
+ return exports.FALLBACK_EMPLOYEE_WS_PORT;
34
+ }
35
+ function configDir() {
36
+ const xdg = process.env.XDG_CONFIG_HOME?.trim();
37
+ const base = xdg
38
+ ? node_path_1.default.resolve(xdg)
39
+ : node_path_1.default.join(node_os_1.default.homedir(), ".config");
40
+ return node_path_1.default.join(base, "apm");
41
+ }
42
+ function getApmConfigPath() {
43
+ return node_path_1.default.join(configDir(), "config.json");
44
+ }
45
+ function normalizeBaseUrl(url) {
46
+ return url.trim().replace(/\/+$/, "");
47
+ }
48
+ function readApmConfigSync() {
49
+ try {
50
+ const p = getApmConfigPath();
51
+ if (!(0, node_fs_1.existsSync)(p))
52
+ return {};
53
+ const j = JSON.parse((0, node_fs_1.readFileSync)(p, "utf8"));
54
+ return j && typeof j === "object" ? j : {};
55
+ }
56
+ catch {
57
+ return {};
58
+ }
59
+ }
60
+ async function readApmConfig() {
61
+ try {
62
+ const raw = await (0, promises_1.readFile)(getApmConfigPath(), "utf8");
63
+ const j = JSON.parse(raw);
64
+ return j && typeof j === "object" ? j : {};
65
+ }
66
+ catch {
67
+ return {};
68
+ }
69
+ }
70
+ async function writeApmConfig(cfg) {
71
+ const dir = configDir();
72
+ await (0, promises_1.mkdir)(dir, { recursive: true, mode: 0o700 });
73
+ const p = getApmConfigPath();
74
+ await (0, promises_1.writeFile)(p, `${JSON.stringify(cfg, null, 2)}\n`, { mode: 0o600 });
75
+ try {
76
+ await (0, promises_1.chmod)(p, 0o600);
77
+ }
78
+ catch {
79
+ /* ignore */
80
+ }
81
+ }
82
+ //# sourceMappingURL=config-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store.js","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * 员工 CLI WebSocket:与后端 `AppWebSocketGateway` 一致,
3
+ * 使用 URL 查询参数 `token`(`Employee.cliToken`),路径 `/ws`;
4
+ * 端口优先 `apm config set ws-port`,否则回退 {@link FALLBACK_EMPLOYEE_WS_PORT}。
5
+ */
6
+ import WebSocket from "ws";
7
+ import { FALLBACK_EMPLOYEE_WS_PORT, resolveEmployeeWsPortFromConfig } from "./config-store";
8
+ export { FALLBACK_EMPLOYEE_WS_PORT, resolveEmployeeWsPortFromConfig };
9
+ /** 与 `EmployeeWebsocketPushService.pushToEmployee` 发送格式一致 */
10
+ export type EmployeeWsServerMessage = {
11
+ event: string;
12
+ data: unknown;
13
+ };
14
+ export type BuildEmployeeWebSocketUrlOptions = {
15
+ /** 显式端口;不传则 {@link resolveEmployeeWsPortFromConfig}(配置 → 回退 4000) */
16
+ port?: number;
17
+ };
18
+ /**
19
+ * 由 `baseUrl` 解析主机名(与 HTTP 同源),使用独立 WS 端口构造 `ws(s)://host:port/ws?token=...`。
20
+ */
21
+ export declare function buildEmployeeWebSocketUrl(baseUrl: string, token: string, options?: BuildEmployeeWebSocketUrlOptions): string;
22
+ export type CreateEmployeeWebSocketOptions = {
23
+ baseUrl: string;
24
+ token: string;
25
+ wsPort?: number;
26
+ /** 服务端推送的 JSON:`{ event, data }`;解析失败时 `parsed` 为 `null` */
27
+ onMessage?: (raw: string, parsed: EmployeeWsServerMessage | null) => void;
28
+ onOpen?: () => void;
29
+ onClose?: (code: number, reason: Buffer) => void;
30
+ onError?: (err: Error) => void;
31
+ };
32
+ /**
33
+ * 使用员工 token 建立 WebSocket,连接成功后可在 `onMessage` 中接收服务端推送。
34
+ */
35
+ export declare function createEmployeeWebSocket(options: CreateEmployeeWebSocketOptions): WebSocket;
36
+ /**
37
+ * 连接并等待服务端消息,直到连接关闭或 `signal` 中止。
38
+ */
39
+ export declare function connectEmployeeWebSocketAndWait(options: CreateEmployeeWebSocketOptions & {
40
+ signal?: AbortSignal;
41
+ }): Promise<WebSocket>;
42
+ //# sourceMappingURL=employee-ws-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-ws-client.d.ts","sourceRoot":"","sources":["../src/employee-ws-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EACL,yBAAyB,EAEzB,+BAA+B,EAChC,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,yBAAyB,EAAE,+BAA+B,EAAE,CAAC;AAEtE,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,gCAAgC,GACzC,MAAM,CAaR;AAED,MAAM,MAAM,8BAA8B,GAAG;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAChC,CAAC;AAEF;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,8BAA8B,GACtC,SAAS,CA2BX;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,8BAA8B,GAAG;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GACA,OAAO,CAAC,SAAS,CAAC,CA8BpB"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveEmployeeWsPortFromConfig = exports.FALLBACK_EMPLOYEE_WS_PORT = void 0;
7
+ exports.buildEmployeeWebSocketUrl = buildEmployeeWebSocketUrl;
8
+ exports.createEmployeeWebSocket = createEmployeeWebSocket;
9
+ exports.connectEmployeeWebSocketAndWait = connectEmployeeWebSocketAndWait;
10
+ /**
11
+ * 员工 CLI WebSocket:与后端 `AppWebSocketGateway` 一致,
12
+ * 使用 URL 查询参数 `token`(`Employee.cliToken`),路径 `/ws`;
13
+ * 端口优先 `apm config set ws-port`,否则回退 {@link FALLBACK_EMPLOYEE_WS_PORT}。
14
+ */
15
+ const ws_1 = __importDefault(require("ws"));
16
+ const config_store_1 = require("./config-store");
17
+ Object.defineProperty(exports, "FALLBACK_EMPLOYEE_WS_PORT", { enumerable: true, get: function () { return config_store_1.FALLBACK_EMPLOYEE_WS_PORT; } });
18
+ Object.defineProperty(exports, "resolveEmployeeWsPortFromConfig", { enumerable: true, get: function () { return config_store_1.resolveEmployeeWsPortFromConfig; } });
19
+ /**
20
+ * 由 `baseUrl` 解析主机名(与 HTTP 同源),使用独立 WS 端口构造 `ws(s)://host:port/ws?token=...`。
21
+ */
22
+ function buildEmployeeWebSocketUrl(baseUrl, token, options) {
23
+ const u = new URL((0, config_store_1.normalizeBaseUrl)(baseUrl));
24
+ const explicit = options?.port;
25
+ const port = explicit != null &&
26
+ Number.isFinite(explicit) &&
27
+ explicit >= 1 &&
28
+ explicit <= 65535
29
+ ? Math.floor(explicit)
30
+ : (0, config_store_1.resolveEmployeeWsPortFromConfig)();
31
+ const wsProto = u.protocol === "https:" ? "wss:" : "ws:";
32
+ const params = new URLSearchParams({ token: token.trim() });
33
+ return `${wsProto}//${u.hostname}:${port}/ws?${params.toString()}`;
34
+ }
35
+ /**
36
+ * 使用员工 token 建立 WebSocket,连接成功后可在 `onMessage` 中接收服务端推送。
37
+ */
38
+ function createEmployeeWebSocket(options) {
39
+ const url = buildEmployeeWebSocketUrl(options.baseUrl, options.token, {
40
+ port: options.wsPort,
41
+ });
42
+ const ws = new ws_1.default(url);
43
+ ws.on("open", () => options.onOpen?.());
44
+ ws.on("close", (code, reason) => options.onClose?.(code, reason));
45
+ ws.on("error", (err) => options.onError?.(err));
46
+ ws.on("message", (data) => {
47
+ const raw = Buffer.isBuffer(data) ? data.toString("utf8") : String(data);
48
+ let parsed = null;
49
+ try {
50
+ const j = JSON.parse(raw);
51
+ if (j &&
52
+ typeof j === "object" &&
53
+ "event" in j &&
54
+ typeof j.event === "string") {
55
+ parsed = j;
56
+ }
57
+ }
58
+ catch {
59
+ /* 非 JSON 时 parsed 保持 null */
60
+ }
61
+ options.onMessage?.(raw, parsed);
62
+ });
63
+ return ws;
64
+ }
65
+ /**
66
+ * 连接并等待服务端消息,直到连接关闭或 `signal` 中止。
67
+ */
68
+ function connectEmployeeWebSocketAndWait(options) {
69
+ return new Promise((resolve, reject) => {
70
+ const ws = createEmployeeWebSocket({
71
+ ...options,
72
+ onOpen: () => {
73
+ options.onOpen?.();
74
+ resolve(ws);
75
+ },
76
+ onError: (err) => {
77
+ options.onError?.(err);
78
+ reject(err);
79
+ },
80
+ });
81
+ const onAbort = () => {
82
+ try {
83
+ ws.close();
84
+ }
85
+ catch {
86
+ /* ignore */
87
+ }
88
+ };
89
+ if (options.signal) {
90
+ if (options.signal.aborted) {
91
+ onAbort();
92
+ reject(new Error("aborted"));
93
+ return;
94
+ }
95
+ options.signal.addEventListener("abort", onAbort, { once: true });
96
+ }
97
+ });
98
+ }
99
+ //# sourceMappingURL=employee-ws-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-ws-client.js","sourceRoot":"","sources":["../src/employee-ws-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * ai-project-manage 后端 SDK(目录结构对齐 apps/fe/src/api)。
3
+ */
4
+ export * from "./api/index";
5
+ export * from "./employee-ws-client";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * ai-project-manage 后端 SDK(目录结构对齐 apps/fe/src/api)。
19
+ */
20
+ __exportStar(require("./api/index"), exports);
21
+ __exportStar(require("./employee-ws-client"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,8CAA4B;AAC5B,uDAAqC"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "ai-project-manage-cli",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "description": "CLI / SDK for AI项目管理",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "apm": "dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "apm": "node ./dist/cli.js",
24
+ "apm:help": "node ./dist/cli.js --help",
25
+ "apm:logout": "node ./dist/cli.js logout",
26
+ "apm:login": "node ./dist/cli.js login",
27
+ "apm:config:get-base-url": "node ./dist/cli.js config get base-url",
28
+ "apm:comment:help": "node ./dist/cli.js comment --help",
29
+ "apm:comment:update": "node ./dist/cli.js comment update",
30
+ "apm:comment:process": "node ./dist/cli.js comment process",
31
+ "apm:requirement:help": "node ./dist/cli.js requirement --help",
32
+ "apm:requirement:test-case:import": "node ./dist/cli.js requirement test-case import",
33
+ "apm:requirement:branch:set-status": "node ./dist/cli.js requirement branch set-status",
34
+ "apm:requirement:defect:set-status": "node ./dist/cli.js requirement defect set-status"
35
+ },
36
+ "dependencies": {
37
+ "commander": "^13.1.0",
38
+ "listpage-http": "0.0.315",
39
+ "ws": "~8.20.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^22.10.7",
43
+ "typescript": "~5.7.3",
44
+ "@types/ws": "~8.18.1"
45
+ }
46
+ }