@ginkoai/cli 2.4.4 → 2.5.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 (180) hide show
  1. package/LICENSE +661 -21
  2. package/dist/commands/agent/status.d.ts.map +1 -1
  3. package/dist/commands/agent/status.js +2 -0
  4. package/dist/commands/agent/status.js.map +1 -1
  5. package/dist/commands/assign.d.ts.map +1 -1
  6. package/dist/commands/assign.js +2 -0
  7. package/dist/commands/assign.js.map +1 -1
  8. package/dist/commands/charter.js +3 -3
  9. package/dist/commands/charter.js.map +1 -1
  10. package/dist/commands/context/index.d.ts +28 -0
  11. package/dist/commands/context/index.d.ts.map +1 -0
  12. package/dist/commands/context/index.js +165 -0
  13. package/dist/commands/context/index.js.map +1 -0
  14. package/dist/commands/context/score.d.ts +34 -0
  15. package/dist/commands/context/score.d.ts.map +1 -0
  16. package/dist/commands/context/score.js +163 -0
  17. package/dist/commands/context/score.js.map +1 -0
  18. package/dist/commands/create.d.ts.map +1 -1
  19. package/dist/commands/create.js +10 -0
  20. package/dist/commands/create.js.map +1 -1
  21. package/dist/commands/diff/diff-command.d.ts.map +1 -1
  22. package/dist/commands/diff/diff-command.js +2 -0
  23. package/dist/commands/diff/diff-command.js.map +1 -1
  24. package/dist/commands/epic/status.d.ts.map +1 -1
  25. package/dist/commands/epic/status.js +5 -0
  26. package/dist/commands/epic/status.js.map +1 -1
  27. package/dist/commands/graph/api-client.d.ts +131 -0
  28. package/dist/commands/graph/api-client.d.ts.map +1 -1
  29. package/dist/commands/graph/api-client.js +153 -0
  30. package/dist/commands/graph/api-client.js.map +1 -1
  31. package/dist/commands/graph/cleanup.d.ts.map +1 -1
  32. package/dist/commands/graph/cleanup.js +2 -0
  33. package/dist/commands/graph/cleanup.js.map +1 -1
  34. package/dist/commands/graph/explore.d.ts.map +1 -1
  35. package/dist/commands/graph/explore.js +2 -0
  36. package/dist/commands/graph/explore.js.map +1 -1
  37. package/dist/commands/graph/init.d.ts.map +1 -1
  38. package/dist/commands/graph/init.js +4 -10
  39. package/dist/commands/graph/init.js.map +1 -1
  40. package/dist/commands/graph/query.d.ts.map +1 -1
  41. package/dist/commands/graph/query.js +2 -0
  42. package/dist/commands/graph/query.js.map +1 -1
  43. package/dist/commands/graph/status.d.ts.map +1 -1
  44. package/dist/commands/graph/status.js +2 -0
  45. package/dist/commands/graph/status.js.map +1 -1
  46. package/dist/commands/handoff.d.ts.map +1 -1
  47. package/dist/commands/handoff.js +34 -0
  48. package/dist/commands/handoff.js.map +1 -1
  49. package/dist/commands/health.d.ts +15 -0
  50. package/dist/commands/health.d.ts.map +1 -0
  51. package/dist/commands/health.js +212 -0
  52. package/dist/commands/health.js.map +1 -0
  53. package/dist/commands/init-copilot.js +1 -1
  54. package/dist/commands/init-copilot.js.map +1 -1
  55. package/dist/commands/init.d.ts.map +1 -1
  56. package/dist/commands/init.js +74 -2
  57. package/dist/commands/init.js.map +1 -1
  58. package/dist/commands/join/index.js +2 -2
  59. package/dist/commands/knowledge/create.d.ts.map +1 -1
  60. package/dist/commands/knowledge/create.js +2 -0
  61. package/dist/commands/knowledge/create.js.map +1 -1
  62. package/dist/commands/knowledge/graph.d.ts.map +1 -1
  63. package/dist/commands/knowledge/graph.js +2 -0
  64. package/dist/commands/knowledge/graph.js.map +1 -1
  65. package/dist/commands/knowledge/search.d.ts.map +1 -1
  66. package/dist/commands/knowledge/search.js +2 -0
  67. package/dist/commands/knowledge/search.js.map +1 -1
  68. package/dist/commands/log.d.ts.map +1 -1
  69. package/dist/commands/log.js +4 -3
  70. package/dist/commands/log.js.map +1 -1
  71. package/dist/commands/orchestrate.d.ts.map +1 -1
  72. package/dist/commands/orchestrate.js +2 -0
  73. package/dist/commands/orchestrate.js.map +1 -1
  74. package/dist/commands/pull/pull-command.d.ts.map +1 -1
  75. package/dist/commands/pull/pull-command.js +2 -0
  76. package/dist/commands/pull/pull-command.js.map +1 -1
  77. package/dist/commands/push/push-command.d.ts.map +1 -1
  78. package/dist/commands/push/push-command.js +19 -2
  79. package/dist/commands/push/push-command.js.map +1 -1
  80. package/dist/commands/ship.js +1 -1
  81. package/dist/commands/ship.js.map +1 -1
  82. package/dist/commands/sprint/create.d.ts +9 -5
  83. package/dist/commands/sprint/create.d.ts.map +1 -1
  84. package/dist/commands/sprint/create.js +226 -29
  85. package/dist/commands/sprint/create.js.map +1 -1
  86. package/dist/commands/sprint/index.d.ts.map +1 -1
  87. package/dist/commands/sprint/index.js +9 -5
  88. package/dist/commands/sprint/index.js.map +1 -1
  89. package/dist/commands/sprint/status.d.ts +3 -0
  90. package/dist/commands/sprint/status.d.ts.map +1 -1
  91. package/dist/commands/sprint/status.js +88 -2
  92. package/dist/commands/sprint/status.js.map +1 -1
  93. package/dist/commands/start/index.js +3 -3
  94. package/dist/commands/start/index.js.map +1 -1
  95. package/dist/commands/start/start-reflection.d.ts +5 -0
  96. package/dist/commands/start/start-reflection.d.ts.map +1 -1
  97. package/dist/commands/start/start-reflection.js +60 -11
  98. package/dist/commands/start/start-reflection.js.map +1 -1
  99. package/dist/commands/sync/sync-command.js +1 -1
  100. package/dist/commands/sync/sync-command.js.map +1 -1
  101. package/dist/commands/sync/team-sync.js +1 -1
  102. package/dist/commands/task/status.d.ts +1 -1
  103. package/dist/commands/task/status.d.ts.map +1 -1
  104. package/dist/commands/task/status.js +161 -6
  105. package/dist/commands/task/status.js.map +1 -1
  106. package/dist/commands/team/members.d.ts.map +1 -1
  107. package/dist/commands/team/members.js +4 -0
  108. package/dist/commands/team/members.js.map +1 -1
  109. package/dist/commands/team/projects.d.ts.map +1 -1
  110. package/dist/commands/team/projects.js +3 -0
  111. package/dist/commands/team/projects.js.map +1 -1
  112. package/dist/commands/team/status.d.ts.map +1 -1
  113. package/dist/commands/team/status.js +2 -0
  114. package/dist/commands/team/status.js.map +1 -1
  115. package/dist/index.js +12 -8
  116. package/dist/index.js.map +1 -1
  117. package/dist/lib/adoption-score.d.ts +1 -1
  118. package/dist/lib/adoption-score.d.ts.map +1 -1
  119. package/dist/lib/adoption-score.js +1 -0
  120. package/dist/lib/adoption-score.js.map +1 -1
  121. package/dist/lib/context-loader-events.d.ts +4 -4
  122. package/dist/lib/context-loader-events.d.ts.map +1 -1
  123. package/dist/lib/context-loader-events.js +69 -18
  124. package/dist/lib/context-loader-events.js.map +1 -1
  125. package/dist/lib/context-quality.d.ts +224 -0
  126. package/dist/lib/context-quality.d.ts.map +1 -0
  127. package/dist/lib/context-quality.js +363 -0
  128. package/dist/lib/context-quality.js.map +1 -0
  129. package/dist/lib/event-logger.d.ts.map +1 -1
  130. package/dist/lib/event-logger.js +2 -3
  131. package/dist/lib/event-logger.js.map +1 -1
  132. package/dist/lib/health-checker.d.ts +35 -0
  133. package/dist/lib/health-checker.d.ts.map +1 -0
  134. package/dist/lib/health-checker.js +475 -0
  135. package/dist/lib/health-checker.js.map +1 -0
  136. package/dist/lib/output-formatter.d.ts +48 -0
  137. package/dist/lib/output-formatter.d.ts.map +1 -1
  138. package/dist/lib/output-formatter.js +168 -4
  139. package/dist/lib/output-formatter.js.map +1 -1
  140. package/dist/lib/resumption-brief.d.ts +91 -0
  141. package/dist/lib/resumption-brief.d.ts.map +1 -0
  142. package/dist/lib/resumption-brief.js +344 -0
  143. package/dist/lib/resumption-brief.js.map +1 -0
  144. package/dist/lib/staleness-detector.js +1 -1
  145. package/dist/lib/state-cache.d.ts +43 -0
  146. package/dist/lib/state-cache.d.ts.map +1 -1
  147. package/dist/lib/state-cache.js +72 -0
  148. package/dist/lib/state-cache.js.map +1 -1
  149. package/dist/lib/targeted-coaching.js +2 -2
  150. package/dist/lib/task-parser.d.ts +34 -4
  151. package/dist/lib/task-parser.d.ts.map +1 -1
  152. package/dist/lib/task-parser.js +110 -4
  153. package/dist/lib/task-parser.js.map +1 -1
  154. package/dist/services/context-search.d.ts.map +1 -1
  155. package/dist/services/context-search.js +4 -2
  156. package/dist/services/context-search.js.map +1 -1
  157. package/dist/templates/ai-instructions-template.d.ts.map +1 -1
  158. package/dist/templates/ai-instructions-template.js +20 -0
  159. package/dist/templates/ai-instructions-template.js.map +1 -1
  160. package/dist/templates/commands/handoff.md +40 -0
  161. package/dist/templates/commands/quick.md +27 -0
  162. package/dist/templates/commands/ship.md +43 -0
  163. package/dist/templates/commands/start.md +15 -0
  164. package/dist/templates/commands/vibecheck.md +36 -0
  165. package/dist/templates/skills/ginko/SKILL.md +1 -8
  166. package/dist/templates/sprint-template.md +273 -0
  167. package/dist/utils/cloud-guard.d.ts +48 -0
  168. package/dist/utils/cloud-guard.d.ts.map +1 -0
  169. package/dist/utils/cloud-guard.js +107 -0
  170. package/dist/utils/cloud-guard.js.map +1 -0
  171. package/dist/utils/config-loader.d.ts +2 -2
  172. package/dist/utils/config-loader.js +2 -2
  173. package/dist/utils/helpers.d.ts.map +1 -1
  174. package/dist/utils/helpers.js +11 -10
  175. package/dist/utils/helpers.js.map +1 -1
  176. package/dist/utils/perf-logger.d.ts +100 -0
  177. package/dist/utils/perf-logger.d.ts.map +1 -0
  178. package/dist/utils/perf-logger.js +132 -0
  179. package/dist/utils/perf-logger.js.map +1 -0
  180. package/package.json +3 -3
