@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,229 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
2
+ import { basename, join } from "node:path";
3
+ import { getMessages, readLocale } from "../i18n/index.js";
4
+ import { renderError } from "../i18n/dispatch.js";
5
+ import * as c from "../formatter/colors.js";
6
+ import { loadRc } from "../config/rc.js";
7
+ import { CLI_VERSION } from "../pkgVersion.js";
8
+ function validateWorkspaceName(name) {
9
+ const trimmed = name.trim();
10
+ if (trimmed === "")
11
+ return { ok: false, reason: "empty", raw: name };
12
+ if (trimmed.length > 64)
13
+ return { ok: false, reason: "too_long", raw: name };
14
+ if (/[\x00-\x1f\x7f\/\\:*?"<>|]/.test(trimmed)) {
15
+ return { ok: false, reason: "invalid_char", raw: name };
16
+ }
17
+ return { ok: true, trimmed };
18
+ }
19
+ /**
20
+ * init 专用的已存在 manifest 读取 ——
21
+ * 区别于 workspace.readManifest:这里需要在 features 缺失/损坏时也能识别
22
+ * "已 init 但文件损坏"以便给用户合适的错误提示;workspace 共享版只关心 features
23
+ * 是否合法数组,语义不匹配 init 的需要。
24
+ */
25
+ function readExistingManifest(manifestPath) {
26
+ try {
27
+ const raw = readFileSync(manifestPath, "utf8");
28
+ const parsed = JSON.parse(raw);
29
+ if (parsed &&
30
+ typeof parsed.workspace_name === "string" &&
31
+ typeof parsed.created_at === "string") {
32
+ return {
33
+ ok: true,
34
+ workspace_name: parsed.workspace_name,
35
+ created_at: parsed.created_at,
36
+ };
37
+ }
38
+ return { ok: false };
39
+ }
40
+ catch {
41
+ return { ok: false };
42
+ }
43
+ }
44
+ /**
45
+ * Resolve --team / --project effective values. Precedence:
46
+ * 1. opts.team / opts.project (CLI flag)
47
+ * 2. .prdrc backends.<n>.default_team / default_project (per spec §6.3)
48
+ * Returns {team, project} or null when nothing resolved. The init driver
49
+ * decides whether null is acceptable based on whether opts.slug was given.
50
+ */
51
+ function resolveDefaultScope(opts) {
52
+ if (opts.team && opts.project) {
53
+ return { team: opts.team, project: opts.project };
54
+ }
55
+ // Tolerant rc read — missing rc is fine, just no defaults available.
56
+ const r = loadRc(opts.rcPath);
57
+ if (!r.ok)
58
+ return { team: opts.team, project: opts.project };
59
+ const backendName = opts.backend ?? r.rc.default_backend;
60
+ const entry = backendName ? r.rc.backends[backendName] : undefined;
61
+ return {
62
+ team: opts.team ?? entry?.default_team,
63
+ project: opts.project ?? entry?.default_project,
64
+ };
65
+ }
66
+ /**
67
+ * Emit a minimal v0.2 yaml at the per-feature working/prd.yaml path. Kept
68
+ * deliberately small — just enough for `prd push --allow-create` to round-trip
69
+ * without 400-ing on meta. Users fill the rest via their normal authoring
70
+ * flow (PRD Improve skill, hand-edit, refresh). Schema field choices match
71
+ * `metaSchema`'s required keys.
72
+ */
73
+ function emitYamlStub(opts) {
74
+ const today = new Date().toISOString().slice(0, 10);
75
+ return `schema_version: v0.2
76
+ meta:
77
+ team: ${opts.team}
78
+ project: ${opts.project}
79
+ feature: ${opts.slug}
80
+ title: ${opts.slug}
81
+ summary: ""
82
+ owner: ""
83
+ tags: []
84
+ created_at: "${today}"
85
+ source_materials: []
86
+ lifecycle:
87
+ version: working
88
+ status: draft
89
+ updated_at: ""
90
+ background_and_goals:
91
+ background: ""
92
+ goals: []
93
+ users_and_roles: []
94
+ in_scope: []
95
+ out_of_scope: []
96
+ entities: []
97
+ main_flow: []
98
+ state_permissions: []
99
+ business_rules: []
100
+ scenarios: []
101
+ edge_cases: []
102
+ ui_interaction: []
103
+ data_and_api:
104
+ data_constraints: []
105
+ api_constraints: []
106
+ performance_constraints: []
107
+ security_constraints: []
108
+ acceptance_criteria: []
109
+ open_questions: []
110
+ `;
111
+ }
112
+ /**
113
+ * init 命令主逻辑。返回退出码,由调用方负责 process.exit。
114
+ */
115
+ export function runInitCommand(opts, cwd) {
116
+ const locale = readLocale();
117
+ const m = getMessages(locale);
118
+ // 1. 决定 workspace_name(--workspace flag 优先,否则 cwd 推断)
119
+ const rawWs = opts.workspace !== undefined && opts.workspace !== ""
120
+ ? opts.workspace
121
+ : basename(cwd);
122
+ // 2. 校验 workspace_name
123
+ const v = validateWorkspaceName(rawWs);
124
+ if (!v.ok) {
125
+ const key = v.reason === "empty"
126
+ ? "init_invalid_workspace_empty"
127
+ : v.reason === "too_long"
128
+ ? "init_invalid_workspace_too_long"
129
+ : "init_invalid_workspace_invalid_char";
130
+ process.stderr.write(c.fail("✗ ") + renderError(m, key, { value: v.raw }) + "\n");
131
+ return 1;
132
+ }
133
+ const workspaceName = v.trimmed;
134
+ // 3. If a slug was passed, require --team and --project (flag or .prdrc).
135
+ // Spec §6.3 + Q1: yaml MUST contain meta.team / meta.project (no auto-defaults).
136
+ let scope;
137
+ if (opts.slug) {
138
+ const resolved = resolveDefaultScope(opts);
139
+ if (!resolved.team || !resolved.project) {
140
+ process.stderr.write(c.fail("✗ ") + m.init_team_project_required + "\n");
141
+ return 1;
142
+ }
143
+ scope = { team: resolved.team, project: resolved.project };
144
+ }
145
+ // 4. 检查 .prd/ 是否存在
146
+ const prdDir = join(cwd, ".prd");
147
+ const manifestPath = join(prdDir, "manifest.json");
148
+ if (existsSync(prdDir)) {
149
+ const existing = readExistingManifest(manifestPath);
150
+ if (existing.ok) {
151
+ process.stderr.write(c.fail("✗ ") +
152
+ m.init_already_exists({
153
+ workspace: existing.workspace_name,
154
+ created_at: existing.created_at,
155
+ }) +
156
+ "\n");
157
+ }
158
+ else {
159
+ process.stderr.write(c.fail("✗ ") + m.init_already_exists_corrupt + "\n");
160
+ }
161
+ return 1;
162
+ }
163
+ // 5. mkdir + write manifest
164
+ try {
165
+ mkdirSync(join(prdDir, "features"), { recursive: true });
166
+ }
167
+ catch (e) {
168
+ process.stderr.write(c.fail("✗ ") +
169
+ m.init_fs_error({
170
+ operation: "mkdir .prd/features/",
171
+ message: e.message,
172
+ }) +
173
+ "\n");
174
+ return 2;
175
+ }
176
+ const manifest = {
177
+ schema_version: "v0.1",
178
+ workspace_name: workspaceName,
179
+ created_at: new Date().toISOString().slice(0, 10),
180
+ cli_version: CLI_VERSION,
181
+ features: [],
182
+ };
183
+ try {
184
+ writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf8");
185
+ }
186
+ catch (e) {
187
+ process.stderr.write(c.fail("✗ ") +
188
+ m.init_fs_error({
189
+ operation: "write .prd/manifest.json",
190
+ message: e.message,
191
+ }) +
192
+ "\n");
193
+ return 2;
194
+ }
195
+ // 6. 渲染成功信息
196
+ process.stdout.write(c.pass("✓ ") +
197
+ m.init_success_manifest({ workspace: workspaceName }) +
198
+ "\n");
199
+ process.stdout.write(c.pass("✓ ") + m.init_success_features + "\n");
200
+ // 7. If a slug was passed, also write the v0.2 yaml stub. Done after manifest
201
+ // so a half-init never leaves a yaml without a workspace (the workspace dir
202
+ // is the contract surface for every other CLI command).
203
+ if (opts.slug && scope) {
204
+ const featureDir = join(prdDir, "features", opts.slug, "working");
205
+ const yamlPath = join(featureDir, "prd.yaml");
206
+ try {
207
+ mkdirSync(featureDir, { recursive: true });
208
+ writeFileSync(yamlPath, emitYamlStub({ slug: opts.slug, team: scope.team, project: scope.project }), "utf8");
209
+ }
210
+ catch (e) {
211
+ process.stderr.write(c.fail("✗ ") +
212
+ m.init_fs_error({
213
+ operation: `write ${yamlPath}`,
214
+ message: e.message,
215
+ }) +
216
+ "\n");
217
+ return 2;
218
+ }
219
+ process.stdout.write(c.pass("✓ ") + m.init_success_yaml({ slug: opts.slug, path: yamlPath }) + "\n");
220
+ }
221
+ process.stdout.write("\n" + m.init_next_step + "\n");
222
+ // UAT F5: keep the legacy `init_next_step` line for backward-compat with
223
+ // shell snippets users already grep, then surface the full chain
224
+ // (validate → freeze → push). Spec §6.1 wants both visible so first-time
225
+ // users don't dead-end after init.
226
+ process.stdout.write(m.init_next_step_complete + "\n");
227
+ return 0;
228
+ }
229
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Readable, Writable } from "node:stream";
2
+ export interface LoginOptions {
3
+ backend?: string;
4
+ url?: string;
5
+ bootstrap?: boolean;
6
+ admin?: boolean;
7
+ /** Test seam: pre-supplied prompt answers, one per readline.question. */
8
+ stdin?: string[];
9
+ /** Test seam: override fetch (e.g. dispatch to in-process Hono). */
10
+ fetchFn?: typeof fetch;
11
+ /** Test seam: rc path override. */
12
+ rcPath?: string;
13
+ }
14
+ interface Prompter {
15
+ question(prompt: string): Promise<string>;
16
+ close(): void;
17
+ }
18
+ /**
19
+ * Construct a buffered readline prompter from explicit streams. Exported so
20
+ * unit tests can drive the pipe path with a `PassThrough` stdin without
21
+ * mutating the real `process.stdin`. The production caller in `makePrompter`
22
+ * passes `process.{stdin,stdout}`.
23
+ */
24
+ export declare function makeBufferedPrompter(input: Readable, output: Writable): Prompter;
25
+ export declare function runLoginCommand(opts: LoginOptions, cwd: string): Promise<number>;
26
+ export {};
@@ -0,0 +1,241 @@
1
+ /**
2
+ * `prd login [--backend <name>] [--url <url>] [--bootstrap] [--admin]` (T6).
3
+ *
4
+ * Interactive: prompts for URL (if not in rc / no --url), name, email, and
5
+ * credential. POSTs /api/auth/login, writes token into ~/.prdrc.
6
+ *
7
+ * Test seam: `opts.stdin` lets tests pre-stuff input. In production we read
8
+ * from process.stdin via Node's `readline`. No interactive ANSI; we want
9
+ * dumb-pipe friendly so CI can pipe `echo "..." | prd login`.
10
+ */
11
+ import { createInterface } from "node:readline";
12
+ import { hostname, userInfo } from "node:os";
13
+ import { loadRc, saveRc } from "../config/rc.js";
14
+ import { apiFetch } from "../api/client.js";
15
+ import { getMessages, readLocale } from "../i18n/index.js";
16
+ import * as c from "../formatter/colors.js";
17
+ /**
18
+ * Construct a buffered readline prompter from explicit streams. Exported so
19
+ * unit tests can drive the pipe path with a `PassThrough` stdin without
20
+ * mutating the real `process.stdin`. The production caller in `makePrompter`
21
+ * passes `process.{stdin,stdout}`.
22
+ */
23
+ export function makeBufferedPrompter(input, output) {
24
+ const rl = createInterface({ input, output });
25
+ // Buffer all 'line' events as they arrive. Critical for piped stdin:
26
+ // `printf 'a\nb\nc\n' | prd login` delivers all 3 lines to readline before
27
+ // the second rl.question registers, so the 2nd/3rd lines emit with no
28
+ // listener and vanish. By draining 'line' into our own queue, question()
29
+ // always has data to dispense. See T6-MN6 + T11 dogfood B-2 report.
30
+ const queue = [];
31
+ let pendingResolve = null;
32
+ let closed = false;
33
+ rl.on("line", (line) => {
34
+ if (pendingResolve) {
35
+ const r = pendingResolve;
36
+ pendingResolve = null;
37
+ r(line);
38
+ }
39
+ else {
40
+ queue.push(line);
41
+ }
42
+ });
43
+ rl.on("close", () => {
44
+ closed = true;
45
+ // Flush any pending question with "" so the await unblocks and the
46
+ // command can take the empty-input branch instead of hanging forever.
47
+ if (pendingResolve) {
48
+ const r = pendingResolve;
49
+ pendingResolve = null;
50
+ r("");
51
+ }
52
+ });
53
+ return {
54
+ question: (prompt) => new Promise((resolve) => {
55
+ // Render prompt regardless of source so the captured transcript looks
56
+ // the same in TTY and CI/pipe modes.
57
+ output.write(prompt);
58
+ if (queue.length > 0) {
59
+ resolve(queue.shift());
60
+ return;
61
+ }
62
+ if (closed) {
63
+ resolve("");
64
+ return;
65
+ }
66
+ pendingResolve = resolve;
67
+ }),
68
+ close: () => rl.close(),
69
+ };
70
+ }
71
+ function makePrompter(opts) {
72
+ if (opts.stdin) {
73
+ const queue = [...opts.stdin];
74
+ return {
75
+ question: async (_prompt) => {
76
+ // Mirror the prompt to stdout for snapshot debugging — matches the
77
+ // experience users get from real readline.
78
+ process.stdout.write(_prompt);
79
+ const next = queue.shift();
80
+ if (next === undefined)
81
+ return "";
82
+ process.stdout.write(next + "\n");
83
+ return next;
84
+ },
85
+ close: () => { },
86
+ };
87
+ }
88
+ return makeBufferedPrompter(process.stdin, process.stdout);
89
+ }
90
+ export async function runLoginCommand(opts, cwd) {
91
+ void cwd;
92
+ const m = getMessages(readLocale());
93
+ const rcResult = loadRc(opts.rcPath);
94
+ let rc = rcResult.ok
95
+ ? rcResult.rc
96
+ : { backends: {}, admin_backends: {} };
97
+ if (!rcResult.ok && rcResult.reason !== "missing") {
98
+ // permission / parse / schema — surface to user before clobbering
99
+ if (rcResult.reason === "permissions") {
100
+ process.stderr.write(c.warn(m.rc_chmod_warn({ mode: rcResult.mode })) + "\n");
101
+ }
102
+ else {
103
+ process.stderr.write(c.fail("✗ ") + m.rc_invalid({ message: rcResult.message }) + "\n");
104
+ return 1;
105
+ }
106
+ }
107
+ const backendName = opts.backend ?? rc.default_backend ?? "default";
108
+ const existingBackend = rc.backends[backendName];
109
+ const prompter = makePrompter(opts);
110
+ try {
111
+ // --- URL resolution ---
112
+ let url = opts.url ?? existingBackend?.url ?? "";
113
+ if (!url) {
114
+ url = (await prompter.question(m.login_prompt_url)).trim();
115
+ if (!url) {
116
+ process.stderr.write(c.fail("✗ ") + m.login_aborted + "\n");
117
+ return 1;
118
+ }
119
+ }
120
+ // Strip trailing slash so apiFetch's normalization is stable.
121
+ url = url.replace(/\/+$/, "");
122
+ // --- name / email ---
123
+ const defaultName = rc.user?.name ?? userInfo().username;
124
+ const defaultEmail = rc.user?.email ?? "";
125
+ const nameRaw = (await prompter.question(`${m.login_prompt_name}[${defaultName}] `)).trim();
126
+ const name = nameRaw || defaultName;
127
+ const emailRaw = (await prompter.question(defaultEmail
128
+ ? `${m.login_prompt_email}[${defaultEmail}] `
129
+ : m.login_prompt_email)).trim();
130
+ const email = emailRaw || defaultEmail || undefined;
131
+ // --- credential ---
132
+ // UAT F4: the old prompts ("Admin token (from your team admin)") misled
133
+ // users who already had a PAT in ~/.prdrc — they typed their PAT here,
134
+ // which is the wrong kind of credential. Spec §6.1: when the user already
135
+ // has a PAT, they should use `prd config set backends.<n>.token <pat>`
136
+ // instead. The unified prompt says so explicitly and only accepts admin
137
+ // tokens / bootstrap secrets (used to create new accounts).
138
+ const via = opts.bootstrap
139
+ ? "bootstrap_secret"
140
+ : "admin_token";
141
+ const credential = (await prompter.question(m.login_credential_prompt)).trim();
142
+ if (!credential) {
143
+ process.stderr.write(c.fail("✗ ") + m.login_aborted + "\n");
144
+ return 1;
145
+ }
146
+ // Construct the label so admins can see "alice-macbook" in `prd admin
147
+ // token list`. `userInfo()` is a best-effort fallback when the
148
+ // environment is exotic (CI containers).
149
+ let label;
150
+ try {
151
+ label = `${userInfo().username}-${hostname()}`;
152
+ }
153
+ catch {
154
+ label = `${name}-cli`;
155
+ }
156
+ // --- call backend ---
157
+ const res = await apiFetch({ name: backendName, url, token: "" }, "/api/auth/login", {
158
+ method: "POST",
159
+ headers: { "content-type": "application/json" },
160
+ body: JSON.stringify({ name, email, via, credential, label }),
161
+ fetchFn: opts.fetchFn,
162
+ });
163
+ if (!res.ok) {
164
+ if (res.code === "UNAUTHENTICATED") {
165
+ process.stderr.write(c.fail("✗ ") + m.login_invalid_credential + "\n");
166
+ }
167
+ else if (res.code === "BOOTSTRAP_DISABLED") {
168
+ process.stderr.write(c.fail("✗ ") + m.login_bootstrap_disabled + "\n");
169
+ }
170
+ else if (res.code === "USER_EXISTS") {
171
+ // Confirm via additional prompt, then retry with
172
+ // confirm_existing_user=true. This keeps the destructive token swap
173
+ // explicit per design §6.5 implicit assumption.
174
+ const answer = (await prompter.question(m.login_user_exists_confirm({ name })))
175
+ .trim()
176
+ .toLowerCase();
177
+ if (answer !== "y" && answer !== "yes") {
178
+ process.stderr.write(c.fail("✗ ") + m.login_aborted + "\n");
179
+ return 1;
180
+ }
181
+ const retry = await apiFetch({ name: backendName, url, token: "" }, "/api/auth/login", {
182
+ method: "POST",
183
+ headers: { "content-type": "application/json" },
184
+ body: JSON.stringify({
185
+ name,
186
+ email,
187
+ via,
188
+ credential,
189
+ label,
190
+ confirm_existing_user: true,
191
+ }),
192
+ fetchFn: opts.fetchFn,
193
+ });
194
+ if (!retry.ok) {
195
+ process.stderr.write(c.fail("✗ ") + `Login failed: ${retry.code} — ${retry.message}\n`);
196
+ return 1;
197
+ }
198
+ return writeRcAndSucceed(retry, rc, backendName, url, name, email, m, opts.rcPath);
199
+ }
200
+ else {
201
+ process.stderr.write(c.fail("✗ ") + `Login failed: ${res.code} — ${res.message}\n`);
202
+ return 1;
203
+ }
204
+ return 1;
205
+ }
206
+ return writeRcAndSucceed(res, rc, backendName, url, name, email, m, opts.rcPath);
207
+ }
208
+ finally {
209
+ prompter.close();
210
+ }
211
+ }
212
+ function writeRcAndSucceed(res, rc, backendName, url, name, email, m, rcPath) {
213
+ const token = res.body?.data?.token;
214
+ if (!token) {
215
+ process.stderr.write(c.fail("✗ ") + "Login response missing token field\n");
216
+ return 1;
217
+ }
218
+ const next = {
219
+ user: { name, email: email ?? rc.user?.email },
220
+ default_backend: rc.default_backend ?? backendName,
221
+ backends: {
222
+ ...rc.backends,
223
+ [backendName]: {
224
+ url,
225
+ token,
226
+ last_login_at: new Date().toISOString(),
227
+ },
228
+ },
229
+ // v1.3 §A.1 — carry over existing admin_backends untouched; login (user
230
+ // CLI track) must never wipe admin tokens, and never write into them.
231
+ admin_backends: rc.admin_backends ?? {},
232
+ };
233
+ const saveRes = saveRc(next, rcPath);
234
+ if (!saveRes.ok) {
235
+ process.stderr.write(c.fail("✗ ") + `Failed to write ~/.prdrc: ${saveRes.message}\n`);
236
+ return 1;
237
+ }
238
+ process.stdout.write(c.pass("✓ ") + m.login_success({ name, url }) + "\n");
239
+ return 0;
240
+ }
241
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface LogoutOptions {
2
+ backend?: string;
3
+ fetchFn?: typeof fetch;
4
+ rcPath?: string;
5
+ }
6
+ export declare function runLogoutCommand(opts: LogoutOptions, cwd: string): Promise<number>;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `prd logout [--backend <name>]` (T6).
3
+ *
4
+ * 1. Find current session via GET /api/me (token in rc).
5
+ * 2. DELETE /api/auth/sessions/<id> to revoke server-side.
6
+ * 3. Strip `token` field from rc backend entry (keep url + last_login_at so
7
+ * the user can `prd login --backend X` later without re-typing URL).
8
+ *
9
+ * Best-effort: if server is unreachable, we still wipe the local token so
10
+ * the rc isn't left holding a stale credential. Caller sees a warning.
11
+ */
12
+ import { saveRc } from "../config/rc.js";
13
+ import { apiFetch } from "../api/client.js";
14
+ import { loadRcWithWarn, requireBackend } from "../sync/cliRcHelpers.js";
15
+ import { getMessages, readLocale } from "../i18n/index.js";
16
+ import * as c from "../formatter/colors.js";
17
+ export async function runLogoutCommand(opts, cwd) {
18
+ void cwd;
19
+ const m = getMessages(readLocale());
20
+ const loaded = loadRcWithWarn(opts.rcPath);
21
+ if (loaded.hadError)
22
+ return 1;
23
+ if (!loaded.rc) {
24
+ process.stderr.write(c.fail("✗ ") + m.backend_not_configured + "\n");
25
+ return 1;
26
+ }
27
+ const backend = requireBackend(loaded.rc, { backend: opts.backend });
28
+ if (!backend)
29
+ return 1;
30
+ // 1. GET /me — find current session.
31
+ const me = await apiFetch(backend, "/api/auth/me", { fetchFn: opts.fetchFn });
32
+ let sessionId;
33
+ if (me.ok) {
34
+ sessionId = me.body?.data?.token?.id;
35
+ }
36
+ else if (me.code === "UNAUTHENTICATED") {
37
+ // Token was already revoked / expired server-side. Still wipe local.
38
+ process.stdout.write(c.warn(m.logout_no_session) + "\n");
39
+ }
40
+ else if (me.network) {
41
+ process.stdout.write(c.warn(`⚠ Could not contact backend: ${me.message}. Wiping local token only.`) +
42
+ "\n");
43
+ }
44
+ else {
45
+ process.stderr.write(c.fail("✗ ") + `Failed: ${me.code} — ${me.message}\n`);
46
+ return 1;
47
+ }
48
+ // 2. DELETE /sessions/:id if we got one.
49
+ if (sessionId) {
50
+ const del = await apiFetch(backend, `/api/auth/sessions/${sessionId}`, { method: "DELETE", fetchFn: opts.fetchFn });
51
+ if (!del.ok && !del.network) {
52
+ // Non-404 / non-network error → surface but proceed to wipe local rc.
53
+ process.stdout.write(c.warn(`⚠ Backend revoke failed: ${del.code}. Wiping local token only.`) +
54
+ "\n");
55
+ }
56
+ }
57
+ // 3. Strip token from rc. Keep `url` + `last_login_at` so a future
58
+ // `prd login --backend X` doesn't have to re-prompt for URL.
59
+ const next = { ...loaded.rc };
60
+ const entry = next.backends[backend.name];
61
+ if (entry) {
62
+ next.backends = {
63
+ ...next.backends,
64
+ [backend.name]: { url: entry.url, last_login_at: entry.last_login_at },
65
+ };
66
+ }
67
+ const save = saveRc(next, opts.rcPath);
68
+ if (!save.ok) {
69
+ process.stderr.write(c.fail("✗ ") + `Failed to write ~/.prdrc: ${save.message}\n`);
70
+ return 1;
71
+ }
72
+ process.stdout.write(c.pass("✓ ") + m.logout_success({ backend: backend.name }) + "\n");
73
+ return 0;
74
+ }
75
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface MigrateYamlOptions {
2
+ /** Single feature slug, or undefined for batch mode. */
3
+ slug?: string;
4
+ /** Override .prdrc default_team. */
5
+ team?: string;
6
+ /** Override .prdrc default_project. */
7
+ project?: string;
8
+ /** Skip prompts; require --team / --project to be passed. */
9
+ nonInteractive?: boolean;
10
+ /** Backend selection (same precedence as other sync commands). */
11
+ backend?: string;
12
+ fetchFn?: typeof fetch;
13
+ rcPath?: string;
14
+ /** Test seam — injectable reader for prompts. */
15
+ promptFn?: (question: string) => Promise<string>;
16
+ }
17
+ export declare function runMigrateYamlCommand(opts: MigrateYamlOptions, cwd: string): Promise<number>;