@prd-improve/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 (209) hide show
  1. package/README.md +38 -0
  2. package/dist/anchor-slicer.d.ts +18 -0
  3. package/dist/anchor-slicer.js +114 -0
  4. package/dist/anchor-slicer.js.map +1 -0
  5. package/dist/api/client.d.ts +68 -0
  6. package/dist/api/client.js +175 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/changelog.d.ts +9 -0
  9. package/dist/changelog.js +34 -0
  10. package/dist/changelog.js.map +1 -0
  11. package/dist/cli.d.ts +2 -0
  12. package/dist/cli.js +258 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/commands/admin/_adminJson.d.ts +18 -0
  15. package/dist/commands/admin/_adminJson.js +27 -0
  16. package/dist/commands/admin/_adminJson.js.map +1 -0
  17. package/dist/commands/admin/_authResolve.d.ts +8 -0
  18. package/dist/commands/admin/_authResolve.js +56 -0
  19. package/dist/commands/admin/_authResolve.js.map +1 -0
  20. package/dist/commands/admin/index.d.ts +22 -0
  21. package/dist/commands/admin/index.js +100 -0
  22. package/dist/commands/admin/index.js.map +1 -0
  23. package/dist/commands/admin/io.d.ts +15 -0
  24. package/dist/commands/admin/io.js +30 -0
  25. package/dist/commands/admin/io.js.map +1 -0
  26. package/dist/commands/admin/member.d.ts +43 -0
  27. package/dist/commands/admin/member.js +362 -0
  28. package/dist/commands/admin/member.js.map +1 -0
  29. package/dist/commands/admin/project.d.ts +40 -0
  30. package/dist/commands/admin/project.js +182 -0
  31. package/dist/commands/admin/project.js.map +1 -0
  32. package/dist/commands/admin/team.d.ts +31 -0
  33. package/dist/commands/admin/team.js +157 -0
  34. package/dist/commands/admin/team.js.map +1 -0
  35. package/dist/commands/admin/teamMember.d.ts +33 -0
  36. package/dist/commands/admin/teamMember.js +262 -0
  37. package/dist/commands/admin/teamMember.js.map +1 -0
  38. package/dist/commands/admin/token.d.ts +29 -0
  39. package/dist/commands/admin/token.js +125 -0
  40. package/dist/commands/admin/token.js.map +1 -0
  41. package/dist/commands/admin/user.d.ts +2 -0
  42. package/dist/commands/admin/user.js +85 -0
  43. package/dist/commands/admin/user.js.map +1 -0
  44. package/dist/commands/config.d.ts +9 -0
  45. package/dist/commands/config.js +178 -0
  46. package/dist/commands/config.js.map +1 -0
  47. package/dist/commands/context.d.ts +11 -0
  48. package/dist/commands/context.js +235 -0
  49. package/dist/commands/context.js.map +1 -0
  50. package/dist/commands/diff.d.ts +6 -0
  51. package/dist/commands/diff.js +208 -0
  52. package/dist/commands/diff.js.map +1 -0
  53. package/dist/commands/freeze.d.ts +10 -0
  54. package/dist/commands/freeze.js +269 -0
  55. package/dist/commands/freeze.js.map +1 -0
  56. package/dist/commands/init.d.ts +24 -0
  57. package/dist/commands/init.js +229 -0
  58. package/dist/commands/init.js.map +1 -0
  59. package/dist/commands/login.d.ts +26 -0
  60. package/dist/commands/login.js +241 -0
  61. package/dist/commands/login.js.map +1 -0
  62. package/dist/commands/logout.d.ts +6 -0
  63. package/dist/commands/logout.js +75 -0
  64. package/dist/commands/logout.js.map +1 -0
  65. package/dist/commands/migrate-yaml.d.ts +17 -0
  66. package/dist/commands/migrate-yaml.js +288 -0
  67. package/dist/commands/migrate-yaml.js.map +1 -0
  68. package/dist/commands/project.d.ts +7 -0
  69. package/dist/commands/project.js +87 -0
  70. package/dist/commands/project.js.map +1 -0
  71. package/dist/commands/pull.d.ts +16 -0
  72. package/dist/commands/pull.js +197 -0
  73. package/dist/commands/pull.js.map +1 -0
  74. package/dist/commands/push.d.ts +9 -0
  75. package/dist/commands/push.js +392 -0
  76. package/dist/commands/push.js.map +1 -0
  77. package/dist/commands/refresh.d.ts +9 -0
  78. package/dist/commands/refresh.js +123 -0
  79. package/dist/commands/refresh.js.map +1 -0
  80. package/dist/commands/status.d.ts +7 -0
  81. package/dist/commands/status.js +190 -0
  82. package/dist/commands/status.js.map +1 -0
  83. package/dist/commands/team.d.ts +6 -0
  84. package/dist/commands/team.js +84 -0
  85. package/dist/commands/team.js.map +1 -0
  86. package/dist/commands/validate.d.ts +5 -0
  87. package/dist/commands/validate.js +129 -0
  88. package/dist/commands/validate.js.map +1 -0
  89. package/dist/commands/whoami.d.ts +6 -0
  90. package/dist/commands/whoami.js +81 -0
  91. package/dist/commands/whoami.js.map +1 -0
  92. package/dist/config/adminBackend.d.ts +43 -0
  93. package/dist/config/adminBackend.js +33 -0
  94. package/dist/config/adminBackend.js.map +1 -0
  95. package/dist/config/rc.d.ts +70 -0
  96. package/dist/config/rc.js +148 -0
  97. package/dist/config/rc.js.map +1 -0
  98. package/dist/config/schema.d.ts +132 -0
  99. package/dist/config/schema.js +36 -0
  100. package/dist/config/schema.js.map +1 -0
  101. package/dist/diff/engine.d.ts +35 -0
  102. package/dist/diff/engine.js +305 -0
  103. package/dist/diff/engine.js.map +1 -0
  104. package/dist/diff/render.d.ts +18 -0
  105. package/dist/diff/render.js +129 -0
  106. package/dist/diff/render.js.map +1 -0
  107. package/dist/formatter/colors.d.ts +17 -0
  108. package/dist/formatter/colors.js +35 -0
  109. package/dist/formatter/colors.js.map +1 -0
  110. package/dist/formatter/human.d.ts +7 -0
  111. package/dist/formatter/human.js +70 -0
  112. package/dist/formatter/human.js.map +1 -0
  113. package/dist/fs/atomicWrite.d.ts +7 -0
  114. package/dist/fs/atomicWrite.js +37 -0
  115. package/dist/fs/atomicWrite.js.map +1 -0
  116. package/dist/i18n/dispatch.d.ts +19 -0
  117. package/dist/i18n/dispatch.js +27 -0
  118. package/dist/i18n/dispatch.js.map +1 -0
  119. package/dist/i18n/en.d.ts +3 -0
  120. package/dist/i18n/en.js +275 -0
  121. package/dist/i18n/en.js.map +1 -0
  122. package/dist/i18n/help.d.ts +3 -0
  123. package/dist/i18n/help.en.d.ts +149 -0
  124. package/dist/i18n/help.en.js +150 -0
  125. package/dist/i18n/help.en.js.map +1 -0
  126. package/dist/i18n/help.js +7 -0
  127. package/dist/i18n/help.js.map +1 -0
  128. package/dist/i18n/help.zh.d.ts +149 -0
  129. package/dist/i18n/help.zh.js +150 -0
  130. package/dist/i18n/help.zh.js.map +1 -0
  131. package/dist/i18n/helpFormat.d.ts +7 -0
  132. package/dist/i18n/helpFormat.js +51 -0
  133. package/dist/i18n/helpFormat.js.map +1 -0
  134. package/dist/i18n/helpGroups.d.ts +3 -0
  135. package/dist/i18n/helpGroups.js +11 -0
  136. package/dist/i18n/helpGroups.js.map +1 -0
  137. package/dist/i18n/index.d.ts +16 -0
  138. package/dist/i18n/index.js +46 -0
  139. package/dist/i18n/index.js.map +1 -0
  140. package/dist/i18n/peekLang.d.ts +1 -0
  141. package/dist/i18n/peekLang.js +16 -0
  142. package/dist/i18n/peekLang.js.map +1 -0
  143. package/dist/i18n/zh.d.ts +680 -0
  144. package/dist/i18n/zh.js +288 -0
  145. package/dist/i18n/zh.js.map +1 -0
  146. package/dist/parser/discover.d.ts +2 -0
  147. package/dist/parser/discover.js +69 -0
  148. package/dist/parser/discover.js.map +1 -0
  149. package/dist/parser/load-yaml.d.ts +11 -0
  150. package/dist/parser/load-yaml.js +25 -0
  151. package/dist/parser/load-yaml.js.map +1 -0
  152. package/dist/pkgVersion.d.ts +9 -0
  153. package/dist/pkgVersion.js +22 -0
  154. package/dist/pkgVersion.js.map +1 -0
  155. package/dist/renderer/context-md.d.ts +27 -0
  156. package/dist/renderer/context-md.js +444 -0
  157. package/dist/renderer/context-md.js.map +1 -0
  158. package/dist/renderer/refresh-md.d.ts +18 -0
  159. package/dist/renderer/refresh-md.js +93 -0
  160. package/dist/renderer/refresh-md.js.map +1 -0
  161. package/dist/schema/index.d.ts +2 -0
  162. package/dist/schema/index.js +3 -0
  163. package/dist/schema/index.js.map +1 -0
  164. package/dist/schema/modules.d.ts +461 -0
  165. package/dist/schema/modules.js +184 -0
  166. package/dist/schema/modules.js.map +1 -0
  167. package/dist/schema/prd.d.ts +1018 -0
  168. package/dist/schema/prd.js +65 -0
  169. package/dist/schema/prd.js.map +1 -0
  170. package/dist/sync/cliRcHelpers.d.ts +25 -0
  171. package/dist/sync/cliRcHelpers.js +62 -0
  172. package/dist/sync/cliRcHelpers.js.map +1 -0
  173. package/dist/sync/conflicts.d.ts +7 -0
  174. package/dist/sync/conflicts.js +72 -0
  175. package/dist/sync/conflicts.js.map +1 -0
  176. package/dist/sync/headProbe.d.ts +1 -0
  177. package/dist/sync/headProbe.js +95 -0
  178. package/dist/sync/headProbe.js.map +1 -0
  179. package/dist/sync/normalize.d.ts +10 -0
  180. package/dist/sync/normalize.js +13 -0
  181. package/dist/sync/normalize.js.map +1 -0
  182. package/dist/sync/syncJson.d.ts +18 -0
  183. package/dist/sync/syncJson.js +42 -0
  184. package/dist/sync/syncJson.js.map +1 -0
  185. package/dist/types.d.ts +70 -0
  186. package/dist/types.js +21 -0
  187. package/dist/types.js.map +1 -0
  188. package/dist/validators/blocking.d.ts +2 -0
  189. package/dist/validators/blocking.js +25 -0
  190. package/dist/validators/blocking.js.map +1 -0
  191. package/dist/validators/duplicate-ids.d.ts +2 -0
  192. package/dist/validators/duplicate-ids.js +58 -0
  193. package/dist/validators/duplicate-ids.js.map +1 -0
  194. package/dist/validators/references.d.ts +5 -0
  195. package/dist/validators/references.js +165 -0
  196. package/dist/validators/references.js.map +1 -0
  197. package/dist/validators/required-modules.d.ts +8 -0
  198. package/dist/validators/required-modules.js +59 -0
  199. package/dist/validators/required-modules.js.map +1 -0
  200. package/dist/validators/runner.d.ts +11 -0
  201. package/dist/validators/runner.js +73 -0
  202. package/dist/validators/runner.js.map +1 -0
  203. package/dist/workspace.d.ts +32 -0
  204. package/dist/workspace.js +37 -0
  205. package/dist/workspace.js.map +1 -0
  206. package/dist/yaml-indexer.d.ts +15 -0
  207. package/dist/yaml-indexer.js +112 -0
  208. package/dist/yaml-indexer.js.map +1 -0
  209. package/package.json +50 -0