@@ -0,0 +1,273 @@
1
+ # Sprint Creation Template
2
+
3
+ ## AI-Mediated Sprint Creation Guide (EPIC-018)
4
+
5
+ **For AI Partners:** Use this template to create well-formed sprints with rich task content. Unlike epics (which require extensive planning), sprints are focused work units. Your job is to:
6
+
7
+ 1. **Gather context** from the graph and session
8
+ 2. **Clarify intent** through natural conversation
9
+ 3. **Generate rich tasks** with WHY-WHAT-HOW structure
10
+ 4. **Assess confidence** and trigger inquiry when uncertain
11
+ 5. **Create the sprint file** and sync to graph
12
+
13
+ ---
14
+
15
+ ## Step 1: Gather Context
16
+
17
+ Before asking questions, silently gather relevant context:
18
+
19
+ ```bash
20
+ # Check for related bugs, issues, or prior work
21
+ ginko graph query "<topic from user intent>"
22
+
23
+ # Check current session context
24
+ # (You already have this from the conversation)
25
+
26
+ # Check what's in progress
27
+ ginko status
28
+ ```
29
+
30
+ **Synthesize:** What do you already know that's relevant? What patterns, ADRs, or gotchas apply?
31
+
32
+ ---
33
+
34
+ ## Step 2: Clarify Intent
35
+
36
+ The user has expressed intent (e.g., "fix some dashboard bugs"). Ask **only what you need** to create actionable tasks.
37
+
38
+ **Key questions (ask naturally, not mechanically):**
39
+
40
+ 1. **Scope:** "Which specific issues are we targeting?" or "I found these dashboard-related items in the graph: [list]. Which are priorities?"
41
+
42
+ 2. **Boundaries:** "Anything explicitly out of scope for this sprint?"
43
+
44
+ 3. **Success criteria:** "How will we know we're done?"
45
+
46
+ **Stop asking when:**
47
+ - You have enough to create 2-6 concrete tasks
48
+ - User signals readiness ("let's go with that", "sounds good")
49
+ - You're confident (>75%) in task definitions
50
+
51
+ ---
52
+
53
+ ## Step 3: Generate Rich Tasks (WHY-WHAT-HOW)
54
+
55
+ For each task, generate the full structure:
56
+
57
+ ```markdown
58
+ ### {sprint_id}_t{NN}: {Title} ({estimate})
59
+
60
+ **Status:** [ ] Not Started
61
+ **Priority:** {CRITICAL|HIGH|MEDIUM|LOW}
62
+ **Confidence:** {0-100}%
63
+
64
+ **Problem:** {WHY - 1-2 sentences on the pain point or motivation}
65
+
66
+ **Solution:** {WHAT - 1-2 sentences on the desired outcome}
67
+
68
+ **Approach:** {HOW - 2-3 sentences on implementation strategy}
69
+
70
+ **Scope:**
71
+ - Includes: {what's in scope}
72
+ - Excludes: {what's explicitly out}
73
+
74
+ **Acceptance Criteria:**
75
+ - [ ] {Specific, testable criterion 1}
76
+ - [ ] {Specific, testable criterion 2}
77
+ - [ ] {Tests pass}
78
+ ```
79
+
80
+ ### Confidence Scoring (Critical)
81
+
82
+ Be honest about your confidence in each task:
83
+
84
+ | Score | Meaning | Your Action |
85
+ |-------|---------|-------------|
86
+ | 90-100% | Crystal clear, obvious implementation | Proceed |
87
+ | 70-89% | Good clarity, minor assumptions | Note assumptions in Approach |
88
+ | 50-69% | Moderate ambiguity | Flag and ask clarifying question |
89
+ | Below 50% | Significant uncertainty | Stop and discuss with human |
90
+
91
+ **Philosophy:** Low confidence is a STRENGTH. A score of 60 with honest questions is better than 90 with hidden assumptions.
92
+
93
+ ---
94
+
95
+ ## Step 4: Composite Confidence Check
96
+
97
+ After generating all tasks, calculate the average confidence.
98
+
99
+ **If composite confidence < 75%:**
100
+
101
+ ```
102
+ I've drafted the sprint, but my overall confidence is {N}%.
103
+
104
+ Some tasks need clarification:
105
+ - Task 2: {title} (confidence: {N}%) - {what's unclear}
106
+ - Task 4: {title} (confidence: {N}%) - {what's unclear}
107
+
108
+ This is a good thing! Better to clarify now than build the wrong thing.
109
+
110
+ For each flagged task, can you help me understand:
111
+ - {Specific question about Task 2}
112
+ - {Specific question about Task 4}
113
+
114
+ Or if you'd prefer, I can proceed with my best judgment.
115
+ ```
116
+
117
+ **If composite confidence >= 75%:**
118
+ Present the sprint plan and ask for approval before creating files.
119
+
120
+ ---
121
+
122
+ ## Step 5: Create Sprint File
123
+
124
+ After approval, create the sprint file.
125
+
126
+ **Filename:** `docs/sprints/SPRINT-YYYY-MM-{sprint_id}-{slug}.md`
127
+
128
+ Example: `docs/sprints/SPRINT-2026-02-adhoc_260205_s01-dashboard-fixes.md`
129
+
130
+ **Generate Sprint ID:**
131
+ - For ad-hoc work: `adhoc_{YYMMDD}_s{NN}` (e.g., `adhoc_260205_s01`)
132
+ - For epic work: `e{NNN}_s{NN}` (e.g., `e018_s02`)
133
+
134
+ ### Sprint File Template
135
+
136
+ ```markdown
137
+ # SPRINT: {Sprint Name}
138
+
139
+ ## Sprint Overview
140
+
141
+ **Sprint Goal**: {One sentence describing what this sprint achieves}
142
+ **Duration**: {YYYY-MM-DD} to {YYYY-MM-DD}
143
+ **Type**: {Bug Fix|Feature|Infrastructure|Polish}
144
+ **Progress:** 0% (0/{N} tasks complete)
145
+ **ID:** `{sprint_id}`
146
+
147
+ **Success Criteria:**
148
+ - {Sprint-level success criterion 1}
149
+ - {Sprint-level success criterion 2}
150
+
151
+ ---
152
+
153
+ ## Sprint Tasks
154
+
155
+ {For each task, use the WHY-WHAT-HOW format from Step 3}
156
+
157
+ ---
158
+
159
+ ## Related Documents
160
+
161
+ - **Epic**: {Epic name or "Ad-Hoc Work"}
162
+ - **ADRs**: {List relevant ADRs}
163
+ - **Patterns**: {List relevant patterns}
164
+
165
+ ---
166
+
167
+ **Sprint Status**: Active
168
+ **Start Date**: {YYYY-MM-DD}
169
+ **Created By**: {user email}
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Step 6: Sync to Graph
175
+
176
+ After creating the sprint file:
177
+
178
+ ```bash
179
+ ginko push sprint
180
+ ```
181
+
182
+ Then start the first task:
183
+
184
+ ```bash
185
+ ginko task start {sprint_id}_t01
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Content Quality Standards
191
+
192
+ Tasks are assessed as:
193
+
194
+ | Quality | Criteria |
195
+ |---------|----------|
196
+ | **Rich** | Has problem, solution, approach, scope, criteria |
197
+ | **Adequate** | Has basics but missing approach or scope |
198
+ | **Thin** | Missing problem or acceptance criteria - needs enrichment |
199
+
200
+ **Target:** All tasks should be Rich or Adequate. Thin tasks trigger inquiry.
201
+
202
+ ---
203
+
204
+ ## Work Mode Sensitivity
205
+
206
+ Adjust depth based on signals:
207
+
208
+ **Hack & Ship** (quick fix, spike, experiment):
209
+ - 1-3 tasks, minimal ceremony
210
+ - Confidence threshold: 60%
211
+ - Skip detailed scope if obvious
212
+
213
+ **Think & Build** (standard work):
214
+ - 2-6 tasks, full WHY-WHAT-HOW
215
+ - Confidence threshold: 75%
216
+ - Include scope and acceptance criteria
217
+
218
+ **Full Planning** (complex, multi-person):
219
+ - Detailed task breakdown
220
+ - Confidence threshold: 85%
221
+ - Include dependencies, risks
222
+
223
+ ---
224
+
225
+ ## Example Conversation Flow
226
+
227
+ **Human:** "Let's start a sprint to fix some dashboard bugs"
228
+
229
+ **AI:** *[Silently queries: `ginko graph query "dashboard bugs"`]*
230
+
231
+ **AI:** "I found a few dashboard-related items in the graph:
232
+ - Stale data in Projects tab after rename
233
+ - Member list not refreshing
234
+ - Settings panel layout issue on mobile
235
+
236
+ Which of these are priorities for this sprint? Any others I missed?"
237
+
238
+ **Human:** "The first two - they're related. Skip the mobile thing for now."
239
+
240
+ **AI:** "Got it. Both relate to data freshness after project changes. Let me draft the tasks:
241
+
242
+ **Sprint: Dashboard Data Refresh Fixes**
243
+
244
+ 1. **Fix member list refresh on project rename** (2h, confidence: 85%)
245
+ - Problem: Member list shows stale data after project name changes
246
+ - Solution: Trigger refresh when project name updates
247
+
248
+ 2. **Add loading state during refresh** (1h, confidence: 90%)
249
+ - Problem: No feedback during data reload
250
+ - Solution: Show spinner while fetching updated data
251
+
252
+ 3. **Test and verify fixes** (1h, confidence: 95%)
253
+ - Verify both issues resolved, no regressions
254
+
255
+ Overall confidence: 90%. Ready to create the sprint?"
256
+
257
+ **Human:** "Looks good, let's go."
258
+
259
+ **AI:** *[Creates sprint file, runs `ginko push sprint`, starts first task]*
260
+
261
+ ---
262
+
263
+ ## Key Principles
264
+
265
+ 1. **Context first:** Query the graph before asking questions
266
+ 2. **Inquiry is strength:** Low confidence triggers conversation, not silent assumptions
267
+ 3. **Rich tasks:** Every task has WHY-WHAT-HOW, not just a title
268
+ 4. **Natural conversation:** Don't interrogate - collaborate
269
+ 5. **Human approval:** Present plan before creating files
270
+
271
+ ---
272
+
273
+ **Remember:** The goal is actionable tasks the AI can execute autonomously. Quality thinking over complete forms.
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-02-15
5
+ * @tags: [cloud, auth, guard, local-first, ADR-078]
6
+ * @related: [auth-storage.ts, identity.ts]
7
+ * @priority: critical
8
+ * @complexity: low
9
+ * @dependencies: [chalk]
10
+ */
11
+ import { type AuthSession } from './auth-storage.js';
12
+ export interface CloudStatus {
13
+ /** Whether the user is authenticated with Ginko Cloud */
14
+ available: boolean;
15
+ /** The auth session if available, null otherwise */
16
+ session: AuthSession | null;
17
+ }
18
+ /**
19
+ * Non-blocking cloud availability check.
20
+ *
21
+ * Returns cloud status without blocking command execution.
22
+ * Use this for LOCAL and CLOUD-ENHANCED commands that should
23
+ * work without authentication but can do more with it.
24
+ *
25
+ * @param _commandName - The command name (for future telemetry)
26
+ * @returns CloudStatus indicating whether cloud features are available
27
+ */
28
+ export declare function withOptionalCloud(_commandName: string): Promise<CloudStatus>;
29
+ /**
30
+ * Blocking cloud requirement check.
31
+ *
32
+ * Shows a value-proposition upgrade message and exits cleanly
33
+ * if the user is not authenticated. Use this for commands that
34
+ * fundamentally require Ginko Cloud (push, pull, graph, team, etc.).
35
+ *
36
+ * @param commandName - The command name for the error message
37
+ */
38
+ export declare function requireCloud(commandName: string): Promise<void>;
39
+ /**
40
+ * Show a one-time upgrade hint after successful local command usage.
41
+ *
42
+ * Only shown once per CLI process to avoid nagging.
43
+ * Call this at the end of LOCAL commands to gently surface cloud features.
44
+ *
45
+ * @param feature - The cloud feature that would enhance this command
46
+ */
47
+ export declare function showCloudUpgradeHint(feature: string): Promise<void>;
48
+ //# sourceMappingURL=cloud-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-guard.d.ts","sourceRoot":"","sources":["../../src/utils/cloud-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAeH,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAMvF,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,oDAAoD;IACpD,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;CAC7B;AASD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAalF;AAMD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBrE;AAMD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWzE"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-02-15
5
+ * @tags: [cloud, auth, guard, local-first, ADR-078]
6
+ * @related: [auth-storage.ts, identity.ts]
7
+ * @priority: critical
8
+ * @complexity: low
9
+ * @dependencies: [chalk]
10
+ */
11
+ /**
12
+ * Cloud Guard Utility (ADR-078: Local-First CLI Architecture)
13
+ *
14
+ * Provides three tiers of cloud availability checks:
15
+ *
16
+ * LOCAL commands: Use withOptionalCloud() — works with zero auth
17
+ * CLOUD-ENHANCED commands: Use withOptionalCloud() — works locally, richer with cloud
18
+ * CLOUD-ONLY commands: Use requireCloud() — shows upgrade message and exits
19
+ *
20
+ * Replaces hard requireAuth() gates that blocked open-source CLI usage.
21
+ */
22
+ import chalk from 'chalk';
23
+ import { isAuthenticated, loadAuthSession } from './auth-storage.js';
24
+ // Track whether we've shown the upgrade hint this session
25
+ let upgradeHintShown = false;
26
+ // =============================================================================
27
+ // Non-blocking check — for LOCAL + CLOUD-ENHANCED commands
28
+ // =============================================================================
29
+ /**
30
+ * Non-blocking cloud availability check.
31
+ *
32
+ * Returns cloud status without blocking command execution.
33
+ * Use this for LOCAL and CLOUD-ENHANCED commands that should
34
+ * work without authentication but can do more with it.
35
+ *
36
+ * @param _commandName - The command name (for future telemetry)
37
+ * @returns CloudStatus indicating whether cloud features are available
38
+ */
39
+ export async function withOptionalCloud(_commandName) {
40
+ try {
41
+ const session = await loadAuthSession();
42
+ return {
43
+ available: session !== null,
44
+ session,
45
+ };
46
+ }
47
+ catch {
48
+ return {
49
+ available: false,
50
+ session: null,
51
+ };
52
+ }
53
+ }
54
+ // =============================================================================
55
+ // Blocking gate — for CLOUD-ONLY commands
56
+ // =============================================================================
57
+ /**
58
+ * Blocking cloud requirement check.
59
+ *
60
+ * Shows a value-proposition upgrade message and exits cleanly
61
+ * if the user is not authenticated. Use this for commands that
62
+ * fundamentally require Ginko Cloud (push, pull, graph, team, etc.).
63
+ *
64
+ * @param commandName - The command name for the error message
65
+ */
66
+ export async function requireCloud(commandName) {
67
+ const authenticated = await isAuthenticated();
68
+ if (!authenticated) {
69
+ console.log('');
70
+ console.log(chalk.cyan(` ginko ${commandName}`) + chalk.dim(' requires Ginko Cloud.'));
71
+ console.log('');
72
+ console.log(chalk.white(' Ginko Cloud adds:'));
73
+ console.log(chalk.dim(' - Knowledge graph search across your codebase'));
74
+ console.log(chalk.dim(' - Team collaboration and visibility'));
75
+ console.log(chalk.dim(' - AI-powered coaching insights'));
76
+ console.log('');
77
+ console.log(chalk.white(' Get started: ') + chalk.cyan('ginko login'));
78
+ console.log(chalk.dim(' Learn more: https://ginkoai.com/cloud'));
79
+ console.log('');
80
+ console.log(chalk.dim(' Everything you\'ve built locally will sync when you connect.'));
81
+ console.log('');
82
+ process.exit(0);
83
+ }
84
+ }
85
+ // =============================================================================
86
+ // End-of-session nudge — shown once per session
87
+ // =============================================================================
88
+ /**
89
+ * Show a one-time upgrade hint after successful local command usage.
90
+ *
91
+ * Only shown once per CLI process to avoid nagging.
92
+ * Call this at the end of LOCAL commands to gently surface cloud features.
93
+ *
94
+ * @param feature - The cloud feature that would enhance this command
95
+ */
96
+ export async function showCloudUpgradeHint(feature) {
97
+ if (upgradeHintShown)
98
+ return;
99
+ const authenticated = await isAuthenticated();
100
+ if (authenticated)
101
+ return;
102
+ upgradeHintShown = true;
103
+ console.log('');
104
+ console.log(chalk.dim(` Tip: ${feature}`));
105
+ console.log(chalk.dim(' Connect with: ginko login'));
106
+ }
107
+ //# sourceMappingURL=cloud-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-guard.js","sourceRoot":"","sources":["../../src/utils/cloud-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAoB,MAAM,mBAAmB,CAAC;AAavF,0DAA0D;AAC1D,IAAI,gBAAgB,GAAG,KAAK,CAAC;AAE7B,gFAAgF;AAChF,2DAA2D;AAC3D,gFAAgF;AAEhF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,YAAoB;IAC1D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAC;QACxC,OAAO;YACL,SAAS,EAAE,OAAO,KAAK,IAAI;YAC3B,OAAO;SACR,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,0CAA0C;AAC1C,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB;IACpD,MAAM,aAAa,GAAG,MAAM,eAAe,EAAE,CAAC;IAE9C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACxF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC,CAAC;QACzF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,gDAAgD;AAChD,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAe;IACxD,IAAI,gBAAgB;QAAE,OAAO;IAE7B,MAAM,aAAa,GAAG,MAAM,eAAe,EAAE,CAAC;IAC9C,IAAI,aAAa;QAAE,OAAO;IAE1B,gBAAgB,GAAG,IAAI,CAAC;IAExB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -36,11 +36,11 @@ export declare function loadLocalConfig(): Promise<LocalConfig>;
36
36
  * @example
