@knpkv/jira-clockify 1.4.1 → 1.6.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 (147) hide show
  1. package/README.md +105 -22
  2. package/dist/package.json +1 -1
  3. package/dist/src/agent/schedule.d.ts +6 -5
  4. package/dist/src/agent/schedule.d.ts.map +1 -1
  5. package/dist/src/agent/schedule.js +117 -102
  6. package/dist/src/agent/schedule.js.map +1 -1
  7. package/dist/src/agent/sessions.d.ts +27 -33
  8. package/dist/src/agent/sessions.d.ts.map +1 -1
  9. package/dist/src/agent/sessions.js +121 -83
  10. package/dist/src/agent/sessions.js.map +1 -1
  11. package/dist/src/agent/writePlanning.d.ts +2 -0
  12. package/dist/src/agent/writePlanning.d.ts.map +1 -1
  13. package/dist/src/agent/writePlanning.js +4 -1
  14. package/dist/src/agent/writePlanning.js.map +1 -1
  15. package/dist/src/bin.js +16 -5
  16. package/dist/src/bin.js.map +1 -1
  17. package/dist/src/cli/CommandFailed.d.ts +27 -0
  18. package/dist/src/cli/CommandFailed.d.ts.map +1 -0
  19. package/dist/src/cli/CommandFailed.js +25 -0
  20. package/dist/src/cli/CommandFailed.js.map +1 -0
  21. package/dist/src/cli/agentWrite.d.ts.map +1 -1
  22. package/dist/src/cli/agentWrite.js +12 -5
  23. package/dist/src/cli/agentWrite.js.map +1 -1
  24. package/dist/src/cli/auth.d.ts +59 -2
  25. package/dist/src/cli/auth.d.ts.map +1 -1
  26. package/dist/src/cli/auth.js +151 -106
  27. package/dist/src/cli/auth.js.map +1 -1
  28. package/dist/src/cli/config.d.ts +4 -3
  29. package/dist/src/cli/config.d.ts.map +1 -1
  30. package/dist/src/cli/config.js +73 -31
  31. package/dist/src/cli/config.js.map +1 -1
  32. package/dist/src/cli/fetchTicket.d.ts +3 -3
  33. package/dist/src/cli/fetchTicket.d.ts.map +1 -1
  34. package/dist/src/cli/fetchTicket.js +7 -7
  35. package/dist/src/cli/fetchTicket.js.map +1 -1
  36. package/dist/src/cli/layers.d.ts +6 -5
  37. package/dist/src/cli/layers.d.ts.map +1 -1
  38. package/dist/src/cli/layers.js +16 -15
  39. package/dist/src/cli/layers.js.map +1 -1
  40. package/dist/src/cli/list.d.ts +3 -2
  41. package/dist/src/cli/list.d.ts.map +1 -1
  42. package/dist/src/cli/list.js +11 -5
  43. package/dist/src/cli/list.js.map +1 -1
  44. package/dist/src/cli/reconcile.d.ts +18 -3
  45. package/dist/src/cli/reconcile.d.ts.map +1 -1
  46. package/dist/src/cli/reconcile.js +73 -23
  47. package/dist/src/cli/reconcile.js.map +1 -1
  48. package/dist/src/cli/root.d.ts.map +1 -1
  49. package/dist/src/cli/root.js +3 -3
  50. package/dist/src/cli/root.js.map +1 -1
  51. package/dist/src/cli/setup.d.ts +14 -4
  52. package/dist/src/cli/setup.d.ts.map +1 -1
  53. package/dist/src/cli/setup.js +45 -94
  54. package/dist/src/cli/setup.js.map +1 -1
  55. package/dist/src/cli/timer/discard.d.ts +1 -1
  56. package/dist/src/cli/timer/discard.d.ts.map +1 -1
  57. package/dist/src/cli/timer/discard.js +2 -1
  58. package/dist/src/cli/timer/discard.js.map +1 -1
  59. package/dist/src/cli/timer/log.d.ts +1 -1
  60. package/dist/src/cli/timer/log.d.ts.map +1 -1
  61. package/dist/src/cli/timer/log.js +2 -1
  62. package/dist/src/cli/timer/log.js.map +1 -1
  63. package/dist/src/cli/timer/start.d.ts +2 -1
  64. package/dist/src/cli/timer/start.d.ts.map +1 -1
  65. package/dist/src/cli/timer/start.js +6 -8
  66. package/dist/src/cli/timer/start.js.map +1 -1
  67. package/dist/src/cli/timer/stop.d.ts +1 -1
  68. package/dist/src/cli/timer/stop.d.ts.map +1 -1
  69. package/dist/src/cli/timer.d.ts.map +1 -1
  70. package/dist/src/cli/timer.js +8 -1
  71. package/dist/src/cli/timer.js.map +1 -1
  72. package/dist/src/cli/unknownCommand.d.ts +24 -0
  73. package/dist/src/cli/unknownCommand.d.ts.map +1 -0
  74. package/dist/src/cli/unknownCommand.js +84 -0
  75. package/dist/src/cli/unknownCommand.js.map +1 -0
  76. package/dist/src/cli/watch.d.ts +2 -2
  77. package/dist/src/cli/watch.d.ts.map +1 -1
  78. package/dist/src/services/AgentSessionReader.d.ts +26 -12
  79. package/dist/src/services/AgentSessionReader.d.ts.map +1 -1
  80. package/dist/src/services/AgentSessionReader.js +163 -69
  81. package/dist/src/services/AgentSessionReader.js.map +1 -1
  82. package/dist/src/services/CodexTranscript.d.ts +50 -13
  83. package/dist/src/services/CodexTranscript.d.ts.map +1 -1
  84. package/dist/src/services/CodexTranscript.js +49 -13
  85. package/dist/src/services/CodexTranscript.js.map +1 -1
  86. package/dist/src/services/ConfigService.d.ts +4 -0
  87. package/dist/src/services/ConfigService.d.ts.map +1 -1
  88. package/dist/src/services/ConfigService.js +6 -2
  89. package/dist/src/services/ConfigService.js.map +1 -1
  90. package/dist/src/services/IssueFacts.d.ts +2 -2
  91. package/dist/src/services/IssueFacts.d.ts.map +1 -1
  92. package/dist/src/services/IssueFacts.js +5 -5
  93. package/dist/src/services/IssueFacts.js.map +1 -1
  94. package/dist/src/services/JiraAccess.d.ts +140 -0
  95. package/dist/src/services/JiraAccess.d.ts.map +1 -0
  96. package/dist/src/services/JiraAccess.js +204 -0
  97. package/dist/src/services/JiraAccess.js.map +1 -0
  98. package/dist/src/services/ProviderSnapshots.d.ts +41 -0
  99. package/dist/src/services/ProviderSnapshots.d.ts.map +1 -0
  100. package/dist/src/services/ProviderSnapshots.js +71 -0
  101. package/dist/src/services/ProviderSnapshots.js.map +1 -0
  102. package/dist/src/services/ReconcileService.d.ts +12 -4
  103. package/dist/src/services/ReconcileService.d.ts.map +1 -1
  104. package/dist/src/services/ReconcileService.js +223 -113
  105. package/dist/src/services/ReconcileService.js.map +1 -1
  106. package/dist/src/services/SavedEntries.d.ts +24 -4
  107. package/dist/src/services/SavedEntries.d.ts.map +1 -1
  108. package/dist/src/services/SavedEntries.js +335 -19
  109. package/dist/src/services/SavedEntries.js.map +1 -1
  110. package/dist/src/services/SessionAttributor.d.ts +12 -0
  111. package/dist/src/services/SessionAttributor.d.ts.map +1 -1
  112. package/dist/src/services/SessionAttributor.js +13 -1
  113. package/dist/src/services/SessionAttributor.js.map +1 -1
  114. package/dist/src/services/SessionLine.d.ts +29 -0
  115. package/dist/src/services/SessionLine.d.ts.map +1 -0
  116. package/dist/src/services/SessionLine.js +8 -0
  117. package/dist/src/services/SessionLine.js.map +1 -0
  118. package/dist/src/services/SourceLedger.d.ts +84 -1
  119. package/dist/src/services/SourceLedger.d.ts.map +1 -1
  120. package/dist/src/services/SourceLedger.js +178 -12
  121. package/dist/src/services/SourceLedger.js.map +1 -1
  122. package/dist/src/services/TicketRanking.d.ts +39 -0
  123. package/dist/src/services/TicketRanking.d.ts.map +1 -0
  124. package/dist/src/services/TicketRanking.js +87 -0
  125. package/dist/src/services/TicketRanking.js.map +1 -0
  126. package/dist/src/services/TimerService.d.ts +3 -3
  127. package/dist/src/services/TimerService.d.ts.map +1 -1
  128. package/dist/src/services/TimerService.js +6 -17
  129. package/dist/src/services/TimerService.js.map +1 -1
  130. package/dist/src/services/internal/retryTransport.d.ts +9 -0
  131. package/dist/src/services/internal/retryTransport.d.ts.map +1 -0
  132. package/dist/src/services/internal/retryTransport.js +15 -0
  133. package/dist/src/services/internal/retryTransport.js.map +1 -0
  134. package/dist/src/testing/fakeHeadless.d.ts +12 -1
  135. package/dist/src/testing/fakeHeadless.d.ts.map +1 -1
  136. package/dist/src/testing/fakeHeadless.js +83 -10
  137. package/dist/src/testing/fakeHeadless.js.map +1 -1
  138. package/dist/src/tui/App.js +1 -1
  139. package/dist/src/tui/atoms/runtime.d.ts +1 -1
  140. package/dist/src/tui/atoms/runtime.d.ts.map +1 -1
  141. package/dist/src/utils/hints.d.ts +4 -2
  142. package/dist/src/utils/hints.d.ts.map +1 -1
  143. package/dist/src/utils/hints.js +4 -2
  144. package/dist/src/utils/hints.js.map +1 -1
  145. package/dist/tsconfig.tsbuildinfo +1 -1
  146. package/package.json +8 -8
  147. package/skills/jcf/SKILL.md +9 -6
