@shiyuphan/follow-me 0.2.0 → 0.3.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 (152) hide show
  1. package/README.md +44 -55
  2. package/dist/src/cli.js +566 -188
  3. package/dist/src/comments.js +66 -5
  4. package/dist/src/git.js +12 -0
  5. package/dist/src/host.js +19 -8
  6. package/dist/src/install.js +21 -0
  7. package/dist/src/plan.js +1 -1
  8. package/dist/src/prompt.js +343 -39
  9. package/dist/src/server.js +176 -67
  10. package/dist/src/session.js +13 -11
  11. package/dist/ui/dist/assets/abnfDiagram-WEYOIA3C-DcmzRkVZ.js +1 -0
  12. package/dist/ui/dist/assets/arc-T5QB0T1C.js +1 -0
  13. package/dist/ui/dist/assets/architecture-WOLXFQ4H-DUIkQTeE.js +1 -0
  14. package/dist/ui/dist/assets/architectureDiagram-ZHVYKT53-BUYi4-bA.js +36 -0
  15. package/dist/ui/dist/assets/array-BifhSqXX.js +1 -0
  16. package/dist/ui/dist/assets/blockDiagram-RJAE7QA3-dyJxtT9e.js +140 -0
  17. package/dist/ui/dist/assets/c4Diagram-XDPPPE54-CrAgiaZR.js +38 -0
  18. package/dist/ui/dist/assets/channel-wW7ebm0i.js +1 -0
  19. package/dist/ui/dist/assets/chunk-2E7WHVMD-C6fAf4Vj.js +88 -0
  20. package/dist/ui/dist/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  21. package/dist/ui/dist/assets/chunk-4EMNKR2T-BLZjwZ4Q.js +1 -0
  22. package/dist/ui/dist/assets/chunk-55XCU76K-DGLK2Q-L.js +1 -0
  23. package/dist/ui/dist/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  24. package/dist/ui/dist/assets/chunk-7S6XSTFO-BablszTX.js +2 -0
  25. package/dist/ui/dist/assets/chunk-AQDTSKZB-Cuk3B_vb.js +72 -0
  26. package/dist/ui/dist/assets/chunk-DSNLSHJZ-DiC78RqE.js +127 -0
  27. package/dist/ui/dist/assets/chunk-DUW6YSOI-Dgx8z5s3.js +1 -0
  28. package/dist/ui/dist/assets/chunk-HAGFOTED-X_RbvixX.js +62 -0
  29. package/dist/ui/dist/assets/chunk-HNE4Q36P-C14_x5ck.js +1 -0
  30. package/dist/ui/dist/assets/chunk-J5ZVWO5B-oDCd-gWO.js +1 -0
  31. package/dist/ui/dist/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  32. package/dist/ui/dist/assets/chunk-NGNAAXSQ-C2Wy9Xmz.js +136 -0
  33. package/dist/ui/dist/assets/chunk-NQOKRVIF-Dxd0dtYR.js +213 -0
  34. package/dist/ui/dist/assets/chunk-UHW7PFBP-BIxePNUS.js +1 -0
  35. package/dist/ui/dist/assets/chunk-VQ5W62QI-CKSKLbj4.js +1 -0
  36. package/dist/ui/dist/assets/chunk-WQQL4CDK-CWNmZGlR.js +10 -0
  37. package/dist/ui/dist/assets/chunk-XXDRQBXY-D-I5QHgG.js +1 -0
  38. package/dist/ui/dist/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  39. package/dist/ui/dist/assets/chunk-YZO67HFG-DFP68CFd.js +1 -0
  40. package/dist/ui/dist/assets/chunk-ZAUX2LTX-DY90d4QG.js +1 -0
  41. package/dist/ui/dist/assets/chunk-ZCHMQSOR-Dlpr-5UC.js +2 -0
  42. package/dist/ui/dist/assets/classDiagram-v2-4MYWR3UA-CH9uhoLJ.js +217 -0
  43. package/dist/ui/dist/assets/cose-bilkent-JH36ORCC-DtYHrp8D.js +1 -0
  44. package/dist/ui/dist/assets/cynefin-EF2NZ3EQ-BtslbtrY.js +1 -0
  45. package/dist/ui/dist/assets/cynefinDiagram-WF24UDRP-DUU1Jcc7.js +62 -0
  46. package/dist/ui/dist/assets/cytoscape.esm-BegBNzOV.js +321 -0
  47. package/dist/ui/dist/assets/dagre-NK4GIZVX-CDlP-dRW.js +4 -0
  48. package/dist/ui/dist/assets/defaultLocale-BFoDCU3G.js +1 -0
  49. package/dist/ui/dist/assets/diagram-CBK3MWTC-DiV2fn-r.js +24 -0
  50. package/dist/ui/dist/assets/diagram-I5XIIV2D-Bg5RehGi.js +24 -0
  51. package/dist/ui/dist/assets/diagram-ODIL2UCW-CFmazz3f.js +30 -0
  52. package/dist/ui/dist/assets/diagram-PFBEJUXE-uw3ZBqDp.js +3 -0
  53. package/dist/ui/dist/assets/diagram-RJA3I4VV-uEOYYRYa.js +41 -0
  54. package/dist/ui/dist/assets/diagram-TYUNFSNR-BN58LF_3.js +200 -0
  55. package/dist/ui/dist/assets/dist-tWS_lXDS.js +1 -0
  56. package/dist/ui/dist/assets/ebnfDiagram-V4P3TTPT-B68Tz-w8.js +1 -0
  57. package/dist/ui/dist/assets/elk-QONTBCTQ-DZZohNea.js +27 -0
  58. package/dist/ui/dist/assets/erDiagram-KYQIGQAA-BH_m74pv.js +99 -0
  59. package/dist/ui/dist/assets/eventmodeling-K75KTNOO-CTp5FHos.js +1 -0
  60. package/dist/ui/dist/assets/flowDiagram-IUGLLWBU-CsCvexry.js +1 -0
  61. package/dist/ui/dist/assets/ganttDiagram-R7GPNTJY-BDau7_0f.js +292 -0
  62. package/dist/ui/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  63. package/dist/ui/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  64. package/dist/ui/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  65. package/dist/ui/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  66. package/dist/ui/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  67. package/dist/ui/dist/assets/gitGraph-VSP46ZUC-Bv84IoCm.js +1 -0
  68. package/dist/ui/dist/assets/gitGraphDiagram-PDYL7XHY-DzXcMlm8.js +106 -0
  69. package/dist/ui/dist/assets/graphlib-DS17s2tU.js +1 -0
  70. package/dist/ui/dist/assets/index-BTJoqVVN.js +133 -0
  71. package/dist/ui/dist/assets/index-D60U3smc.css +1 -0
  72. package/dist/ui/dist/assets/info-OHQRW6UA-222J0O_j.js +1 -0
  73. package/dist/ui/dist/assets/infoDiagram-MVDRKAX5-DE2sa3Vz.js +2 -0
  74. package/dist/ui/dist/assets/init-C-OQMol4.js +1 -0
  75. package/dist/ui/dist/assets/ishikawaDiagram-HPEHV2GE-BJDk0Zcj.js +70 -0
  76. package/dist/ui/dist/assets/journeyDiagram-BOSHW7O7-JSUXX5Hb.js +139 -0
  77. package/dist/ui/dist/assets/kanban-definition-FNSA4HC5-Bg79b49M.js +89 -0
  78. package/dist/ui/dist/assets/katex-B_JcIwqj.js +257 -0
  79. package/dist/ui/dist/assets/line-Bk5qQSIa.js +1 -0
  80. package/dist/ui/dist/assets/linear-PFnVMru5.js +1 -0
  81. package/dist/ui/dist/assets/mermaid-parser.core-Dcxlzc-S.js +7 -0
  82. package/dist/ui/dist/assets/mermaid.core-TeOHQJ00.js +44 -0
  83. package/dist/ui/dist/assets/mindmap-definition-6OY57UG3-IaNk8NnW.js +98 -0
  84. package/dist/ui/dist/assets/ordinal-BDEzSJ7C.js +1 -0
  85. package/dist/ui/dist/assets/packet-JDAUHWVQ-DMff5cVK.js +1 -0
  86. package/dist/ui/dist/assets/path-fybaL0A-.js +1 -0
  87. package/dist/ui/dist/assets/pegDiagram-ECIUJNBX-66Xu4YRc.js +1 -0
  88. package/dist/ui/dist/assets/pie-XZMESJXO-GEtzLCIM.js +1 -0
  89. package/dist/ui/dist/assets/pieDiagram-GNMPY74T-7jMBi-kU.js +39 -0
  90. package/dist/ui/dist/assets/prism-bash-D6zCJ74D.js +1 -0
  91. package/dist/ui/dist/assets/prism-c-04YixN25.js +1 -0
  92. package/dist/ui/dist/assets/prism-clike-DapgWyxx.js +1 -0
  93. package/dist/ui/dist/assets/prism-core-FDHlWQ43.js +1 -0
  94. package/dist/ui/dist/assets/prism-cpp-C-lJbC-6.js +1 -0
  95. package/dist/ui/dist/assets/prism-css-CPgOzxXp.js +1 -0
  96. package/dist/ui/dist/assets/prism-go-C_8qAH5n.js +1 -0
  97. package/dist/ui/dist/assets/prism-java-6wtusvIl.js +1 -0
  98. package/dist/ui/dist/assets/prism-javascript-BnO-swvr.js +1 -0
  99. package/dist/ui/dist/assets/prism-json-Dp_-W-Hv.js +1 -0
  100. package/dist/ui/dist/assets/prism-jsx-D-D0NWtC.js +1 -0
  101. package/dist/ui/dist/assets/prism-kotlin-BUlJgC-o.js +1 -0
  102. package/dist/ui/dist/assets/prism-markdown-Bc9-36OC.js +1 -0
  103. package/dist/ui/dist/assets/prism-markup-Cp04rIa1.js +1 -0
  104. package/dist/ui/dist/assets/prism-markup-templating-KkSMBj6Y.js +1 -0
  105. package/dist/ui/dist/assets/prism-php-Co4fM40K.js +1 -0
  106. package/dist/ui/dist/assets/prism-python-CfiSVtM6.js +1 -0
  107. package/dist/ui/dist/assets/prism-ruby-DFCASkuD.js +1 -0
  108. package/dist/ui/dist/assets/prism-rust-Bu9N8X3N.js +1 -0
  109. package/dist/ui/dist/assets/prism-sql-CYhVDMEE.js +1 -0
  110. package/dist/ui/dist/assets/prism-swift-B0kWc-ne.js +1 -0
  111. package/dist/ui/dist/assets/prism-toml-DKb54GAT.js +1 -0
  112. package/dist/ui/dist/assets/prism-tsx-p6J2Kc_4.js +1 -0
  113. package/dist/ui/dist/assets/prism-typescript-BMqONzxf.js +1 -0
  114. package/dist/ui/dist/assets/prism-yaml-C0JHu8gr.js +1 -0
  115. package/dist/ui/dist/assets/quadrantDiagram-D57K4MC3-8hIWayC2.js +7 -0
  116. package/dist/ui/dist/assets/radar-ABXABTNO-BTdwUOOF.js +1 -0
  117. package/dist/ui/dist/assets/railroad-I3PHUGI6-DcMbDqBL.js +1 -0
  118. package/dist/ui/dist/assets/railroad-abnf-LNEFI6M7-gTzUTWeI.js +1 -0
  119. package/dist/ui/dist/assets/railroad-ebnf-DWYD2UWJ-CNtdUPtk.js +1 -0
  120. package/dist/ui/dist/assets/railroad-peg-JR7BVNR7-DOiExAtE.js +1 -0
  121. package/dist/ui/dist/assets/railroadDiagram-Y72NRBL7-2kE_ygvM.js +1 -0
  122. package/dist/ui/dist/assets/requirementDiagram-EQYSW5RA-CoIAHRq2.js +84 -0
  123. package/dist/ui/dist/assets/rough.esm-Dy-Kn_BL.js +1 -0
  124. package/dist/ui/dist/assets/sankeyDiagram-SY24JHO5-7p8D3wim.js +40 -0
  125. package/dist/ui/dist/assets/sequenceDiagram-BLEHNHQU-C6QFnMvn.js +169 -0
  126. package/dist/ui/dist/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
  127. package/dist/ui/dist/assets/src-FgijoBVs.js +1 -0
  128. package/dist/ui/dist/assets/stateDiagram-v2-A6IESKWZ-n9eAb_bT.js +291 -0
  129. package/dist/ui/dist/assets/swimlanes-B3ENRKFQ-U18mtUzX.js +1 -0
  130. package/dist/ui/dist/assets/swimlanesDiagram-AYQRV4AK-DX07QVy9.js +8 -0
  131. package/dist/ui/dist/assets/timeline-definition-JXYKGLGB-CD2Z8QGP.js +120 -0
  132. package/dist/ui/dist/assets/treeView-D4JQ5SDB-sqUjH5gB.js +1 -0
  133. package/dist/ui/dist/assets/treemap-SAJKECNS-DvZ38FP7.js +1 -0
  134. package/dist/ui/dist/assets/usecaseDiagram-WPOLBNNX-CqOGidaZ.js +328 -0
  135. package/dist/ui/dist/assets/vennDiagram-Q3Y3IDCW-D1SXSBQ5.js +34 -0
  136. package/dist/ui/dist/assets/wardley-7MLQ67FV-Bpwio-Dx.js +1 -0
  137. package/dist/ui/dist/assets/wardleyDiagram-IVAIDKWA-JSUXHMnk.js +78 -0
  138. package/dist/ui/dist/assets/xychartDiagram-4URNHDU4-B4IFqQTN.js +7 -0
  139. package/dist/ui/dist/index.html +15 -0
  140. package/dist/ui/dist/style.css +121 -0
  141. package/package.json +31 -10
  142. package/skills/follow-me/SKILL.md +15 -89
  143. package/dist/src/anthropic.js +0 -133
  144. package/dist/ui/app.js +0 -2201
  145. package/dist/ui/concerns.js +0 -165
  146. package/dist/ui/highlight.js +0 -221
  147. package/dist/ui/index.html +0 -94
  148. package/dist/ui/live.js +0 -184
  149. package/dist/ui/playback.js +0 -579
  150. package/dist/ui/questions.js +0 -189
  151. package/dist/ui/style.css +0 -1331
  152. package/dist/ui/summary.js +0 -45