37
37
  * // Using path key
38
38
  * const sprintPath = await resolveProjectPath('currentSprint');
39
- * // → /Users/cnorton/Development/ginko/docs/sprints/CURRENT-SPRINT.md
39
+ * // → /home/user/my-project/docs/sprints/CURRENT-SPRINT.md
40
40
  *
41
41
  * // Using relative path directly
42
42
  * const customPath = await resolveProjectPath('docs/custom/file.md');
43
- * // → /Users/cnorton/Development/ginko/docs/custom/file.md
43
+ * // → /home/user/my-project/docs/custom/file.md
44
44
  */
45
45
  export declare function resolveProjectPath(relativePath: string): Promise<string>;
46
46
  /**
@@ -187,11 +187,11 @@ async function createLocalConfig(projectRoot) {
187
187
  * @example
188
188
  * // Using path key
189
189
  * const sprintPath = await resolveProjectPath('currentSprint');
190
- * // → /Users/cnorton/Development/ginko/docs/sprints/CURRENT-SPRINT.md
190
+ * // → /home/user/my-project/docs/sprints/CURRENT-SPRINT.md
191
191
  *
192
192
  * // Using relative path directly
193
193
  * const customPath = await resolveProjectPath('docs/custom/file.md');
194
- * // → /Users/cnorton/Development/ginko/docs/custom/file.md
194
+ * // → /home/user/my-project/docs/custom/file.md
195
195
  */