@@ -0,0 +1,70 @@
1
+ import { type PrdRc, type ResolvedBackend } from "./schema.js";
2
+ export declare const RC_PATH: string;
3
+ export type LoadRcResult = {
4
+ ok: true;
5
+ rc: PrdRc;
6
+ path: string;
7
+ } | {
8
+ ok: false;
9
+ reason: "missing";
10
+ } | {
11
+ ok: false;
12
+ reason: "permissions";
13
+ mode: string;
14
+ } | {
15
+ ok: false;
16
+ reason: "parse";
17
+ message: string;
18
+ } | {
19
+ ok: false;
20
+ reason: "schema";
21
+ message: string;
22
+ };
23
+ /**
24
+ * Load ~/.prdrc — returns typed result rather than throwing.
25
+ * `pathOverride` exists for tests (HOME juggling is fragile in vitest workers).
26
+ */
27
+ export declare function loadRc(pathOverride?: string): LoadRcResult;
28
+ export declare function saveRc(rc: PrdRc, pathOverride?: string): {
29
+ ok: true;
30
+ path: string;
31
+ } | {
32
+ ok: false;
33
+ message: string;
34
+ };
35
+ /**
36
+ * Override precedence (design §6.9):
37
+ * 1. opts.backend (CLI --backend <name>) — selects from rc
38
+ * 2. PRDSERVER_URL + PRDSERVER_TOKEN env (both set) → ad-hoc backend
39
+ * 3. PRDSERVER_BACKEND env → selects from rc
40
+ * 4. rc.default_backend
41
+ *
42
+ * `PRDSERVER_URL` alone (no token) is an explicit error — callers must
43
+ * surface "rc_env_url_without_token".
44
+ */
45
+ export type ResolveBackendResult = {
46
+ ok: true;
47
+ backend: ResolvedBackend;
48
+ } | {
49
+ ok: false;
50
+ reason: "no_backend";
51
+ } | {
52
+ ok: false;
53
+ reason: "unknown_name";
54
+ name: string;
55
+ } | {
56
+ ok: false;
57
+ reason: "no_token";
58
+ name: string;
59
+ } | {
60
+ ok: false;
61
+ reason: "env_url_without_token";
62
+ };
63
+ export declare function resolveBackend(rc: PrdRc | null, opts?: {
64
+ backend?: string;
65
+ }, env?: NodeJS.ProcessEnv): ResolveBackendResult;
66
+ /**
67
+ * Token masking for `prd config show` / `prd whoami` output.
68
+ * Format: prd_pat_<first4>****<last2> (design §6.7 / §6.8 example).
69
+ */
70
+ export declare function maskToken(token: string): string;
@@ -0,0 +1,148 @@
1
+ /**
2
+ * ~/.prdrc load / save / backend resolution (T6).
3
+ *
4
+ * Hardening choices:
5
+ * - chmod 600 on save (idempotent, defensive — never widens permissions).
6
+ * - Refuse to load if file mode is wider than 600 — return {ok:false,reason}
7
+ * so callers can warn the user (consistent with design §6.9 security goal).
8
+ * - All errors return typed Result instead of throwing — driver code wants
9
+ * to render its own i18n message, not catch raw zod issues.
10
+ */
11
+ import { existsSync, readFileSync, statSync } from "node:fs";
12
+ import { homedir } from "node:os";
13
+ import { join } from "node:path";
14
+ import { load as yamlLoad, dump as yamlDump } from "js-yaml";
15
+ import { PrdRcSchema, } from "./schema.js";
16
+ import { writeFileAtomic } from "../fs/atomicWrite.js";
17
+ export const RC_PATH = join(homedir(), ".prdrc");
18
+ /**
19
+ * Load ~/.prdrc — returns typed result rather than throwing.
20
+ * `pathOverride` exists for tests (HOME juggling is fragile in vitest workers).
21
+ */
22
+ export function loadRc(pathOverride) {
23
+ const path = pathOverride ?? RC_PATH;
24
+ if (!existsSync(path))
25
+ return { ok: false, reason: "missing" };
26
+ // Permission check — POSIX only; on Windows mode bits are mostly noise so
27
+ // we skip the check there. Aligns with the "best-effort" Unix-only policy
28
+ // in the design doc.
29
+ if (process.platform !== "win32") {
30
+ try {
31
+ const st = statSync(path);
32
+ const mode = st.mode & 0o777;
33
+ if (mode & 0o077) {
34
+ return {
35
+ ok: false,
36
+ reason: "permissions",
37
+ mode: mode.toString(8).padStart(3, "0"),
38
+ };
39
+ }
40
+ }
41
+ catch {
42
+ // stat failed → fall through to readFileSync which will surface the real
43
+ // error; don't hide it behind a fake "permissions" reason.
44
+ }
45
+ }
46
+ let text;
47
+ try {
48
+ text = readFileSync(path, "utf8");
49
+ }
50
+ catch (e) {
51
+ return { ok: false, reason: "parse", message: e.message };
52
+ }
53
+ let raw;
54
+ try {
55
+ raw = yamlLoad(text);
56
+ }
57
+ catch (e) {
58
+ return { ok: false, reason: "parse", message: e.message };
59
+ }
60
+ const parsed = PrdRcSchema.safeParse(raw ?? {});
61
+ if (!parsed.success) {
62
+ return {
63
+ ok: false,
64
+ reason: "schema",
65
+ message: parsed.error.issues
66
+ .map((i) => `${i.path.join(".")}: ${i.message}`)
67
+ .join("; "),
68
+ };
69
+ }
70
+ return { ok: true, rc: parsed.data, path };
71
+ }
72
+ export function saveRc(rc, pathOverride) {
73
+ const path = pathOverride ?? RC_PATH;
74
+ try {
75
+ const text = yamlDump(rc, { lineWidth: 0, noRefs: true });
76
+ // T6-MN1 (v1.7) — atomic tempfile + rename so a crash mid-write leaves
77
+ // the previous rc intact rather than producing a truncated rc that bricks
78
+ // `prd push/pull/whoami`. writeFileAtomic chmod's the tempfile to 0o600
79
+ // before rename — POSIX rename(2) unlinks the target and gives the tempfile
80
+ // its name, so the resulting inode carries the tempfile's mode. No extra
81
+ // chmod needed here (I2 reviewer fix — previous defensive chmod was based
82
+ // on a wrong inode-reuse model).
83
+ writeFileAtomic(path, text, { mode: 0o600 });
84
+ return { ok: true, path };
85
+ }
86
+ catch (e) {
87
+ return { ok: false, message: e.message };
88
+ }
89
+ }
90
+ export function resolveBackend(rc, opts = {}, env = process.env) {
91
+ // Step 1: --backend flag → select from rc
92
+ if (opts.backend) {
93
+ if (!rc)
94
+ return { ok: false, reason: "no_backend" };
95
+ const entry = rc.backends[opts.backend];
96
+ if (!entry)
97
+ return { ok: false, reason: "unknown_name", name: opts.backend };
98
+ if (!entry.token)
99
+ return { ok: false, reason: "no_token", name: opts.backend };
100
+ return { ok: true, backend: { name: opts.backend, url: entry.url, token: entry.token } };
101
+ }
102
+ // Step 2: PRDSERVER_URL + PRDSERVER_TOKEN env (both) → ad-hoc backend
103
+ const envUrl = env.PRDSERVER_URL;
104
+ const envTok = env.PRDSERVER_TOKEN;
105
+ if (envUrl && envTok) {
106
+ return { ok: true, backend: { name: "(env)", url: envUrl, token: envTok } };
107
+ }
108
+ if (envUrl && !envTok) {
109
+ return { ok: false, reason: "env_url_without_token" };
110
+ }
111
+ // Step 3: PRDSERVER_BACKEND env → select from rc
112
+ const envName = env.PRDSERVER_BACKEND;
113
+ if (envName) {
114
+ if (!rc)
115
+ return { ok: false, reason: "no_backend" };
116
+ const entry = rc.backends[envName];
117
+ if (!entry)
118
+ return { ok: false, reason: "unknown_name", name: envName };
119
+ if (!entry.token)
120
+ return { ok: false, reason: "no_token", name: envName };
121
+ return { ok: true, backend: { name: envName, url: entry.url, token: entry.token } };
122
+ }
123
+ // Step 4: rc.default_backend
124
+ if (!rc || !rc.default_backend)
125
+ return { ok: false, reason: "no_backend" };
126
+ const entry = rc.backends[rc.default_backend];
127
+ if (!entry)
128
+ return { ok: false, reason: "unknown_name", name: rc.default_backend };
129
+ if (!entry.token)
130
+ return { ok: false, reason: "no_token", name: rc.default_backend };
131
+ return { ok: true, backend: { name: rc.default_backend, url: entry.url, token: entry.token } };
132
+ }
133
+ /**
134
+ * Token masking for `prd config show` / `prd whoami` output.
135
+ * Format: prd_pat_<first4>****<last2> (design §6.7 / §6.8 example).
136
+ */
137
+ export function maskToken(token) {
138
+ // Token shape from server: 'prd_pat_' + 32 base64url chars.
139
+ if (token.length <= 12)
140
+ return "****";
141
+ if (token.startsWith("prd_pat_")) {
142
+ const body = token.slice(8);
143
+ return `prd_pat_${body.slice(0, 4)}****${body.slice(-2)}`;
144
+ }
145
+ // Foreign token shape — still mask the middle.
146
+ return `${token.slice(0, 4)}****${token.slice(-2)}`;
147
+ }
148
+ //# sourceMappingURL=rc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc.js","sourceRoot":"","sources":["../../src/config/rc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Zod schema for ~/.prdrc.yaml (T6).
3
+ *
4
+ * Shape locked by design doc §6.9. Keep optional fields *truly* optional —
5
+ * users may have a half-bootstrapped rc (just user.name) before any login.
6
+ */
7
+ import { z } from "zod";
8
+ export declare const BackendEntrySchema: z.ZodObject<{
9
+ url: z.ZodString;
10
+ token: z.ZodOptional<z.ZodString>;
11
+ last_login_at: z.ZodOptional<z.ZodString>;
12
+ default_team: z.ZodOptional<z.ZodString>;
13
+ default_project: z.ZodOptional<z.ZodString>;
14
+ }, "strip", z.ZodTypeAny, {
15
+ url: string;
16
+ token?: string | undefined;
17
+ last_login_at?: string | undefined;
18
+ default_team?: string | undefined;
19
+ default_project?: string | undefined;
20
+ }, {
21
+ url: string;
22
+ token?: string | undefined;
23
+ last_login_at?: string | undefined;
24
+ default_team?: string | undefined;
25
+ default_project?: string | undefined;
26
+ }>;
27
+ export declare const PrdRcSchema: z.ZodObject<{
28
+ user: z.ZodOptional<z.ZodObject<{
29
+ name: z.ZodOptional<z.ZodString>;
30
+ email: z.ZodOptional<z.ZodString>;
31
+ }, "strip", z.ZodTypeAny, {
32
+ name?: string | undefined;
33
+ email?: string | undefined;
34
+ }, {
35
+ name?: string | undefined;
36
+ email?: string | undefined;
37
+ }>>;
38
+ default_backend: z.ZodOptional<z.ZodString>;
39
+ backends: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
40
+ url: z.ZodString;
41
+ token: z.ZodOptional<z.ZodString>;
42
+ last_login_at: z.ZodOptional<z.ZodString>;
43
+ default_team: z.ZodOptional<z.ZodString>;
44
+ default_project: z.ZodOptional<z.ZodString>;
45
+ }, "strip", z.ZodTypeAny, {
46
+ url: string;
47
+ token?: string | undefined;
48
+ last_login_at?: string | undefined;
49
+ default_team?: string | undefined;
50
+ default_project?: string | undefined;
51
+ }, {
52
+ url: string;
53
+ token?: string | undefined;
54
+ last_login_at?: string | undefined;
55
+ default_team?: string | undefined;
56
+ default_project?: string | undefined;
57
+ }>>>;
58
+ admin_backends: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
59
+ url: z.ZodString;
60
+ token: z.ZodOptional<z.ZodString>;
61
+ last_login_at: z.ZodOptional<z.ZodString>;
62
+ default_team: z.ZodOptional<z.ZodString>;
63
+ default_project: z.ZodOptional<z.ZodString>;
64
+ }, "strip", z.ZodTypeAny, {
65
+ url: string;
66
+ token?: string | undefined;
67
+ last_login_at?: string | undefined;
68
+ default_team?: string | undefined;
69
+ default_project?: string | undefined;
70
+ }, {
71
+ url: string;
72
+ token?: string | undefined;
73
+ last_login_at?: string | undefined;
74
+ default_team?: string | undefined;
75
+ default_project?: string | undefined;
76
+ }>>>;
77
+ lang: z.ZodOptional<z.ZodString>;
78
+ }, "strip", z.ZodTypeAny, {
79
+ backends: Record<string, {
80
+ url: string;
81
+ token?: string | undefined;
82
+ last_login_at?: string | undefined;
83
+ default_team?: string | undefined;
84
+ default_project?: string | undefined;
85
+ }>;
86
+ admin_backends: Record<string, {
87
+ url: string;
88
+ token?: string | undefined;
89
+ last_login_at?: string | undefined;
90
+ default_team?: string | undefined;
91
+ default_project?: string | undefined;
92
+ }>;
93
+ user?: {
94
+ name?: string | undefined;
95
+ email?: string | undefined;
96
+ } | undefined;
97
+ default_backend?: string | undefined;
98
+ lang?: string | undefined;
99
+ }, {
100
+ user?: {
101
+ name?: string | undefined;
102
+ email?: string | undefined;
103
+ } | undefined;
104
+ default_backend?: string | undefined;
105
+ backends?: Record<string, {
106
+ url: string;
107
+ token?: string | undefined;
108
+ last_login_at?: string | undefined;
109
+ default_team?: string | undefined;
110
+ default_project?: string | undefined;
111
+ }> | undefined;
112
+ admin_backends?: Record<string, {
113
+ url: string;
114
+ token?: string | undefined;
115
+ last_login_at?: string | undefined;
116
+ default_team?: string | undefined;
117
+ default_project?: string | undefined;
118
+ }> | undefined;
119
+ lang?: string | undefined;
120
+ }>;
121
+ export type BackendEntry = z.infer<typeof BackendEntrySchema>;
122
+ export type PrdRc = z.infer<typeof PrdRcSchema>;
123
+ /**
124
+ * Backend "selection" result — the URL + token that the API client uses.
125
+ * `name` is the rc key, or '(env)' for env-based override, or '(flag)' for
126
+ * --backend ad-hoc.
127
+ */
128
+ export interface ResolvedBackend {
129
+ name: string;
130
+ url: string;
131
+ token: string;
132
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Zod schema for ~/.prdrc.yaml (T6).
3
+ *
4
+ * Shape locked by design doc §6.9. Keep optional fields *truly* optional —
5
+ * users may have a half-bootstrapped rc (just user.name) before any login.
6
+ */
7
+ import { z } from "zod";
8
+ export const BackendEntrySchema = z.object({
9
+ url: z.string().url(),
10
+ token: z.string().optional(),
11
+ last_login_at: z.string().optional(),
12
+ // v1.1 §6.3 — default scope for `prd init` / `prd migrate-yaml` so users
13
+ // don't have to retype --team / --project every command. Kept optional so
14
+ // legacy .prdrc files keep validating (the consuming command surfaces a
15
+ // "you must pass --team or set default_team" error at use-site).
16
+ default_team: z.string().optional(),
17
+ default_project: z.string().optional(),
18
+ });
19
+ export const PrdRcSchema = z.object({
20
+ user: z
21
+ .object({
22
+ name: z.string().min(1).optional(),
23
+ email: z.string().email().optional(),
24
+ })
25
+ .optional(),
26
+ default_backend: z.string().optional(),
27
+ backends: z.record(z.string(), BackendEntrySchema).default({}),
28
+ // v1.3 §A.1 — separate admin namespace; admin CLI reads here, never falls
29
+ // back to `backends.<name>.token`. Same BackendEntry shape (url required,
30
+ // token optional, last_login_at/default_team/default_project ignored for
31
+ // admin track).
32
+ admin_backends: z.record(z.string(), BackendEntrySchema).default({}),
33
+ // v1.16 — 全局 UX 语言偏好(顶层,非 per-backend);resolveLang 优先级 config 层
34
+ lang: z.string().optional(),
35
+ });
36
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,yEAAyE;IACzE,0EAA0E;IAC1E,wEAAwE;IACxE,iEAAiE;IACjE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,CAAC;SACJ,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;KACrC,CAAC;SACD,QAAQ,EAAE;IACb,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9D,0EAA0E;IAC1E,0EAA0E;IAC1E,yEAAyE;IACzE,gBAAgB;IAChB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACpE,gEAAgE;IAChE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Pure function:把两份 PRD yaml AST 对比成结构化 DiffResult。
3
+ * 不读不写,可独立单测。
4
+ *
5
+ * 18 个 diffable 单元 = 14 个普通模块 + data_and_api 的 4 子组(DC/API/PC/SEC)。
6
+ * Summary 的 unchanged_modules 用 15 模块(parent)计数。
7
+ */
8
+ export interface FieldChange {
9
+ field: string;
10
+ before: unknown;
11
+ after: unknown;
12
+ is_multiline: boolean;
13
+ }
14
+ export interface ChangedItem {
15
+ primary_key: string;
16
+ display_label?: string;
17
+ field_changes?: FieldChange[];
18
+ }
19
+ export interface ModuleDiff {
20
+ module_key: string;
21
+ module_label: string;
22
+ added: ChangedItem[];
23
+ modified: ChangedItem[];
24
+ removed: ChangedItem[];
25
+ }
26
+ export interface DiffResult {
27
+ perModule: Record<string, ModuleDiff>;
28
+ totals: {
29
+ added: number;
30
+ modified: number;
31
+ removed: number;
32
+ unchanged_modules: number;
33
+ };
34
+ }
35
+ export declare function diffPRDs(left: any, right: any): DiffResult;