@@ -1,189 +0,0 @@
1
- // @ts-check
2
- // Pure logic for the question loop: telling a question from a change request, matching the
3
- // previous version's questions to their answers, placing each answer in the new plan, and deciding
4
- // where playback stops for one. No DOM, no fetch.
5
-
6
- /**
7
- * @typedef {{ kind: "hunk", unit: string, commit: number, changes: readonly number[] | null }
8
- * | { kind: "message", commit: number } | { kind: "position", commit: number }
9
- * | { kind: "plan" }} Anchor
10
- * @typedef {{ id: string, anchor: Anchor, body: string, kind?: string,
11
- * context: { commitMessage: string, path: string | null, lines?: string[] } }} AskedComment
12
- * @typedef {{ comment: string, status: string, note: string,
13
- * at?: { commit: number, unit?: string } }} Response
14
- * @typedef {{ version: number, comments: AskedComment[], responses: Response[] }} Previous
15
- * @typedef {{ unit: string, select: { kind: "rest" } | { kind: "lines", changes: number[] } }} Ref
16
- * @typedef {{ commit: number, unit: string | null, continues: number[] }} Place
17
- * @typedef {{ id: string, comment: AskedComment, response: Response | null, status: string,
18
- * resolved: boolean, place: Place | null }} AnswerCard
19
- */
20
-
21
- const QUESTION_WORDS = /^\s*(why|what|how|when|where|is|does|can|should)(?![\w'’])/i;
22
-
23
- /**
24
- * What a comment is, guessed from its text: a question when it ends with a question mark or
25
- * opens with a question word. The reviewer can override the guess.
26
- * @param {string} text
27
- * @returns {"question" | "change"}
28
- */
29
- export function inferKind(text) {
30
- const trimmed = text.trim();
31
- return trimmed.endsWith("?") || QUESTION_WORDS.test(trimmed) ? "question" : "change";
32
- }
33
-
34
- /**
35
- * Whether a commit's ref takes any of the lines a comment was on. A "rest" ref takes them all.
36
- * @param {Ref} ref
37
- * @param {readonly number[] | null} changes null means the whole unit
38
- */
39
- function takes(ref, changes) {
40
- if (ref.select.kind === "rest" || changes === null) return true;
41
- const own = new Set(ref.select.changes);
42
- return changes.some((c) => own.has(c));
43
- }
44
-
45
- /**
46
- * Where an answer belongs in the new plan. The agent's own "at" wins, with its 1-based commit.
47
- * Otherwise the first commit that now holds the lines asked about, and the later ones after it.
48
- * null when the code is gone and the answer can only live in the Answers panel.
49
- * @param {AskedComment} comment
50
- * @param {Response | null} response
51
- * @param {readonly { refs: readonly Ref[] }[]} commits
52
- * @returns {Place | null}
53
- */
54
- export function placeAnswer(comment, response, commits) {
55
- const at = response?.at;
56
- if (at !== undefined && at.commit >= 1 && at.commit <= commits.length) {
57
- return { commit: at.commit - 1, unit: at.unit ?? null, continues: [] };
58
- }
59
- const { anchor } = comment;
60
- if (anchor.kind !== "hunk") return null;
61
- const holders = commits.flatMap((commit, index) =>
62
- commit.refs.some((r) => r.unit === anchor.unit && takes(r, anchor.changes)) ? [index] : [],
63
- );
64
- const [first, ...later] = holders;
65
- return first === undefined ? null : { commit: first, unit: anchor.unit, continues: later };
66
- }
67
-
68
- /**
69
- * One card per question of the previous version, in the order they were asked.
70
- * @param {Previous | null} previous
71
- * @param {readonly string[]} resolved ids the reviewer marked resolved
72
- * @param {readonly { refs: readonly Ref[] }[]} commits
73
- * @returns {AnswerCard[]}
74
- */
75
- export function answerCards(previous, resolved, commits) {
76
- if (previous === null) return [];
77
- return previous.comments
78
- .filter((c) => c.kind === "question")
79
- .map((comment) => {
80
- const response = previous.responses.find((r) => r.comment === comment.id) ?? null;
81
- return {
82
- id: comment.id,
83
- comment,
84
- response,
85
- status: response?.status ?? "unanswered",
86
- resolved: resolved.includes(comment.id),
87
- place: placeAnswer(comment, response, commits),
88
- };
89
- });
90
- }
91
-
92
- /**
93
- * How many of the previous questions the new plan answered.
94
- * @param {Previous | null} previous
95
- */
96
- export function answeredCount(previous) {
97
- if (previous === null) return 0;
98
- const asked = new Set(previous.comments.filter((c) => c.kind === "question").map((c) => c.id));
99
- return previous.responses.filter((r) => r.status === "answered" && asked.has(r.comment)).length;
100
- }
101
-
102
- /**
103
- * The cards that belong on a commit: those under its message when unit is null, those above a
104
- * unit otherwise. A card placed on a unit the commit does not show falls back to the message.
105
- * @param {readonly AnswerCard[]} cards
106
- * @param {number} commit
107
- * @param {string | null} unit
108
- * @param {readonly string[]} shown unit ids the commit shows
109
- */
110
- export function cardsAt(cards, commit, unit, shown) {
111
- return cards.filter((card) => {
112
- if (card.place === null || card.place.commit !== commit) return false;
113
- const home =
114
- card.place.unit !== null && shown.includes(card.place.unit) ? card.place.unit : null;
115
- return home === unit;
116
- });
117
- }
118
-
119
- /**
120
- * The comment an "Ask again" posts: same place, in this plan, tied to the question it continues.
121
- * An anchor whose code is gone falls back to the whole plan.
122
- * @param {AnswerCard} card
123
- * @param {string} body
124
- */
125
- export function askAgain(card, body) {
126
- const { anchor, context } = card.comment;
127
- const commit = card.place?.commit ?? 0;
128
- /** @type {Anchor} */
129
- let next = { kind: "plan" };
130
- if (anchor.kind === "hunk" && card.place?.unit) {
131
- next = { kind: "hunk", unit: card.place.unit, commit, changes: anchor.changes };
132
- } else if (anchor.kind === "message" || anchor.kind === "position") {
133
- next = { kind: anchor.kind, commit };
134
- }
135
- return { anchor: next, context, body, kind: "question", follows: card.id };
136
- }
137
-
138
- /**
139
- * The step where playback stops for an unresolved answer: right after the narration of the beat
140
- * it sits on, so the reviewer hears the explanation and then sees the answer to their question.
141
- * A card on a commit as a whole stops after that commit's intro.
142
- * @param {readonly { kind: string, commit: number, unit?: string }[]} beats
143
- * @param {readonly { kind: string, beat: number }[]} steps
144
- * @param {number} position
145
- * @param {readonly AnswerCard[]} cards
146
- * @param {ReadonlySet<string>} seen cards already shown, so a replay does not stop again
147
- * @returns {AnswerCard[]}
148
- */
149
- export function holdAt(beats, steps, position, cards, seen) {
150
- const step = steps[position];
151
- if (step === undefined) return [];
152
- return cards.filter((card) => {
153
- if (card.resolved || seen.has(card.id) || card.place === null) return false;
154
- const { commit, unit } = card.place;
155
- if (unit === null) {
156
- const intro = beats.findIndex((b) => b.kind === "intro" && b.commit === commit);
157
- const next = steps.findIndex((s) => s.beat > intro);
158
- return position === next && next !== -1;
159
- }
160
- const target = beats.findIndex(
161
- (b) => b.kind === "chunk" && b.commit === commit && b.unit === unit,
162
- );
163
- if (target === -1) return false;
164
- return position === steps.findIndex((s) => s.beat === target && s.kind !== "say");
165
- });
166
- }
167
-
168
- /**
169
- * Questions and change requests on a commit, for the two counts in the commit list.
170
- * @param {readonly { anchor: Anchor, kind?: string }[]} comments
171
- * @param {number} commit
172
- */
173
- export function kindCounts(comments, commit) {
174
- const here = comments.filter((c) => c.anchor.kind !== "plan" && c.anchor.commit === commit);
175
- const questions = here.filter((c) => c.kind === "question").length;
176
- return { questions, changes: here.length - questions };
177
- }
178
-
179
- /**
180
- * The line that says what a card is waiting on.
181
- * @param {AnswerCard} card
182
- */
183
- export function statusLine(card) {
184
- if (card.resolved) return "Resolved";
185
- if (card.status === "answered") return "Answered";
186
- if (card.status === "deferred") return "Deferred";
187
- if (card.status === "unanswered") return "Not answered";
188
- return "Answered by changing the plan";
189
- }