@@ -10,11 +10,25 @@ import { Command, Flag as Options, Prompt } from "effect/cli";
10
10
  import * as HttpClient from "effect/http/HttpClient";
11
11
  import * as ChildProcess from "effect/process/ChildProcess";
12
12
  import { ClockifyAuth } from "../services/ClockifyAuth.js";
13
- class InvalidClockifyApiKeyError extends Data.TaggedError("InvalidClockifyApiKeyError") {
13
+ import { JiraAccess } from "../services/JiraAccess.js";
14
+ import { CONNECT_JIRA_COMMAND } from "../utils/hints.js";
15
+ import { CommandFailed, requireTerminal, toCommandFailed } from "./CommandFailed.js";
16
+ export class InvalidClockifyApiKeyError extends Data.TaggedError("InvalidClockifyApiKeyError") {
14
17
  get message() {
15
18
  return "Invalid API key — check the value and try again";
16
19
  }
17
20
  }
21
+ /**
22
+ * A Clockify request failed for a reason other than the key: the network, an unexpected status, or a
23
+ * response this client cannot decode. Names the operation, so a decode mismatch is not mistaken for
24
+ * a missing workspace or a bad key.
25
+ */
26
+ export class ClockifyRequestError extends Data.TaggedError("ClockifyRequestError") {
27
+ get message() {
28
+ const reason = Predicate.hasProperty(this.cause, "message") ? String(this.cause.message) : String(this.cause);
29
+ return `Clockify ${this.operation} failed: ${reason}`;
30
+ }
31
+ }
18
32
  const ClockifyUser = Schema.Struct({
19
33
  id: Schema.String,
20
34
  name: Schema.optional(Schema.String),
@@ -26,13 +40,54 @@ const ClockifyWorkspace = Schema.Struct({
26
40
  });
27
41
  const decodeClockifyUser = Schema.decodeUnknownEffect(ClockifyUser);
28
42
  const decodeClockifyWorkspaces = Schema.decodeUnknownEffect(Schema.Array(ClockifyWorkspace));
29
- const emptyWorkspaces = () => [];
43
+ /** Only Clockify's own rejection of the key means the key is wrong. */
44
+ const isRejectedKey = (error) => error._tag === "HttpClientError" && (error.response?.status === 401 || error.response?.status === 403);
45
+ /**
46
+ * The account behind an API key: who it is and which workspaces it can use. An empty list is a real
47
+ * answer; any failure is typed, so setup never reports "no workspaces" for a request that failed.
48
+ */
49
+ export const loadClockifyAccount = Effect.fn("ClockifyAuth.loadClockifyAccount")(function* (client) {
50
+ const user = yield* client.getLoggedUser(undefined).pipe(Effect.flatMap(decodeClockifyUser), Effect.mapError((cause) => isRejectedKey(cause)
51
+ ? new InvalidClockifyApiKeyError()
52
+ : new ClockifyRequestError({ operation: "getLoggedUser", cause })));
53
+ const workspaces = yield* client.getWorkspacesOfUser(undefined).pipe(Effect.flatMap(decodeClockifyWorkspaces), Effect.mapError((cause) => isRejectedKey(cause)
54
+ ? new InvalidClockifyApiKeyError()
55
+ : new ClockifyRequestError({ operation: "getWorkspacesOfUser", cause })));
56
+ return { user, workspaces };
57
+ });
30
58
  // ---------------------------------------------------------------------------
31
- // Jira OAuth
59
+ // Jira
32
60
  // ---------------------------------------------------------------------------
61
+ const apiTokenPage = "https://id.atlassian.com/manage-profile/security/api-tokens";
62
+ /**
63
+ * Asks for a site, email and API token, checks them against Jira and saves them. The token is read
64
+ * without echo and never printed; a failed check names its cause and saves nothing.
65
+ */
66
+ export const connectJiraWithToken = (given) => Effect.gen(function* () {
67
+ const access = yield* JiraAccess;
68
+ yield* requireTerminal(`Run ${CONNECT_JIRA_COMMAND} in a terminal to enter the API token.`);
69
+ yield* Console.log(`Create an API token at ${apiTokenPage}, then paste it here.`);
70
+ const site = Option.isSome(given.site)
71
+ ? given.site.value
72
+ : yield* Prompt.String({ message: "Jira address (your-team.atlassian.net):" });
73
+ const email = Option.isSome(given.email)
74
+ ? given.email.value
75
+ : yield* Prompt.String({ message: "Email you sign in to Atlassian with:" });
76
+ const apiToken = yield* Prompt.Password({ message: "API token:" });
77
+ yield* Console.log("Checking with Jira...");
78
+ const verified = yield* access.verifyToken({ site, email, apiToken });
79
+ yield* access.saveToken(verified);
80
+ yield* Console.log(`Jira connected: ${verified.displayName} on ${verified.siteUrl}.`);
81
+ return verified;
82
+ }).pipe(Effect.catchTag("QuitError", () => Effect.fail(new CommandFailed({ message: "Jira was not connected." }))), Effect.mapError(toCommandFailed));
83
+ const jiraToken = Command.make("token", {
84
+ site: Options.String("site").pipe(Options.withDescription("Your Jira address, such as your-team.atlassian.net"), Options.optional),
85
+ email: Options.String("email").pipe(Options.withDescription("The email you sign in to Atlassian with"), Options.optional)
86
+ }, (given) => Effect.asVoid(connectJiraWithToken(given))).pipe(Command.withDescription("Connect Jira with an API token (recommended)"));
33
87
  const jiraCreate = Command.make("create", {}, () => Effect.gen(function* () {
34
88
  yield* Console.log(`
35
- Create OAuth app in Atlassian Developer Console:
89
+ Advanced: connect Jira through your own Atlassian OAuth app.
90
+ For most people ${CONNECT_JIRA_COMMAND} is simpler.
36
91
 
37
92
  1. Browser will open to create a new OAuth 2.0 (3LO) app
38
93
  2. Enter app name (e.g., "jcf")
@@ -49,12 +104,15 @@ Create OAuth app in Atlassian Developer Console:
49
104
  const url = "https://developer.atlassian.com/console/myapps/create-3lo-app/";
50
105
  const exitCode = (command) => Effect.scoped(command.pipe(Effect.flatMap((handle) => handle.exitCode)));
51
106
  yield* exitCode(ChildProcess.make("open", [url])).pipe(Effect.catch(() => exitCode(ChildProcess.make("xdg-open", [url]))), Effect.catch(() => exitCode(ChildProcess.make("rundll32.exe", ["url.dll,FileProtocolHandler", url]))), Effect.asVoid, Effect.catch(() => Effect.void));
52
- }));
107
+ })).pipe(Command.withDescription("Advanced: open the Atlassian console to create your own OAuth app"));
53
108
  const jiraConfigure = Command.make("configure", {
54
109
  clientId: Options.String("client-id").pipe(Options.withDescription("OAuth client ID"), Options.optional),
55
110
  clientSecret: Options.String("client-secret").pipe(Options.withDescription("OAuth client secret"), Options.optional)
56
111
  }, ({ clientId, clientSecret }) => Effect.gen(function* () {
57
112
  const auth = yield* JiraAuth;
113
+ if (Option.isNone(clientId) || Option.isNone(clientSecret)) {
114
+ yield* requireTerminal("Pass --client-id and --client-secret.");
115
+ }
58
116
  const id = Option.isSome(clientId)
59
117
  ? clientId.value
60
118
  : yield* Prompt.String({ message: "Enter OAuth client ID:" });
@@ -63,127 +121,114 @@ const jiraConfigure = Command.make("configure", {
63
121
  : yield* Prompt.String({ message: "Enter OAuth client secret:" });
64
122
  yield* auth.configure({ clientId: id, clientSecret: secret });
65
123
  yield* Console.log("OAuth configured. Run: jcf auth jira login");
66
- }));
124
+ }).pipe(Effect.mapError(toCommandFailed))).pipe(Command.withDescription("Advanced: store your OAuth app's client ID and secret"));
67
125
  const jiraLogin = Command.make("login", { site: Options.String("site").pipe(Options.withDescription("Jira site URL"), Options.optional) }, ({ site }) => Effect.gen(function* () {
68
126
  const auth = yield* JiraAuth;
127
+ if (!(yield* auth.isConfigured())) {
128
+ return yield* new CommandFailed({
129
+ message: `No OAuth app is configured. Run ${CONNECT_JIRA_COMMAND} to use an API token instead, ` +
130
+ "or jcf auth jira configure to set up your own OAuth app."
131
+ });
132
+ }
69
133
  const result = yield* auth.login(Option.isSome(site) ? { siteUrl: site.value } : undefined);
70
134
  if (Array.isArray(result) && result.length > 0) {
71
135
  yield* Console.log("\nRe-run with --site <url> to select a specific site.");
72
136
  }
73
- }).pipe(Effect.catch((e) => Console.log(`Error: ${Predicate.hasProperty(e, "message") ? String(e.message) : String(e)}`))));
137
+ }).pipe(Effect.mapError(toCommandFailed))).pipe(Command.withDescription("Advanced: sign in through your OAuth app in the browser"));
74
138
  const jiraLogout = Command.make("logout", {}, () => Effect.gen(function* () {
139
+ const access = yield* JiraAccess;
75
140
  const auth = yield* JiraAuth;
76
- yield* auth.logout();
77
- yield* Console.log("Logged out from Jira");
78
- }).pipe(Effect.catch((e) => Console.log(`Error: ${Predicate.hasProperty(e, "message") ? String(e.message) : String(e)}`))));
79
- const jiraStatus = Command.make("status", {}, () => Effect.gen(function* () {
80
- const auth = yield* JiraAuth;
81
- const user = yield* auth.getCurrentUser();
82
- if (user) {
83
- yield* Console.log(`Jira: ✓ logged in as ${user.name} (${user.email})`);
84
- }
85
- else {
86
- yield* Console.log("Jira: ✗ not logged in");
87
- yield* Console.log(" Run: jcf auth jira create → configure → login");
88
- }
89
- }).pipe(Effect.catch(() => Console.log("Jira: ✗ not configured"))));
90
- const authJira = Command.make("jira", {}, () => Console.log("Jira auth: create, configure, login, logout, status"))
91
- .pipe(Command.withSubcommands([jiraCreate, jiraConfigure, jiraLogin, jiraLogout, jiraStatus]));
141
+ const removedToken = yield* access.removeToken;
142
+ const oauth = yield* auth.isLoggedIn();
143
+ if (oauth)
144
+ yield* auth.logout();
145
+ yield* Console.log(removedToken || oauth ? "Jira disconnected." : "Jira was not connected.");
146
+ }).pipe(Effect.mapError(toCommandFailed))).pipe(Command.withDescription("Disconnect Jira: remove the API token and sign out of OAuth"));
147
+ /** One line saying how Jira is connected, or what to run when it is not. */
148
+ const jiraStatusLine = JiraAccess.use((access) => access.connection).pipe(Effect.map(Option.match({
149
+ onNone: () => `Jira: not connected. Run ${CONNECT_JIRA_COMMAND}`,
150
+ onSome: (connection) => `Jira: connected as ${connection.displayName === "" ? "unknown user" : connection.displayName} on ` +
151
+ `${connection.siteUrl} (${connection.method === "api-token" ? "API token" : "OAuth app"})`
152
+ })), Effect.catch((error) => Effect.succeed(`Jira: ${error.message}`)));
153
+ const jiraStatus = Command.make("status", {}, () => Effect.flatMap(jiraStatusLine, Console.log)).pipe(Command.withDescription("Show whether Jira is connected, and how"));
154
+ const authJira = Command.make("jira", {}, () => Console.log(`Connect Jira: ${CONNECT_JIRA_COMMAND}. Run jcf auth jira --help for every option.`)).pipe(Command.withDescription("Connect Jira with an API token, or with your own OAuth app (advanced)"), Command.withSubcommands([jiraToken, jiraStatus, jiraLogout, jiraCreate, jiraConfigure, jiraLogin]));
92
155
  // ---------------------------------------------------------------------------
93
156
  // Clockify API key
94
157
  // ---------------------------------------------------------------------------
95
- export const clockifySetup = Command.make("setup", {}, () => Effect.gen(function* () {
158
+ const clockifyBaseUrl = "https://api.clockify.me/api";
159
+ /**
160
+ * Asks for a Clockify API key (unless given), checks it, picks a workspace and saves it. A key that
161
+ * Clockify refuses, a failed request and an account with no workspace each fail with their own line.
162
+ */
163
+ export const connectClockify = (given, workspaceName = Option.none()) => Effect.gen(function* () {
96
164
  const auth = yield* ClockifyAuth;
97
- yield* Console.log("Clockify API Key Setup");
98
- yield* Console.log("Get your API key from: https://app.clockify.me/manage-api-keys");
99
- yield* Console.log("");
100
- const apiKey = yield* Prompt.String({ message: "Enter API key:" });
101
- if (!apiKey) {
102
- yield* Console.log("No API key provided, aborting.");
103
- return;
165
+ if (Option.isNone(given)) {
166
+ yield* requireTerminal("Pass the key with --api-key, or run jcf auth clockify setup in a terminal.");
167
+ yield* Console.log("Get your API key from https://app.clockify.me/manage-api-keys");
104
168
  }
105
- yield* Console.log("Validating...");
106
- const httpClient = yield* HttpClient.HttpClient;
107
- const client = makeClockifyApi(httpClient, {
108
- apiKey: Redacted.make(apiKey),
109
- baseUrl: "https://api.clockify.me/api"
110
- });
111
- const user = yield* client.getLoggedUser(undefined).pipe(Effect.flatMap(decodeClockifyUser), Effect.catch(() => Effect.fail(new InvalidClockifyApiKeyError())));
112
- yield* Console.log(`Authenticated as: ${user.name} (${user.email})`);
113
- const workspaces = yield* client.getWorkspacesOfUser(undefined).pipe(Effect.flatMap(decodeClockifyWorkspaces), Effect.catch(() => Effect.succeed(emptyWorkspaces())));
114
- if (workspaces.length === 0) {
115
- yield* Console.log("No workspaces found.");
116
- return;
169
+ const apiKey = Option.isSome(given)
170
+ ? given.value
171
+ : Redacted.value(yield* Prompt.Password({ message: "Clockify API key:" }));
172
+ if (apiKey.trim() === "") {
173
+ return yield* new CommandFailed({ message: "No API key given; Clockify was not connected." });
117
174
  }
118
- yield* Console.log("");
119
- yield* Console.log("Workspaces:");
120
- for (let i = 0; i < workspaces.length; i++) {
121
- const workspace = workspaces[i];
122
- if (workspace !== undefined) {
123
- yield* Console.log(` ${i + 1}. ${workspace.name}`);
124
- }
175
+ yield* Console.log("Checking with Clockify...");
176
+ const httpClient = yield* HttpClient.HttpClient;
177
+ const client = makeClockifyApi(httpClient, { apiKey: Redacted.make(apiKey), baseUrl: clockifyBaseUrl });
178
+ const { user, workspaces } = yield* loadClockifyAccount(client);
179
+ const [first] = workspaces;
180
+ if (first === undefined) {
181
+ return yield* new CommandFailed({
182
+ message: "This Clockify account has no workspace. Create one at https://app.clockify.me, then run this again."
183
+ });
125
184
  }
126
- let selectedIdx = 0;
127
- if (workspaces.length > 1) {
128
- const choice = yield* Prompt.String({ message: `Select workspace (1-${workspaces.length}):` });
129
- selectedIdx = Math.max(0, Math.min(workspaces.length - 1, parseInt(choice, 10) - 1));
185
+ const names = workspaces.map((candidate) => candidate.name).join(", ");
186
+ const workspace = Option.isSome(workspaceName)
187
+ ? workspaces.find((candidate) => candidate.name === workspaceName.value || candidate.id === workspaceName.value)
188
+ : workspaces.length === 1
189
+ ? first
190
+ : yield* requireTerminal(`This key can use ${workspaces.length} workspaces; pass --workspace with one of: ${names}.`)
191
+ .pipe(Effect.andThen(Prompt.Select({
192
+ message: "Workspace:",
193
+ choices: workspaces.map((candidate) => ({ title: candidate.name, value: candidate }))
194
+ })));
195
+ if (workspace === undefined) {
196
+ return yield* new CommandFailed({
197
+ message: `No workspace named "${Option.getOrElse(workspaceName, () => "")}" for this key. Its workspaces: ${names}.`
198
+ });
130
199
  }
131
- const workspace = workspaces[selectedIdx];
132
- yield* Console.log(`Selected: ${workspace.name}`);
133
- yield* auth.save({
134
- apiKey,
135
- workspaceId: workspace.id,
136
- userId: user.id,
137
- baseUrl: "https://api.clockify.me/api"
138
- });
139
- yield* Console.log("");
140
- yield* Console.log("Clockify configured! Saved to ~/.jcf/clockify.json");
141
- }).pipe(Effect.catch((e) => Console.log(`Error: ${Predicate.hasProperty(e, "message") ? String(e.message) : String(e)}`))));
142
- const clockifyStatus = Command.make("status", {}, () => Effect.gen(function* () {
200
+ yield* auth.save({ apiKey, workspaceId: workspace.id, userId: user.id, baseUrl: clockifyBaseUrl });
201
+ yield* Console.log(`Clockify connected: ${user.name ?? user.email ?? user.id}, workspace ${workspace.name}.`);
202
+ }).pipe(Effect.catchTag("QuitError", () => Effect.fail(new CommandFailed({ message: "Clockify was not connected." }))), Effect.mapError(toCommandFailed));
203
+ export const clockifySetup = Command.make("setup", {
204
+ apiKey: Options.String("api-key").pipe(Options.withDescription("Clockify API key, for scripts; without it the key is asked for and not echoed"), Options.optional),
205
+ workspace: Options.String("workspace").pipe(Options.withDescription("Workspace name or id, when the key can use more than one"), Options.optional)
206
+ }, ({ apiKey, workspace }) => connectClockify(apiKey, workspace)).pipe(Command.withDescription("Connect Clockify with an API key"));
207
+ /** One line saying which Clockify workspace is connected, or what to run when none is. */
208
+ const clockifyStatusLine = Effect.gen(function* () {
143
209
  const auth = yield* ClockifyAuth;
144
- const configured = yield* auth.isConfigured;
145
- if (!configured) {
146
- yield* Console.log("Clockify: ✗ not configured");
147
- yield* Console.log(" Run: jcf auth clockify setup");
148
- return;
210
+ if (!(yield* auth.isConfigured))
211
+ return "Clockify: not connected. Run jcf auth clockify setup";
212
+ const config = yield* auth.getConfig;
213
+ const httpClient = yield* HttpClient.HttpClient;
214
+ const account = yield* Effect.result(loadClockifyAccount(makeClockifyApi(httpClient, config)));
215
+ if (account._tag === "Failure") {
216
+ return `Clockify: connected, workspace ${config.workspaceId} (could not read its name: ${account.failure.message})`;
149
217
  }
150
- const config = yield* auth.getConfig.pipe(Effect.catch((e) => Console.log(`Clockify: error — ${e.message}`).pipe(Effect.flatMap(() => Effect.fail(e)))));
151
- yield* Console.log("Clockify: ✓ authenticated");
152
- yield* Console.log(` Workspace: ${config.workspaceId}`);
153
- yield* Console.log(` User: ${config.userId}`);
154
- }).pipe(Effect.catch(() => Effect.void)));
155
- const authClockify = Command.make("clockify", {}, () => Console.log("Clockify auth: setup, status")).pipe(Command.withSubcommands([clockifySetup, clockifyStatus]));
218
+ const name = account.success.workspaces.find((workspace) => workspace.id === config.workspaceId)?.name;
219
+ return `Clockify: connected, workspace ${name ?? `${config.workspaceId}, which this key can no longer see`}`;
220
+ }).pipe(Effect.catch((error) => Effect.succeed(`Clockify: ${error.message}. Run jcf auth clockify setup`)));
221
+ const clockifyStatus = Command.make("status", {}, () => Effect.flatMap(clockifyStatusLine, Console.log)).pipe(Command.withDescription("Show whether Clockify is connected, and to which workspace"));
222
+ const authClockify = Command.make("clockify", {}, () => Console.log("Connect Clockify: jcf auth clockify setup. Run jcf auth clockify --help for every option.")).pipe(Command.withDescription("Connect Clockify with an API key"), Command.withSubcommands([clockifySetup, clockifyStatus]));
156
223
  // ---------------------------------------------------------------------------
157
224
  // Combined status
158
225
  // ---------------------------------------------------------------------------
159
- const authStatus = Command.make("status", {}, () => Effect.gen(function* () {
160
- yield* Console.log("=== Auth Status ===");
161
- yield* Console.log("");
162
- // Jira
163
- const jira = yield* JiraAuth;
164
- const jiraUser = yield* jira.getCurrentUser().pipe(Effect.catch(() => Effect.succeed(null)));
165
- if (jiraUser) {
166
- yield* Console.log(`Jira: ✓ ${jiraUser.name} (${jiraUser.email})`);
167
- }
168
- else {
169
- yield* Console.log("Jira: ✗ not logged in");
170
- }
171
- // Clockify
172
- const clockifyAuth = yield* ClockifyAuth;
173
- const clockifyOk = yield* clockifyAuth.isConfigured;
174
- if (clockifyOk) {
175
- const cfg = yield* clockifyAuth.getConfig.pipe(Effect.catch(() => Effect.succeed(null)));
176
- if (cfg) {
177
- yield* Console.log(`Clockify: ✓ workspace ${cfg.workspaceId}`);
178
- }
179
- else {
180
- yield* Console.log("Clockify: ✗ config corrupt");
181
- }
182
- }
183
- else {
184
- yield* Console.log("Clockify: ✗ not configured");
185
- }
186
- }));
226
+ /** Both systems' status lines, Jira first. */
227
+ export const printAuthStatus = Effect.gen(function* () {
228
+ yield* Console.log(yield* jiraStatusLine);
229
+ yield* Console.log(yield* clockifyStatusLine);
230
+ });
231
+ const authStatus = Command.make("status", {}, () => printAuthStatus).pipe(Command.withDescription("Show whether Jira and Clockify are connected"));
187
232
  /** Top-level `auth` command with jira/clockify/status subcommands. */
188
- export const auth = Command.make("auth", {}, () => Console.log("Auth: jira, clockify, status")).pipe(Command.withSubcommands([authJira, authClockify, authStatus]));
233
+ export const auth = Command.make("auth", {}, () => printAuthStatus).pipe(Command.withDescription("Connect Jira and Clockify, and see which are connected"), Command.withSubcommands([authJira, authClockify, authStatus]));
189
234
  //# sourceMappingURL=auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/cli/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/cli/auth.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Config commands: show, set (project/billable/jql), reset.
2
+ * Config commands: show, set, unset and reset.
3
3
  *
4
4
  * @module
5
5
  */
@@ -7,6 +7,7 @@ import { ClockifyApiClient } from "@knpkv/clockify-api-client";
7
7
  import { Command, Prompt } from "effect/cli";
8
8
  import { ClockifyAuth } from "../services/ClockifyAuth.js";
9
9
  import { ConfigService } from "../services/ConfigService.js";
10
- /** Top-level `config` command with show/set/reset subcommands. */
11
- export declare const config: Command.Command<"config", {} | {}, {}, import("effect/Terminal").QuitError, ClockifyApiClient | ClockifyAuth | ConfigService | Prompt.Environment>;
10
+ import { CommandFailed } from "./CommandFailed.js";
11
+ /** Top-level `config` command with show/set/unset/reset subcommands. */
12
+ export declare const config: Command.Command<"config", {} | {}, {}, CommandFailed | import("effect/Terminal").QuitError, ClockifyApiClient | ClockifyAuth | ConfigService | Prompt.Environment>;
12
13
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/cli/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAE9D,OAAO,EAAoB,OAAO,EAAmB,MAAM,EAAE,MAAM,YAAY,CAAA;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAoC,MAAM,8BAA8B,CAAA;AAqV9F,kEAAkE;AAClE,eAAO,MAAM,MAAM,oJAUlB,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/cli/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAE9D,OAAO,EAAoB,OAAO,EAAmB,MAAM,EAAE,MAAM,YAAY,CAAA;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAoC,MAAM,8BAA8B,CAAA;AAC9F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAuZlD,wEAAwE;AACxE,eAAO,MAAM,MAAM,oKAgBlB,CAAA"}
@@ -1,33 +1,46 @@
1
1
  /**
2
- * Config commands: show, set (project/billable/jql), reset.
2
+ * Config commands: show, set, unset and reset.
3
3
  *
4
4
  * @module
5
5
  */
6
6
  import { ClockifyApiClient } from "@knpkv/clockify-api-client";
7
- import { Console, Effect } from "effect";
7
+ import { Console, Effect, Path } from "effect";
8
8
  import { Argument as Args, Command, Flag as Options, Prompt } from "effect/cli";
9
9
  import { isTicketKey } from "../agent/sessions.js";
10
10
  import { ClockifyAuth } from "../services/ClockifyAuth.js";
11
11
  import { ConfigService, defaultJcfConfig } from "../services/ConfigService.js";
12
+ import { CommandFailed } from "./CommandFailed.js";
12
13
  // ---------------------------------------------------------------------------
13
14
  // show
14
15
  // ---------------------------------------------------------------------------
15
- /** One printer so `jcf config` and `jcf config show` cannot drift apart. */
16
+ /**
17
+ * One printer so `jcf config` and `jcf config show` cannot drift apart. It says whether the file exists,
18
+ * and marks each value that is jcf's own default, so a reader can tell what was chosen from what was not.
19
+ */
16
20
  const printConfig = (config) => Effect.gen(function* () {
17
- yield* Console.log("~/.jcf/config.json:");
21
+ const cfg = yield* ConfigService;
22
+ const path = yield* Path.Path;
23
+ const file = path.join(yield* cfg.configDir, "config.json");
24
+ const exists = yield* cfg.fileExists;
25
+ yield* Console.log(exists
26
+ ? `Settings in ${file}. "(default)" marks a value that is jcf's own.`
27
+ : `No config file yet (${file}): every value below is jcf's default. Change one with jcf config set.`);
18
28
  yield* Console.log("");
19
- yield* Console.log(` Default JQL: ${config.defaultJql}`);
20
- yield* Console.log(` Refresh (sec): ${config.refreshInterval}`);
21
- yield* Console.log(` Default project: ${config.defaultProjectName ?? config.defaultProjectId ?? "(none)"}`);
22
- yield* Console.log(` Default billable:${config.defaultBillable ? " yes" : " no"}`);
23
- yield* Console.log(` Project map: ${JSON.stringify(config.projectMap)}`);
24
- yield* Console.log(` Session roots: ${config.sessionRoots.length > 0 ? config.sessionRoots.join(", ") : "(none)"}`);
25
- yield* Console.log(` Session tickets: ${JSON.stringify(config.sessionTicketMap)}`);
26
- yield* Console.log(` Idle cap (sec): ${config.sessionIdleCapSeconds}`);
27
- yield* Console.log(` Dwell (sec): ${config.sessionDwellSeconds === 0 ? "off" : config.sessionDwellSeconds}`);
28
- yield* Console.log(` Confidence floor:${` ${config.sessionConfidenceFloor}`}`);
29
- yield* Console.log(` Ownership: ${config.sessionOwnership === "assigned" ? "assigned to you only" : "any ticket a signal placed"}`);
30
- yield* Console.log(` Yours anyway: ${config.sessionOwnershipOverrides.length > 0 ? config.sessionOwnershipOverrides.join(", ") : "(none)"}`);
29
+ const line = (label, key, shown) => Console.log(` ${label.padEnd(18)}${shown}${exists && JSON.stringify(config[key]) === JSON.stringify(defaultJcfConfig[key]) ? " (default)" : ""}`);
30
+ const list = (values) => values.length > 0 ? values.join(", ") : "(none)";
31
+ yield* line("Default JQL:", "defaultJql", config.defaultJql);
32
+ yield* line("Refresh (sec):", "refreshInterval", String(config.refreshInterval));
33
+ yield* line("Default project:", "defaultProjectId", config.defaultProjectName ?? config.defaultProjectId ?? "(none)");
34
+ yield* line("Default billable:", "defaultBillable", config.defaultBillable ? "yes" : "no");
35
+ yield* line("Project map:", "projectMap", JSON.stringify(config.projectMap));
36
+ yield* line("Session roots:", "sessionRoots", list(config.sessionRoots));
37
+ yield* line("Session tickets:", "sessionTicketMap", JSON.stringify(config.sessionTicketMap));
38
+ yield* line("Idle cap (sec):", "sessionIdleCapSeconds", String(config.sessionIdleCapSeconds));
39
+ yield* line("Dwell (sec):", "sessionDwellSeconds", config.sessionDwellSeconds === 0 ? "off" : String(config.sessionDwellSeconds));
40
+ yield* line("Confidence floor:", "sessionConfidenceFloor", String(config.sessionConfidenceFloor));
41
+ yield* line("Ownership:", "sessionOwnership", config.sessionOwnership === "assigned" ? "assigned to you only" : "any ticket a signal placed");
42
+ yield* line("Yours anyway:", "sessionOwnershipOverrides", list(config.sessionOwnershipOverrides));
43
+ yield* line("Ignored tickets:", "sessionIgnoredTickets", list(config.sessionIgnoredTickets));
31
44
  });
32
45
  const configShow = Command.make("show", {}, () => Effect.gen(function* () {
33
46
  const cfg = yield* ConfigService;
@@ -40,14 +53,11 @@ const configSetProject = Command.make("project", {}, () => Effect.gen(function*
40
53
  const cfg = yield* ConfigService;
41
54
  const clockifyAuth = yield* ClockifyAuth;
42
55
  const clockifyClient = yield* ClockifyApiClient;
43
- const auth = yield* clockifyAuth.getConfig.pipe(Effect.catch(() => Effect.succeed(null)));
44
- if (auth === null) {
45
- yield* Console.log("Clockify not configured. Run: jcf auth clockify setup");
46
- return;
47
- }
48
- const projects = yield* clockifyClient.getProjects(auth.workspaceId).pipe(Effect.catch(() => Effect.succeed([])));
56
+ const auth = yield* clockifyAuth.getConfig.pipe(Effect.mapError(() => new CommandFailed({ message: "Clockify is not connected. Run jcf auth clockify setup." })));
57
+ const projects = yield* clockifyClient.getProjects(auth.workspaceId).pipe(Effect.mapError(() => new CommandFailed({ message: "Could not read Clockify projects. Check the connection and try again." })));
49
58
  if (projects.length === 0) {
50
- yield* Console.log("No projects found in Clockify workspace.");
59
+ yield* Console.log("This Clockify workspace has no projects, so entries are saved without one. " +
60
+ "Create a project at https://app.clockify.me/projects to choose a default.");
51
61
  return;
52
62
  }
53
63
  const selected = yield* Prompt.Select({
@@ -201,6 +211,30 @@ const configSetMine = Command.make("mine", { key: Args.String("ISSUE-KEY") }, ({
201
211
  });
202
212
  yield* Console.log(`${ticketKey} will be proposed as yours whatever Jira says its assignee is.`);
203
213
  })).pipe(Command.withDescription("Treat one ticket as yours even when Jira assigns it to somebody else"));
214
+ const configSetSessionIgnore = Command.make("session-ignore", { key: Args.String("ISSUE-KEY") }, ({ key }) => Effect.gen(function* () {
215
+ const cfg = yield* ConfigService;
216
+ const ticketKey = key.trim().toUpperCase();
217
+ if (!isTicketKey(ticketKey)) {
218
+ yield* Console.log("That is not an Issue Key, e.g. PROJ-123.");
219
+ return;
220
+ }
221
+ const current = yield* cfg.get;
222
+ yield* cfg.set({ sessionIgnoredTickets: [...new Set([...current.sessionIgnoredTickets, ticketKey])].sort() });
223
+ yield* Console.log(`${ticketKey} is ignored in all session scans.`);
224
+ })).pipe(Command.withDescription("Ignore one session ticket in every week"));
225
+ const configUnsetSessionIgnore = Command.make("session-ignore", { key: Args.String("ISSUE-KEY") }, ({ key }) => Effect.gen(function* () {
226
+ const cfg = yield* ConfigService;
227
+ const ticketKey = key.trim().toUpperCase();
228
+ if (!isTicketKey(ticketKey)) {
229
+ yield* Console.log("That is not an Issue Key, e.g. PROJ-123.");
230
+ return;
231
+ }
232
+ const current = yield* cfg.get;
233
+ yield* cfg.set({
234
+ sessionIgnoredTickets: current.sessionIgnoredTickets.filter((ignored) => ignored !== ticketKey)
235
+ });
236
+ yield* Console.log(`${ticketKey} is restored to session scans.`);
237
+ })).pipe(Command.withDescription("Restore one globally ignored session ticket"));
204
238
  // ---------------------------------------------------------------------------
205
239
  // reset
206
240
  // ---------------------------------------------------------------------------
@@ -223,27 +257,35 @@ const configReset = Command.make("reset", {}, () => Effect.gen(function* () {
223
257
  sessionDwellSeconds: defaultJcfConfig.sessionDwellSeconds,
224
258
  sessionAgent: defaultJcfConfig.sessionAgent,
225
259
  sessionOwnership: defaultJcfConfig.sessionOwnership,
226
- sessionOwnershipOverrides: defaultJcfConfig.sessionOwnershipOverrides
260
+ sessionOwnershipOverrides: defaultJcfConfig.sessionOwnershipOverrides,
261
+ sessionIgnoredTickets: defaultJcfConfig.sessionIgnoredTickets
227
262
  });
228
263
  yield* Console.log("Config reset to defaults, including session roots and standing attributions.");
229
264
  }));
230
- const configSet = Command.make("set", {}, () => Console.log("Config set: project, billable, jql, session-root, session-ticket, idle-cap, dwell, ownership, mine")).pipe(Command.withSubcommands([
231
- configSetProject,
232
- configSetBillable,
233
- configSetJql,
265
+ const configSet = Command.make("set", {}, () => Console.log("Config set: project, billable, jql, session-root, session-ticket, idle-cap, dwell, ownership, mine, session-ignore")).pipe(Command.withDescription("Change one setting"), Command.withSubcommands([
266
+ configSetProject.pipe(Command.withDescription("Choose the default Clockify project")),
267
+ configSetBillable.pipe(Command.withDescription("Choose whether new entries are billable by default")),
268
+ configSetJql.pipe(Command.withDescription("Set the Jira query that lists your issues")),
234
269
  configSetSessionRoot,
235
270
  configSetSessionTicket,
236
271
  configSetIdleCap,
237
272
  configSetDwell,
238
273
  configSetOwnership,
239
- configSetMine
274
+ configSetMine,
275
+ configSetSessionIgnore
240
276
  ]));
277
+ const configUnset = Command.make("unset", {}, () => Console.log("Config unset: session-ignore")).pipe(Command.withDescription("Clear one setting"), Command.withSubcommands([configUnsetSessionIgnore]));
241
278
  // ---------------------------------------------------------------------------
242
279
  // Top-level config command
243
280
  // ---------------------------------------------------------------------------
244
- /** Top-level `config` command with show/set/reset subcommands. */
281
+ /** Top-level `config` command with show/set/unset/reset subcommands. */
245
282
  export const config = Command.make("config", {}, () => Effect.gen(function* () {
246
283
  const cfg = yield* ConfigService;
247
284
  yield* printConfig(yield* cfg.get);
248
- })).pipe(Command.withSubcommands([configShow, configSet, configReset]));
285
+ })).pipe(Command.withDescription("Show and change jcf settings"), Command.withSubcommands([
286
+ configShow.pipe(Command.withDescription("Show the current settings")),
287
+ configSet,
288
+ configUnset,
289
+ configReset.pipe(Command.withDescription("Reset every setting to its default"))
290
+ ]));
249
291
  //# sourceMappingURL=config.js.map