@ethlete/agent-rules 0.1.0-next.2 → 0.1.0-next.20

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 (178) hide show
  1. package/CHANGELOG.md +269 -0
  2. package/README.md +350 -29
  3. package/THIRD-PARTY-LICENSES.md +35 -0
  4. package/content/git-hooks/post-checkout.sh +10 -0
  5. package/content/git-hooks/pre-push.sh +5 -0
  6. package/content/hooks/context-warning.py +766 -108
  7. package/content/hooks/subagent-model-policy.py +187 -0
  8. package/content/output-styles/ste-clarity.md +131 -0
  9. package/content/rules/app-styling.md +59 -0
  10. package/content/rules/comments.md +53 -20
  11. package/content/rules/lint-and-format.md +6 -5
  12. package/content/rules/nx-layout.md +47 -0
  13. package/content/rules/reactive-state.md +1 -1
  14. package/content/rules/styling.md +9 -7
  15. package/content/rules/subagent-models.md +29 -0
  16. package/content/skills/angular-patterns/SKILL.md +30 -7
  17. package/content/skills/api-source/SKILL.md +130 -0
  18. package/content/skills/app-testing/SKILL.md +141 -0
  19. package/content/skills/codex-subagent/SKILL.md +90 -0
  20. package/content/skills/codex-subagent/codex-agent.mjs +229 -0
  21. package/content/skills/design-exploration/SKILL.md +205 -0
  22. package/content/skills/design-exploration/check-story.mjs +139 -0
  23. package/content/skills/design-exploration/shoot-template.mjs +61 -0
  24. package/content/skills/domain-modeling/ADR-FORMAT.md +47 -0
  25. package/content/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
  26. package/content/skills/domain-modeling/SKILL.md +80 -0
  27. package/content/skills/figma-export/SKILL.md +191 -0
  28. package/content/skills/figma-export/dump-figma-layers.py +83 -0
  29. package/content/skills/figma-export/dump-figma-svg.py +235 -0
  30. package/content/skills/figma-export/measure-template.mjs +87 -0
  31. package/content/skills/git-commit/SKILL.md +6 -7
  32. package/content/skills/git-flow/SKILL.md +87 -0
  33. package/content/skills/grill-with-docs/SKILL.md +13 -0
  34. package/content/skills/grilling/SKILL.md +34 -0
  35. package/content/skills/handoff/SKILL.md +74 -4
  36. package/content/skills/query/SKILL.md +165 -64
  37. package/content/skills/rxjs-signals/SKILL.md +31 -4
  38. package/content/skills/sdk-docs/SKILL.md +50 -14
  39. package/content/skills/sdk-local-build/SKILL.md +30 -10
  40. package/content/skills/sdk-local-build/sdk-local-baseline.mjs +64 -0
  41. package/content/skills/sdk-source/SKILL.md +49 -21
  42. package/content/skills/sdk-update/SKILL.md +96 -0
  43. package/content/skills/story-styling/SKILL.md +10 -8
  44. package/content/skills/styleguide/SKILL.md +12 -7
  45. package/content/skills/styleguide/assets.md +54 -0
  46. package/content/skills/styleguide/changesets.md +17 -0
  47. package/content/skills/styleguide/file-structure.md +73 -0
  48. package/content/skills/styleguide/lint-rule-lookup.md +51 -0
  49. package/content/skills/styleguide/storybook-structure.md +25 -0
  50. package/content/skills/theming/SKILL.md +41 -28
  51. package/content/skills/timetrack/SKILL.md +397 -0
  52. package/content/skills/verify-in-app/SKILL.md +107 -0
  53. package/migrations/app-styling-utilities.md +63 -0
  54. package/migrations/list-state-query-form.md +20 -0
  55. package/migrations/nx-layout.md +29 -0
  56. package/migrations/sdk-components-over-hand-built-ui.md +27 -0
  57. package/migrations/search-query-field.md +52 -0
  58. package/migrations.json +48 -0
  59. package/package.json +16 -2
  60. package/src/index.js +63 -28
  61. package/src/index.js.map +1 -1
  62. package/src/lib/cli-args.d.ts +9 -0
  63. package/src/lib/cli-args.js +48 -0
  64. package/src/lib/cli-args.js.map +1 -0
  65. package/src/lib/commitlint.d.ts +10 -0
  66. package/src/lib/commitlint.js +51 -0
  67. package/src/lib/commitlint.js.map +1 -0
  68. package/src/lib/config.d.ts +38 -4
  69. package/src/lib/config.js +84 -8
  70. package/src/lib/config.js.map +1 -1
  71. package/src/lib/filter.d.ts +2 -0
  72. package/src/lib/filter.js +4 -4
  73. package/src/lib/filter.js.map +1 -1
  74. package/src/lib/frontmatter.d.ts +2 -0
  75. package/src/lib/frontmatter.js +33 -5
  76. package/src/lib/frontmatter.js.map +1 -1
  77. package/src/lib/git-flow/build.d.ts +35 -0
  78. package/src/lib/git-flow/build.js +24 -0
  79. package/src/lib/git-flow/build.js.map +1 -0
  80. package/src/lib/git-flow/config.d.ts +59 -0
  81. package/src/lib/git-flow/config.js +50 -0
  82. package/src/lib/git-flow/config.js.map +1 -0
  83. package/src/lib/git-flow/index.d.ts +6 -0
  84. package/src/lib/git-flow/index.js +10 -0
  85. package/src/lib/git-flow/index.js.map +1 -0
  86. package/src/lib/git-flow/parse.d.ts +49 -0
  87. package/src/lib/git-flow/parse.js +300 -0
  88. package/src/lib/git-flow/parse.js.map +1 -0
  89. package/src/lib/git-flow/rename.d.ts +24 -0
  90. package/src/lib/git-flow/rename.js +70 -0
  91. package/src/lib/git-flow/rename.js.map +1 -0
  92. package/src/lib/git-flow/start.d.ts +49 -0
  93. package/src/lib/git-flow/start.js +57 -0
  94. package/src/lib/git-flow/start.js.map +1 -0
  95. package/src/lib/git-flow/validate.d.ts +34 -0
  96. package/src/lib/git-flow/validate.js +72 -0
  97. package/src/lib/git-flow/validate.js.map +1 -0
  98. package/src/lib/git-flow-command.d.ts +4 -0
  99. package/src/lib/git-flow-command.js +157 -0
  100. package/src/lib/git-flow-command.js.map +1 -0
  101. package/src/lib/git-flow-repair.d.ts +17 -0
  102. package/src/lib/git-flow-repair.js +157 -0
  103. package/src/lib/git-flow-repair.js.map +1 -0
  104. package/src/lib/git-flow-start.d.ts +20 -0
  105. package/src/lib/git-flow-start.js +132 -0
  106. package/src/lib/git-flow-start.js.map +1 -0
  107. package/src/lib/git.d.ts +64 -0
  108. package/src/lib/git.js +131 -0
  109. package/src/lib/git.js.map +1 -0
  110. package/src/lib/gitlab.d.ts +35 -0
  111. package/src/lib/gitlab.js +108 -0
  112. package/src/lib/gitlab.js.map +1 -0
  113. package/src/lib/index.d.ts +2 -0
  114. package/src/lib/index.js +2 -0
  115. package/src/lib/index.js.map +1 -1
  116. package/src/lib/migrate.js +1 -1
  117. package/src/lib/migrate.js.map +1 -1
  118. package/src/lib/output-style-command.d.ts +3 -0
  119. package/src/lib/output-style-command.js +69 -0
  120. package/src/lib/output-style-command.js.map +1 -0
  121. package/src/lib/output-style.d.ts +38 -0
  122. package/src/lib/output-style.js +134 -0
  123. package/src/lib/output-style.js.map +1 -0
  124. package/src/lib/owned-paths.js +27 -3
  125. package/src/lib/owned-paths.js.map +1 -1
  126. package/src/lib/package-runner.d.ts +3 -0
  127. package/src/lib/package-runner.js +69 -0
  128. package/src/lib/package-runner.js.map +1 -0
  129. package/src/lib/plain-text.d.ts +9 -0
  130. package/src/lib/plain-text.js +22 -0
  131. package/src/lib/plain-text.js.map +1 -0
  132. package/src/lib/plan.d.ts +6 -6
  133. package/src/lib/plan.js +147 -40
  134. package/src/lib/plan.js.map +1 -1
  135. package/src/lib/prompt.d.ts +8 -0
  136. package/src/lib/prompt.js +27 -0
  137. package/src/lib/prompt.js.map +1 -0
  138. package/src/lib/render.d.ts +24 -2
  139. package/src/lib/render.js +39 -10
  140. package/src/lib/render.js.map +1 -1
  141. package/src/lib/sync.d.ts +0 -1
  142. package/src/lib/sync.js +23 -15
  143. package/src/lib/sync.js.map +1 -1
  144. package/src/lib/targets/agents-skills.js +1 -1
  145. package/src/lib/targets/agents-skills.js.map +1 -1
  146. package/src/lib/targets/claude-hooks.d.ts +1 -23
  147. package/src/lib/targets/claude-hooks.js +17 -85
  148. package/src/lib/targets/claude-hooks.js.map +1 -1
  149. package/src/lib/targets/claude.js +1 -2
  150. package/src/lib/targets/claude.js.map +1 -1
  151. package/src/lib/targets/codex-hooks.d.ts +12 -0
  152. package/src/lib/targets/codex-hooks.js +34 -0
  153. package/src/lib/targets/codex-hooks.js.map +1 -0
  154. package/src/lib/targets/codex.js +4 -4
  155. package/src/lib/targets/codex.js.map +1 -1
  156. package/src/lib/targets/copilot.js +3 -3
  157. package/src/lib/targets/copilot.js.map +1 -1
  158. package/src/lib/targets/cursor.js +2 -2
  159. package/src/lib/targets/cursor.js.map +1 -1
  160. package/src/lib/targets/git-hooks.d.ts +24 -0
  161. package/src/lib/targets/git-hooks.js +71 -0
  162. package/src/lib/targets/git-hooks.js.map +1 -0
  163. package/src/lib/targets/hooks-shared.d.ts +58 -0
  164. package/src/lib/targets/hooks-shared.js +128 -0
  165. package/src/lib/targets/hooks-shared.js.map +1 -0
  166. package/src/lib/targets/shared.d.ts +1 -9
  167. package/src/lib/targets/shared.js +4 -8
  168. package/src/lib/targets/shared.js.map +1 -1
  169. package/src/lib/timetrack-command.d.ts +11 -0
  170. package/src/lib/timetrack-command.js +1055 -0
  171. package/src/lib/timetrack-command.js.map +1 -0
  172. package/src/lib/timetrack-snapshot.d.ts +55 -0
  173. package/src/lib/timetrack-snapshot.js +120 -0
  174. package/src/lib/timetrack-snapshot.js.map +1 -0
  175. package/src/lib/timetrack.d.ts +561 -0
  176. package/src/lib/timetrack.js +271 -0
  177. package/src/lib/timetrack.js.map +1 -0
  178. package/content/skills/styleguide/STYLEGUIDE.md +0 -520