196
196
  export async function resolveProjectPath(relativePath) {
197
197
  const [localConfig, projectConfig] = await Promise.all([
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAGnD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAEtD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAmBpD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAWhD;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBpE;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAqCD"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAGnD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAEtD;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAoBpD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAWhD;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBpE;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAqCD"}
@@ -19,16 +19,8 @@ export async function getProjectRoot() {
19
19
  return await requireGinkoRoot();
20
20
  }
21
21
  export async function getUserEmail() {
22
- try {
23
- // Try git config first
24
- const email = execSync('git config user.email', { encoding: 'utf8' }).trim();
25
- if (email)
26
- return email;
27
- }
28
- catch (e) {
29
- // Git not configured
30
- }
31
- // Try config file
22
+ // Ginko config is authoritative — it stores the identity set during init/login (BUG-021)
23
+ // This ensures init and start use the same user directory
32
24
  try {
33
25
  const ginkoDir = await getGinkoDir();
34
26
  const config = await fs.readJSON(path.join(ginkoDir, 'config.json'));
@@ -38,6 +30,15 @@ export async function getUserEmail() {
38
30
  catch (e) {
39
31
  // Config not found or invalid
40
32
  }
33
+ // Fall back to git config
34
+ try {
35
+ const email = execSync('git config user.email', { encoding: 'utf8' }).trim();
36
+ if (email)
37
+ return email;
38
+ }
39
+ catch (e) {
40
+ // Git not configured
41
+ }
41
42
  return 'user@example.com';
42
43
  }
43
44
  export function formatTimeAgo(date) {
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * @fileType: utility
3
+ * @status: current
4
+ * @updated: 2026-02-05
5
+ * @tags: [performance, timing, metrics, EPIC-018]
6
+ * @related: [context-loader-events.ts, start-reflection.ts]
7
+ * @priority: medium
8
+ * @complexity: low
9
+ * @dependencies: []
10
+ */
11
+ /**
12
+ * Performance Logger for Context Loading (EPIC-018 Sprint 1 TASK-04)
13
+ *
14
+ * Provides timing instrumentation for context loading operations.
15
+ * Enabled via GINKO_PERF_LOG=true environment variable.
16
+ *
17
+ * Usage:
18
+ * ```typescript
19
+ * const perf = PerfLogger.create('contextLoad');
20
+ * perf.mark('apiCall');
21
+ * await fetchData();
22
+ * perf.measure('apiCall', 'API call completed');
23
+ * perf.summary();
24
+ * ```
25
+ */
26
+ export interface PerfMark {
27
+ name: string;
28
+ timestamp: number;
29
+ }
30
+ export interface PerfMeasure {
31
+ name: string;
32
+ duration: number;
33
+ label?: string;
34
+ }
35
+ export interface PerfSummary {
36
+ operation: string;
37
+ totalDuration: number;
38
+ measures: PerfMeasure[];
39
+ startedAt: number;
40
+ endedAt: number;
41
+ }
42
+ /**
43
+ * Performance logger for measuring operation timing
44
+ */
45
+ export declare class PerfLogger {
46
+ private operation;
47
+ private startTime;
48
+ private marks;
49
+ private measures;
50
+ private enabled;
51
+ private constructor();
52
+ /**
53
+ * Create a new performance logger for an operation
54
+ */
55
+ static create(operation: string): PerfLogger;
56
+ /**
57
+ * Mark the start of a timed section
58
+ */
59
+ mark(name: string): void;
60
+ /**
61
+ * Measure duration since a mark was set
62
+ * @returns duration in milliseconds
63
+ */
64
+ measure(markName: string, label?: string): number;
65
+ /**
66
+ * Quick measure from operation start
67
+ */
68
+ elapsed(label?: string): number;
69
+ /**
70
+ * Log a summary of all measurements
71
+ */
72
+ summary(): PerfSummary;
73
+ /**
74
+ * Check if performance logging is enabled
75
+ */
76
+ isEnabled(): boolean;
77
+ /**
78
+ * Get total elapsed time in ms
79
+ */
80
+ getTotalDuration(): number;
81
+ }
82
+ /**
83
+ * Utility to time a promise and log result
84
+ */
85
+ export declare function timeAsync<T>(operation: string, promise: Promise<T>, options?: {
86
+ silent?: boolean;
87
+ }): Promise<{
88
+ result: T;
89
+ duration: number;
90
+ }>;
91
+ /**
92
+ * Time multiple parallel operations
93
+ */
94
+ export declare function timeParallel<T extends readonly unknown[]>(operation: string, promises: {
95
+ [K in keyof T]: Promise<T[K]>;
96
+ }, labels?: string[]): Promise<{
97
+ results: T;
98
+ duration: number;
99
+ }>;
100
+ //# sourceMappingURL=perf-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf-logger.d.ts","sourceRoot":"","sources":["../../src/utils/perf-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,OAAO,CAAU;IAEzB,OAAO;IAOP;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU;IAI5C;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxB;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAoBjD;;OAEG;IACH,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAQ/B;;OAEG;IACH,OAAO,IAAI,WAAW;IAsBtB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,gBAAgB,IAAI,MAAM;CAG3B;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAU1C;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,SAAS,OAAO,EAAE,EAC7D,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,EAC3C,MAAM,CAAC,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAe3C"}