@@ -0,0 +1,561 @@
1
+ /** What every write answers: it waits in the app until the user approves or rejects it. */
2
+ export type TimetrackQueued = {
3
+ status: 'queued';
4
+ approvalId: string;
5
+ };
6
+ /** Where a queued write stands. `result` is what the op answered once approved and carried out. */
7
+ export type TimetrackApprovalStatus = {
8
+ status: 'queued' | 'rejected' | 'expired';
9
+ approvalId: string;
10
+ } | {
11
+ status: 'approved';
12
+ approvalId: string;
13
+ result?: unknown;
14
+ error?: string;
15
+ };
16
+ export type TimetrackIssue = {
17
+ key: string;
18
+ id: string;
19
+ summary: string;
20
+ issueType: string;
21
+ parentKey?: string;
22
+ subject?: string;
23
+ };
24
+ export type TimetrackStatus = {
25
+ version: number;
26
+ jiraReady: boolean;
27
+ tempoReady: boolean;
28
+ projects: {
29
+ key: string;
30
+ name: string;
31
+ }[];
32
+ subjectField: string;
33
+ };
34
+ export type TimetrackInstance = {
35
+ levels: {
36
+ hierarchyLevel: number;
37
+ typeNames: string[];
38
+ }[];
39
+ suggestedParenting: 'parent-field' | 'issue-link';
40
+ subjectFieldCandidates: {
41
+ id: string;
42
+ name: string;
43
+ }[];
44
+ };
45
+ export type TimetrackRepoProject = {
46
+ repoPath: string;
47
+ projectKey?: string;
48
+ private: boolean;
49
+ inherited: boolean;
50
+ suggestedProjectKey?: string;
51
+ };
52
+ /** One standing statement about what work in a context is logged against. */
53
+ export type TimetrackAttributionRule = {
54
+ id: string;
55
+ repoPath?: string;
56
+ branch?: string;
57
+ appId?: string;
58
+ /** The issue the rule names, or nothing when it donates its time or names a stand-in instead. */
59
+ issueKey?: string;
60
+ /** The stand-in the rule names, as an id into what `timetrackStandIns` answers. */
61
+ standInId?: string;
62
+ /** Whether the rule donates its time to the work around it rather than naming an issue. */
63
+ donates: boolean;
64
+ createdAtMs: number;
65
+ };
66
+ /** One standing statement about a path: whether it is work, and which project it files into. */
67
+ export type TimetrackProjectLinkRule = {
68
+ id: string;
69
+ path: string;
70
+ projectKey?: string;
71
+ private: boolean;
72
+ createdAtMs: number;
73
+ };
74
+ /** The settings that decide what a day's work is named. It holds no host, no account and no token. */
75
+ export type TimetrackRules = {
76
+ dayTargetMs: number;
77
+ gapFillMs: number;
78
+ dayStartHour: number;
79
+ attributionRules: TimetrackAttributionRule[];
80
+ projectLinks: TimetrackProjectLinkRule[];
81
+ backgroundProjects: string[];
82
+ noWorkContextApps: string[];
83
+ holdsWorkApps: string[];
84
+ };
85
+ /**
86
+ * One name the user gave work that Jira does not hold yet.
87
+ *
88
+ * Nothing in this CLI opens or resolves a stand-in, because the name is the user's own word for their
89
+ * work and the app is where they give it. A delete is allowed: it takes a name away rather than
90
+ * putting one on the day.
91
+ */
92
+ export type TimetrackStandIn = {
93
+ id: string;
94
+ name: string;
95
+ projectKey?: string;
96
+ state: 'open' | 'resolved';
97
+ /** The issue it resolved to. Absent while it is open. */
98
+ issueKey?: string;
99
+ /** The local day keys that hold bands of it, oldest first. */
100
+ days: string[];
101
+ author: 'user' | 'agent';
102
+ createdAtMs: number;
103
+ /** The checkout the app opened it for. Absent on one the user opened by hand. */
104
+ openedFor?: string;
105
+ /**
106
+ * The branch of that checkout it covers. Absent on a record opened before the grain was the branch,
107
+ * which is why such a record covers the whole checkout and blocks every branch of it.
108
+ */
109
+ openedForBranch?: string;
110
+ /** The directory of that branch it covers, where the branch names no piece of work of its own. */
111
+ openedForWorkPath?: string;
112
+ };
113
+ /** One commit a split reads a directory out of: the day it counts toward, and its changed files. */
114
+ export type TimetrackWorkCommit = {
115
+ day: string;
116
+ paths: string[];
117
+ };
118
+ /** One directory a split names, with the days of the record that worked in it. */
119
+ export type TimetrackStandInPiece = {
120
+ workPath: string;
121
+ days: string[];
122
+ commits: number;
123
+ };
124
+ /** What a split would do, or did. `candidates` is every directory; `pieces` is what gets written. */
125
+ export type TimetrackStandInSplit = {
126
+ candidates: TimetrackStandInPiece[];
127
+ pieces: TimetrackStandInPiece[];
128
+ /** The days no piece claims, which the record being split keeps rather than the split refusing. */
129
+ remainder: string[];
130
+ standIns: TimetrackStandIn[];
131
+ };
132
+ /**
133
+ * What the checkout-wide naming offer says about one day, offers and refusals alike.
134
+ *
135
+ * A card the day screen never draws is the hardest thing to ask about, because every step that can
136
+ * stop it is invisible from the screen. `declines` names the step that stopped.
137
+ */
138
+ export type TimetrackNaming = {
139
+ day: string;
140
+ /** Whether a Tempo token is stored. Without one every checkout declines with `no-history`. */
141
+ tempoReady: boolean;
142
+ /** How far the read of the user's Tempo history got. */
143
+ history: 'loading' | 'no-token' | 'ready' | 'failed';
144
+ /** How many worklogs the span holds, whatever project they are in. */
145
+ historyWorklogs: number;
146
+ /** What the read failed with. Absent unless `history` is `failed`. */
147
+ historyMessage?: string;
148
+ offers: TimetrackNamingOffer[];
149
+ declines: TimetrackNamingDecline[];
150
+ };
151
+ export type TimetrackNamingOffer = {
152
+ repoPath: string;
153
+ projectKey: string;
154
+ issueKey: string;
155
+ summary: string;
156
+ days: number;
157
+ loggedMs: number;
158
+ /** How much of the project's logged time went to this one issue, from 0 to 1. */
159
+ share: number;
160
+ };
161
+ export type TimetrackNamingDecline = {
162
+ repoPath: string;
163
+ reason: 'already-named' | 'named-by-stand-in' | 'no-project-link' | 'no-history' | 'project-too-small' | 'too-few-days' | 'share-too-low';
164
+ projectKey?: string;
165
+ issueKey?: string;
166
+ days?: number;
167
+ loggedMs?: number;
168
+ projectMs?: number;
169
+ share?: number;
170
+ };
171
+ /** One day's evidence, straight out of the app's encrypted store. `events` is opaque here on purpose. */
172
+ export type TimetrackDayEvents = {
173
+ day: string;
174
+ fromMs: number;
175
+ toMs: number;
176
+ events: unknown[];
177
+ };
178
+ /** One transcribed stretch of the user's own microphone during a call. */
179
+ export type TimetrackTranscriptChunk = {
180
+ atMs: number;
181
+ callStartedAtMs: number;
182
+ appId: string;
183
+ model: string;
184
+ language: string | null;
185
+ text: string;
186
+ };
187
+ export type TimetrackTranscriptDay = {
188
+ day: string;
189
+ chunks: TimetrackTranscriptChunk[];
190
+ };
191
+ /** One row of a day as the app's own review drew it. Every edit names a row by this `id`. */
192
+ export type TimetrackRow = {
193
+ id: string;
194
+ issueKey?: string;
195
+ standInId?: string;
196
+ description: string;
197
+ fromMs: number;
198
+ toMs: number;
199
+ durationMs: number;
200
+ observedMs: number;
201
+ laneKey?: string;
202
+ state: string;
203
+ confidence: string;
204
+ edited: boolean;
205
+ hidden: boolean;
206
+ /** What `timetrackAskAutoMode` takes to ask about the row again. Absent where the app offers no ask. */
207
+ autoModeSubject?: TimetrackAutoModeSubject;
208
+ };
209
+ /** A day as the screen draws it: the rows, the ones taken off the timeline, and its totals. */
210
+ export type TimetrackDayRows = {
211
+ day: string;
212
+ rows: TimetrackRow[];
213
+ hidden: TimetrackRow[];
214
+ proposedMs: number;
215
+ loggedMs: number;
216
+ targetMs: number;
217
+ unattributedMs: number;
218
+ warnings: {
219
+ kind: string;
220
+ detail: string;
221
+ }[];
222
+ behind?: {
223
+ fromMs: number;
224
+ toMs: number;
225
+ issueKey: string;
226
+ laneKey: string;
227
+ durationMs: number;
228
+ }[];
229
+ };
230
+ /** One change to one row, named by the id `timetrackDayRows` answered. */
231
+ export type TimetrackRowEdit = {
232
+ kind: 'range';
233
+ rowId: string;
234
+ fromMs: number;
235
+ toMs: number;
236
+ } | {
237
+ kind: 'issue';
238
+ rowId: string;
239
+ issueKey: string;
240
+ } | {
241
+ kind: 'description';
242
+ rowId: string;
243
+ description: string;
244
+ } | {
245
+ kind: 'state';
246
+ rowId: string;
247
+ state: 'accepted' | 'rejected';
248
+ } | {
249
+ kind: 'hidden';
250
+ rowId: string;
251
+ hidden: boolean;
252
+ } | {
253
+ kind: 'reset';
254
+ rowId: string;
255
+ };
256
+ export type TimetrackEditedDay = TimetrackDayRows & {
257
+ applied: number;
258
+ };
259
+ export type TimetrackWorklog = {
260
+ day: string;
261
+ issueKey: string;
262
+ description: string;
263
+ fromMs: number;
264
+ toMs: number;
265
+ durationMs: number;
266
+ };
267
+ /** One of the user's own Tempo worklogs, whoever wrote it. */
268
+ export type TimetrackTempoWorklog = {
269
+ id: string;
270
+ day: string;
271
+ /** The local start as `HH:MM`. An app older than this CLI leaves it out for a worklog at midnight. */
272
+ startTime?: string;
273
+ startMs: number;
274
+ durationMs: number;
275
+ /** Absent where Jira no longer resolves the issue Tempo names. */
276
+ issueKey?: string;
277
+ issueId: string;
278
+ description: string;
279
+ };
280
+ export type TimetrackTempoWorklogs = {
281
+ from: string;
282
+ to: string;
283
+ worklogs: TimetrackTempoWorklog[];
284
+ };
285
+ export type TimetrackTempoDelete = {
286
+ deleted: {
287
+ id: string;
288
+ day: string;
289
+ startTime: string;
290
+ minutes: number;
291
+ issueKey?: string;
292
+ description: string;
293
+ };
294
+ /** Set when Tempo dropped the worklog but the app's ledger kept the entry that owned it. */
295
+ unrecorded?: string;
296
+ };
297
+ export type TimetrackTempoSyncWrite = {
298
+ kind: 'create' | 'update' | 'delete';
299
+ proposalId: string;
300
+ issueKey?: string;
301
+ fromMs: number;
302
+ durationMs: number;
303
+ description: string;
304
+ reason: string;
305
+ /** The worklog an update or a delete targets. */
306
+ tempoWorklogId?: string;
307
+ /** Why the row would be held back rather than sent. */
308
+ blocked?: string;
309
+ };
310
+ export type TimetrackTempoSyncRowResult = {
311
+ kind: 'create' | 'update' | 'delete';
312
+ proposalId: string;
313
+ status: 'written' | 'blocked' | 'skipped' | 'failed';
314
+ issueKey?: string;
315
+ tempoWorklogId?: string;
316
+ detail?: string;
317
+ };
318
+ /** What a sync of one day would write, and what a confirmed write did. */
319
+ export type TimetrackTempoSync = {
320
+ day: string;
321
+ /** Covers the write set only. A write must name it, and the app refuses one a fresh plan does not match. */
322
+ planHash: string;
323
+ writes: TimetrackTempoSyncWrite[];
324
+ unchanged: number;
325
+ skipped: number;
326
+ unresolvedKeys: string[];
327
+ foreign: {
328
+ id: string;
329
+ issueKey?: string;
330
+ issueId: string;
331
+ fromMs: number;
332
+ durationMs: number;
333
+ description: string;
334
+ }[];
335
+ coveredMs: number;
336
+ run?: {
337
+ rows: TimetrackTempoSyncRowResult[];
338
+ retryCount: number;
339
+ unrecorded?: string;
340
+ };
341
+ };
342
+ /** One entry of a calendar the app reads, all-day and declined ones included. */
343
+ export type TimetrackCalendarEvent = {
344
+ calendarId: string;
345
+ day: string;
346
+ startMs: number;
347
+ endMs: number;
348
+ allDay: boolean;
349
+ title: string;
350
+ /** Everyone invited except rooms, the user included. */
351
+ attendeeCount: number;
352
+ /** The user's own answer, or `organizer` where the entry has no attendee list. */
353
+ response: 'accepted' | 'declined' | 'tentative' | 'needsAction' | 'organizer' | 'unknown';
354
+ };
355
+ export type TimetrackCalendarEvents = {
356
+ from: string;
357
+ to: string;
358
+ calendarIds: string[];
359
+ events: TimetrackCalendarEvent[];
360
+ };
361
+ /**
362
+ * Where the app writes the port and the token, which is its data directory on each platform.
363
+ *
364
+ * `TIMETRACK_AGENT_DISCOVERY` names the file directly, for a machine whose app data lives somewhere
365
+ * else and for a test.
366
+ */
367
+ export declare const timetrackDiscoveryPath: () => string;
368
+ /**
369
+ * The name the approval queue shows for this caller: `TIMETRACK_CLIENT` when set, Claude Code when it
370
+ * runs this, and nothing otherwise.
371
+ */
372
+ export declare const timetrackClientName: () => string | undefined;
373
+ /**
374
+ * Asks the running Timetrack app to carry out one operation.
375
+ *
376
+ * It is the only way this package reaches Jira. The token lives in the app's keychain entry and in no
377
+ * repository, so a checkout an agent works in holds nothing worth stealing and nothing to rotate.
378
+ */
379
+ export declare const askTimetrack: <T>(request: Record<string, unknown> & {
380
+ op: string;
381
+ }) => Promise<T>;
382
+ export declare const timetrackStatus: () => Promise<TimetrackStatus>;
383
+ export declare const timetrackNaming: (day: string) => Promise<TimetrackNaming>;
384
+ export declare const timetrackInstance: () => Promise<TimetrackInstance>;
385
+ export declare const timetrackIssue: (key: string) => Promise<TimetrackIssue>;
386
+ export declare const timetrackSearch: (options: {
387
+ text?: string;
388
+ projectKey?: string;
389
+ assignedToMe?: boolean;
390
+ limit?: number;
391
+ }) => Promise<TimetrackIssue[]>;
392
+ export declare const timetrackRepoProject: (repoPath: string) => Promise<TimetrackRepoProject>;
393
+ /** Queues a new issue, filed with the app's own ticket settings once the user approves it. */
394
+ export declare const timetrackCreateIssue: (options: {
395
+ summary: string;
396
+ description?: string;
397
+ projectKey?: string;
398
+ issueTypeName?: string;
399
+ parentKey?: string;
400
+ subject?: string;
401
+ }) => Promise<TimetrackQueued>;
402
+ /** Queues a row for the day it belongs to. It is a row on the day once approved, not a Tempo entry. */
403
+ export declare const timetrackAddWorklog: (options: {
404
+ issueKey: string;
405
+ description?: string;
406
+ fromMs: number;
407
+ durationMs: number;
408
+ }) => Promise<TimetrackQueued>;
409
+ export declare const timetrackDayEvents: (day: string) => Promise<TimetrackDayEvents>;
410
+ export declare const timetrackTranscriptDay: (day: string) => Promise<TimetrackTranscriptDay>;
411
+ export declare const timetrackDayRows: (day: string) => Promise<TimetrackDayRows>;
412
+ /**
413
+ * Queues the stated edits to a day's rows. Once approved, the result is the day as it reads afterwards.
414
+ *
415
+ * `applied` in that result counts the edits that found their row: a day the collectors keep changing
416
+ * can drop a row a caller read a moment ago.
417
+ */
418
+ export declare const timetrackEditDay: (options: {
419
+ day: string;
420
+ edits: readonly TimetrackRowEdit[];
421
+ }) => Promise<TimetrackQueued>;
422
+ /** Reads the user's own Tempo worklogs from Tempo, both days included. The app caps the span at 92 days. */
423
+ export declare const timetrackTempoWorklogs: (options: {
424
+ from: string;
425
+ to: string;
426
+ }) => Promise<TimetrackTempoWorklogs>;
427
+ /**
428
+ * Plans a Tempo sync of one day exactly as the app's Sync page does. It writes nothing, so it is
429
+ * answered at once. The app moves its review to the day.
430
+ */
431
+ export declare const timetrackTempoSync: (day: string) => Promise<TimetrackTempoSync>;
432
+ /** Queues the write of the plan whose hash the user confirmed. The app checks the hash again on approval. */
433
+ export declare const timetrackTempoSyncWrite: (options: {
434
+ day: string;
435
+ planHash: string;
436
+ }) => Promise<TimetrackQueued>;
437
+ /**
438
+ * Queues the delete of one of the user's own Tempo worklogs. Once approved, the app refuses an id that
439
+ * is not among the account's own worklogs on `day`, and drops the ledger entry that owned it.
440
+ */
441
+ export declare const timetrackTempoDelete: (options: {
442
+ day: string;
443
+ worklogId: string;
444
+ }) => Promise<TimetrackQueued>;
445
+ /** Reads the calendars the app watches, both days included. The app caps the span at 92 days. */
446
+ export declare const timetrackCalendarEvents: (options: {
447
+ from: string;
448
+ to: string;
449
+ }) => Promise<TimetrackCalendarEvents>;
450
+ export declare const timetrackRules: () => Promise<TimetrackRules>;
451
+ /**
452
+ * Queues a read of the agent session logs under `paths` again, so sessions the app dropped while no
453
+ * project link held them are stored. Once approved, the read runs in the background.
454
+ *
455
+ * With `replace`, the re-read overwrites the samples, spend and prompts the store holds for those
456
+ * sessions, which is how a parser fix reaches days already stored.
457
+ */
458
+ export declare const timetrackResyncAgentSessions: (paths: readonly string[], options?: {
459
+ replace?: boolean;
460
+ }) => Promise<TimetrackQueued>;
461
+ export declare const timetrackStandIns: () => Promise<TimetrackStandIn[]>;
462
+ /**
463
+ * Queues the delete of one placeholder. Once approved, the result is the list as it reads afterwards.
464
+ *
465
+ * The rule pointing at it goes with it. A record the app opened for one branch refuses that branch as
466
+ * it goes, so no second one opens for it; a record naming no branch refuses nothing, and the next
467
+ * pass may open one at whatever grain the day reads.
468
+ */
469
+ export declare const timetrackRemoveStandIn: (id: string) => Promise<TimetrackQueued>;
470
+ /**
471
+ * Queues another name for one placeholder. Once approved, the result is the list as it reads afterwards.
472
+ *
473
+ * Only the name changes. The days it holds and the rules that name it stay, which is what a delete
474
+ * and a fresh record would lose.
475
+ */
476
+ export declare const timetrackRenameStandIn: (options: {
477
+ id: string;
478
+ name: string;
479
+ }) => Promise<TimetrackQueued>;
480
+ /**
481
+ * Queues the merge of one open placeholder into another. Once approved, the result is the list as it
482
+ * reads afterwards. The kept one takes the days and the rules of both.
483
+ */
484
+ export declare const timetrackMergeStandIn: (options: {
485
+ id: string;
486
+ into: string;
487
+ }) => Promise<TimetrackQueued>;
488
+ /**
489
+ * Queues the resolve of one placeholder to a Jira issue, as the user's pick in the app does. A resolved
490
+ * one moves to the new issue. The app checks both exist before it queues; once approved, the result is
491
+ * the list as it reads afterwards.
492
+ */
493
+ export declare const timetrackResolveStandIn: (options: {
494
+ id: string;
495
+ issueKey: string;
496
+ }) => Promise<TimetrackQueued>;
497
+ /**
498
+ * Plans the cut of one placeholder into one per directory it turned out to cover, and writes nothing.
499
+ *
500
+ * The commits come from the caller: one
501
+ * collected before Timetrack read file paths carries none, so only `git log --name-only` can say.
502
+ * A checkout whose commits name more directories than a grain can hold has no automatic reading,
503
+ * and `paths` is how the user picks which of them are the pieces.
504
+ */
505
+ export declare const timetrackSplitStandIn: (options: {
506
+ id: string;
507
+ branch: string;
508
+ commits: readonly TimetrackWorkCommit[];
509
+ /** The checkout the directories are in, for a record that names none of its own. */
510
+ repoPath?: string;
511
+ /** The projects the checkout declares, relative to it. They are the grain a piece is cut to. */
512
+ projectRoots: readonly string[];
513
+ /** The directories the user picked as the pieces. Empty lets the automatic reading answer. */
514
+ paths: readonly string[];
515
+ /** The directory that takes every day of the record no commit claims. */
516
+ claim?: string;
517
+ }) => Promise<TimetrackStandInSplit>;
518
+ /** Queues the split `timetrackSplitStandIn` planned, with the same options. */
519
+ export declare const timetrackApplyStandInSplit: (options: Parameters<typeof timetrackSplitStandIn>[0]) => Promise<TimetrackQueued>;
520
+ /** Where a write this caller queued stands, and what it answered once the user approved it. */
521
+ export declare const timetrackApprovalStatus: (id: string) => Promise<TimetrackApprovalStatus>;
522
+ /** One write that still waits in the app. `running` was approved and is being carried out. */
523
+ export type TimetrackWaitingApproval = {
524
+ approvalId: string;
525
+ state: 'queued' | 'running';
526
+ op: string;
527
+ client?: string;
528
+ askedAtMs: number;
529
+ summary: string;
530
+ };
531
+ /** The writes that wait in the app now, from every caller, in the order its queue panel lists them. */
532
+ export declare const timetrackApprovals: () => Promise<TimetrackWaitingApproval[]>;
533
+ /**
534
+ * Rejects one write that waits, as the user's Reject press does, and answers at once. The app refuses an
535
+ * item that no longer waits. There is no approving counterpart: only the user approves, in the app.
536
+ */
537
+ export declare const timetrackRejectApproval: (id: string) => Promise<TimetrackApprovalStatus>;
538
+ /** What an auto mode ask is about: an open stand-in, or the unnamed context behind a band. */
539
+ export type TimetrackAutoModeSubject = {
540
+ kind: 'stand-in';
541
+ standInId: string;
542
+ } | {
543
+ kind: 'context';
544
+ contextId: string;
545
+ };
546
+ /** What `timetrackAskAutoMode` queued. `asking` means an ask about it already waited or ran. */
547
+ export type TimetrackAutoModeAsk = {
548
+ status: 'queued' | 'asking';
549
+ day: string;
550
+ subject: TimetrackAutoModeSubject;
551
+ label: string;
552
+ };
553
+ /**
554
+ * Asks auto mode about one subject of a day again, as the app's "Ask auto mode again" does, and answers
555
+ * at once with what it queued. The new answer replaces the stored one later; it writes nothing to Jira or
556
+ * Tempo, and whatever it queues waits for the user's approval as auto mode's own does.
557
+ */
558
+ export declare const timetrackAskAutoMode: (options: {
559
+ day: string;
560
+ subject: TimetrackAutoModeSubject;
561
+ }) => Promise<TimetrackAutoModeAsk>;