@workjournal/cli 0.8.0 → 0.16.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 (92) hide show
  1. package/README.md +11 -1
  2. package/dist/api-client.d.ts +24 -9
  3. package/dist/api-client.d.ts.map +1 -1
  4. package/dist/api-client.js +109 -57
  5. package/dist/api-client.js.map +1 -1
  6. package/dist/auth.d.ts +6 -0
  7. package/dist/auth.d.ts.map +1 -1
  8. package/dist/auth.js +18 -0
  9. package/dist/auth.js.map +1 -1
  10. package/dist/cli-args.d.ts +19 -0
  11. package/dist/cli-args.d.ts.map +1 -0
  12. package/dist/cli-args.js +50 -0
  13. package/dist/cli-args.js.map +1 -0
  14. package/dist/commands/entries.d.ts +6 -0
  15. package/dist/commands/entries.d.ts.map +1 -1
  16. package/dist/commands/entries.js +68 -14
  17. package/dist/commands/entries.js.map +1 -1
  18. package/dist/commands/export.d.ts.map +1 -1
  19. package/dist/commands/export.js +2 -3
  20. package/dist/commands/export.js.map +1 -1
  21. package/dist/commands/invites.d.ts.map +1 -1
  22. package/dist/commands/invites.js +6 -7
  23. package/dist/commands/invites.js.map +1 -1
  24. package/dist/commands/journals.d.ts +1 -1
  25. package/dist/commands/journals.d.ts.map +1 -1
  26. package/dist/commands/journals.js +20 -19
  27. package/dist/commands/journals.js.map +1 -1
  28. package/dist/commands/prompts.d.ts +9 -0
  29. package/dist/commands/prompts.d.ts.map +1 -0
  30. package/dist/commands/prompts.js +83 -0
  31. package/dist/commands/prompts.js.map +1 -0
  32. package/dist/commands/shares.d.ts.map +1 -1
  33. package/dist/commands/shares.js +11 -13
  34. package/dist/commands/shares.js.map +1 -1
  35. package/dist/commands/workspaces.d.ts.map +1 -1
  36. package/dist/commands/workspaces.js +4 -7
  37. package/dist/commands/workspaces.js.map +1 -1
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +3 -1
  40. package/dist/config.js.map +1 -1
  41. package/dist/help/_dispatch.d.ts +29 -0
  42. package/dist/help/_dispatch.d.ts.map +1 -0
  43. package/dist/help/_dispatch.js +132 -0
  44. package/dist/help/_dispatch.js.map +1 -0
  45. package/dist/help/_registry.d.ts +18 -0
  46. package/dist/help/_registry.d.ts.map +1 -0
  47. package/dist/help/_registry.js +88 -0
  48. package/dist/help/_registry.js.map +1 -0
  49. package/dist/help/_renderer.d.ts +31 -0
  50. package/dist/help/_renderer.d.ts.map +1 -0
  51. package/dist/help/_renderer.js +99 -0
  52. package/dist/help/_renderer.js.map +1 -0
  53. package/dist/help/_types.d.ts +53 -0
  54. package/dist/help/_types.d.ts.map +1 -0
  55. package/dist/help/_types.js +15 -0
  56. package/dist/help/_types.js.map +1 -0
  57. package/dist/help/auth-login.json +12 -0
  58. package/dist/help/auth-logout.json +7 -0
  59. package/dist/help/auth-status.json +7 -0
  60. package/dist/help/auth-whoami.json +7 -0
  61. package/dist/help/config-show.json +7 -0
  62. package/dist/help/entries-delete.json +12 -0
  63. package/dist/help/entries-get.json +12 -0
  64. package/dist/help/entries-last.json +19 -0
  65. package/dist/help/entries-list.json +14 -0
  66. package/dist/help/entries-search.json +15 -0
  67. package/dist/help/entries-update.json +37 -0
  68. package/dist/help/entries-write.json +33 -0
  69. package/dist/help/export.json +29 -0
  70. package/dist/help/invites-delete.json +16 -0
  71. package/dist/help/invites-list.json +11 -0
  72. package/dist/help/invites-new.json +12 -0
  73. package/dist/help/journal.json +13 -0
  74. package/dist/help/journals-assign-prompt.json +12 -0
  75. package/dist/help/journals-delete.json +11 -0
  76. package/dist/help/journals-get.json +20 -0
  77. package/dist/help/journals-list.json +14 -0
  78. package/dist/help/journals-new.json +21 -0
  79. package/dist/help/journals-rename.json +12 -0
  80. package/dist/help/journals-select.json +11 -0
  81. package/dist/help/journals-set-slug.json +16 -0
  82. package/dist/help/journals-unassign-prompt.json +11 -0
  83. package/dist/help/prompts-delete.json +11 -0
  84. package/dist/help/prompts-get.json +11 -0
  85. package/dist/help/prompts-list.json +14 -0
  86. package/dist/help/prompts-new.json +23 -0
  87. package/dist/help/prompts-update.json +29 -0
  88. package/dist/help/shares-delete.json +16 -0
  89. package/dist/help/shares-list.json +11 -0
  90. package/dist/index.js +197 -76
  91. package/dist/index.js.map +1 -1
  92. package/package.json +4 -5
package/README.md CHANGED
@@ -108,7 +108,17 @@ workjournal # lists entries in acme/engineering
108
108
 
109
109
  ## Credentials
110
110
 
111
- The CLI stores credentials at `~/.workjournal/credentials.json` with user-only file permissions. Remove them with `workjournal auth logout`.
111
+ The CLI stores credentials in the user config directory with user-only file permissions:
112
+
113
+ | Platform | Default path |
114
+ |---|---|
115
+ | Linux / WSL2 (Linux Node) | `${XDG_CONFIG_HOME:-$HOME/.config}/workjournal/credentials.json` |
116
+ | macOS | `${XDG_CONFIG_HOME:-$HOME/.config}/workjournal/credentials.json` |
117
+ | Windows | `%APPDATA%\workjournal\credentials.json` (PowerShell: `$env:APPDATA\workjournal\credentials.json`) |
118
+
119
+ Override with `WORKJOURNAL_CONFIG_DIR=/your/path`. Remove the credentials with `workjournal auth logout`.
120
+
121
+ Earlier CLI versions used `~/.workjournal/`; on first invocation post-upgrade the directory is moved automatically with a one-line stderr notice.
112
122
 
113
123
  ## Headless environments
114
124
 
@@ -14,15 +14,21 @@ export declare const API_PATHS: {
14
14
  readonly entries: (workspaceSlug: string, journalSlug: string) => string;
15
15
  readonly entry: (workspaceSlug: string, journalSlug: string, index: number | string) => string;
16
16
  readonly searchEntries: (workspaceSlug: string, journalSlug: string) => string;
17
- readonly members: (workspaceSlug: string, journalSlug: string) => string;
18
- readonly member: (workspaceSlug: string, journalSlug: string, userId: string) => string;
17
+ readonly contributors: (workspaceSlug: string, journalSlug: string) => string;
18
+ readonly contributor: (workspaceSlug: string, journalSlug: string, userId: string) => string;
19
19
  readonly invitations: (workspaceSlug: string, journalSlug: string) => string;
20
20
  readonly invitation: (workspaceSlug: string, journalSlug: string, invitationId: string) => string;
21
+ readonly resendInvitation: (workspaceSlug: string, journalSlug: string, invitationId: string) => string;
21
22
  readonly acceptInvitation: "/v1/invitations/accept";
23
+ readonly invitationByToken: (token: string) => string;
22
24
  readonly exportJournal: (workspaceSlug: string, journalSlug: string) => string;
23
25
  readonly publicJournal: (slug: string) => string;
24
26
  readonly publicEntries: (slug: string) => string;
25
27
  readonly sharedWithMeJournals: "/v1/shared-with-me/journals";
28
+ readonly prompts: (workspaceSlug: string) => string;
29
+ readonly prompt: (workspaceSlug: string, promptSlug: string) => string;
30
+ readonly journalPrompt: (workspaceSlug: string, journalSlug: string, promptSlug: string) => string;
31
+ readonly supportContact: (workspaceSlug: string) => string;
26
32
  };
27
33
  export interface ApiError {
28
34
  error: {
@@ -31,12 +37,21 @@ export interface ApiError {
31
37
  };
32
38
  }
33
39
  /**
34
- * Ensure the user is authenticated. Exits with code 1 if not.
40
+ * Thrown when the api-client cannot obtain a working bearer token
41
+ * either no credentials are on disk (`not-logged-in`) or the server
42
+ * rejected both the cached and freshly-refreshed token (`expired`,
43
+ * which covers refresh-token revocation, role changes, and persistent
44
+ * clock skew). The top-level CLI handler maps this to a friendly
45
+ * message and exit code 1.
35
46
  */
36
- export declare function requireAuth(): Promise<string>;
37
- export declare function apiGet<T>(path: string, token: string): Promise<T>;
38
- export declare function apiGetRaw(path: string, token: string): Promise<string>;
39
- export declare function apiPost<T>(path: string, token: string, body: unknown): Promise<T>;
40
- export declare function apiPatch<T>(path: string, token: string, body: unknown): Promise<T>;
41
- export declare function apiDelete(path: string, token: string): Promise<void>;
47
+ export declare class AuthRequiredError extends Error {
48
+ readonly reason: 'not-logged-in' | 'expired';
49
+ constructor(reason: 'not-logged-in' | 'expired');
50
+ }
51
+ export declare function apiGet<T>(path: string): Promise<T>;
52
+ export declare function apiGetRaw(path: string): Promise<string>;
53
+ export declare function apiPost<T>(path: string, body: unknown): Promise<T>;
54
+ export declare function apiPatch<T>(path: string, body: unknown): Promise<T>;
55
+ export declare function apiPut(path: string, body?: unknown): Promise<void>;
56
+ export declare function apiDelete(path: string): Promise<void>;
42
57
  //# sourceMappingURL=api-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;CAAe,CAAC;AAEtC,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAOnD;AA8CD,wBAAsB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAMvE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5E;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAUvF;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAUxF;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM1E"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;CAAe,CAAC;AAEtC,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;aACf,MAAM,EAAE,eAAe,GAAG,SAAS;gBAAnC,MAAM,EAAE,eAAe,GAAG,SAAS;CAI/D;AAkGD,wBAAsB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAGxD;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI7D;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAOxE;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAOzE;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3D"}
@@ -1,5 +1,5 @@
1
1
  import { WS_API_PATHS } from '@workjournal/shared';
2
- import { getAccessToken } from './credentials.js';
2
+ import { forceRefreshAccessToken, getAccessToken } from './credentials.js';
3
3
  const API_BASE_URL = process.env['WORKJOURNAL_API_URL'] ?? 'https://api.workjournal.pro';
4
4
  const API_TIMEOUT_MS = 10_000;
5
5
  /**
@@ -9,41 +9,50 @@ const API_TIMEOUT_MS = 10_000;
9
9
  */
10
10
  export const API_PATHS = WS_API_PATHS;
11
11
  /**
12
- * Ensure the user is authenticated. Exits with code 1 if not.
12
+ * Thrown when the api-client cannot obtain a working bearer token
13
+ * either no credentials are on disk (`not-logged-in`) or the server
14
+ * rejected both the cached and freshly-refreshed token (`expired`,
15
+ * which covers refresh-token revocation, role changes, and persistent
16
+ * clock skew). The top-level CLI handler maps this to a friendly
17
+ * message and exit code 1.
13
18
  */
14
- export async function requireAuth() {
15
- const token = await getAccessToken();
16
- if (!token) {
17
- process.stderr.write('Not logged in. Run `workjournal auth login` to authenticate.\n');
18
- process.exit(1);
19
+ export class AuthRequiredError extends Error {
20
+ reason;
21
+ constructor(reason) {
22
+ super(reason);
23
+ this.reason = reason;
24
+ this.name = 'AuthRequiredError';
19
25
  }
20
- return token;
21
26
  }
22
- async function ensureOk(res) {
23
- if (!res.ok) {
24
- if (res.status === 401) {
25
- process.stderr.write('Authentication expired. Run `workjournal auth login` to re-authenticate.\n');
26
- process.exit(1);
27
- }
28
- let message = `${res.status} ${res.statusText}`;
29
- try {
30
- const body = (await res.json());
31
- if (body?.error?.message) {
32
- message = body.error.message;
33
- }
34
- }
35
- catch {
36
- // use default message
37
- }
38
- throw new Error(message);
39
- }
27
+ let refreshInFlight = null;
28
+ /**
29
+ * Single-flight wrapper around {@link forceRefreshAccessToken} so concurrent
30
+ * 401 retries (rare for the CLI but free to support) share one refresh
31
+ * call. The slot is cleared as soon as the refresh settles, regardless of
32
+ * outcome — a failed refresh shouldn't poison subsequent recovery attempts
33
+ * within the same process.
34
+ */
35
+ function singleFlightRefresh() {
36
+ if (refreshInFlight)
37
+ return refreshInFlight;
38
+ const inflight = forceRefreshAccessToken().finally(() => {
39
+ refreshInFlight = null;
40
+ });
41
+ refreshInFlight = inflight;
42
+ return inflight;
40
43
  }
41
- async function handleResponse(res) {
42
- await ensureOk(res);
43
- return res.json();
44
+ function withAuth(init, token) {
45
+ const headers = {};
46
+ if (init.headers && !Array.isArray(init.headers) && !(init.headers instanceof Headers)) {
47
+ Object.assign(headers, init.headers);
48
+ }
49
+ headers['Authorization'] = `Bearer ${token}`;
50
+ return { ...init, headers };
44
51
  }
45
52
  /**
46
- * Shared fetch wrapper with AbortController timeout.
53
+ * Shared fetch wrapper with AbortController timeout. Each call gets its own
54
+ * controller — when {@link fetchWithRetry} retries after a 401, the retry
55
+ * starts a fresh 10s budget rather than sharing the original.
47
56
  */
48
57
  async function apiRequest(url, init) {
49
58
  const controller = new AbortController();
@@ -61,48 +70,91 @@ async function apiRequest(url, init) {
61
70
  clearTimeout(timeout);
62
71
  }
63
72
  }
64
- export async function apiGet(path, token) {
65
- const res = await apiRequest(`${API_BASE_URL}${path}`, {
66
- method: 'GET',
67
- headers: { Authorization: `Bearer ${token}` },
68
- });
73
+ /**
74
+ * Issue a request with the latest access token from disk. On a 401, run a
75
+ * single in-flight {@link forceRefreshAccessToken} and retry once. Throws
76
+ * {@link AuthRequiredError} if no token is available, refresh fails, or the
77
+ * retried request also returns 401 — the only ways the CLI cannot recover
78
+ * without a fresh `workjournal auth login`.
79
+ *
80
+ * Mirrors the mcp-server's `#fetchWithRetry` (see
81
+ * `packages/mcp-server/src/api-client.ts`); both paths exist to absorb
82
+ * clock skew, mid-flight expiry, and server-side revocation without
83
+ * surfacing a hard failure to the agent harness on the user's first call
84
+ * after token expiry.
85
+ */
86
+ async function fetchWithRetry(path, init) {
87
+ const token = await getAccessToken();
88
+ if (token === null)
89
+ throw new AuthRequiredError('not-logged-in');
90
+ const url = `${API_BASE_URL}${path}`;
91
+ let res = await apiRequest(url, withAuth(init, token));
92
+ if (res.status === 401) {
93
+ const fresh = await singleFlightRefresh();
94
+ if (fresh === null)
95
+ throw new AuthRequiredError('expired');
96
+ res = await apiRequest(url, withAuth(init, fresh));
97
+ if (res.status === 401)
98
+ throw new AuthRequiredError('expired');
99
+ }
100
+ return res;
101
+ }
102
+ async function ensureOk(res) {
103
+ if (res.ok)
104
+ return;
105
+ let message = `${res.status} ${res.statusText}`;
106
+ try {
107
+ const body = (await res.json());
108
+ if (body?.error?.message) {
109
+ message = body.error.message;
110
+ }
111
+ }
112
+ catch {
113
+ // use default message
114
+ }
115
+ throw new Error(message);
116
+ }
117
+ async function handleResponse(res) {
118
+ await ensureOk(res);
119
+ return res.json();
120
+ }
121
+ export async function apiGet(path) {
122
+ const res = await fetchWithRetry(path, { method: 'GET' });
69
123
  return handleResponse(res);
70
124
  }
71
- export async function apiGetRaw(path, token) {
72
- const res = await apiRequest(`${API_BASE_URL}${path}`, {
73
- method: 'GET',
74
- headers: { Authorization: `Bearer ${token}` },
75
- });
125
+ export async function apiGetRaw(path) {
126
+ const res = await fetchWithRetry(path, { method: 'GET' });
76
127
  await ensureOk(res);
77
128
  return res.text();
78
129
  }
79
- export async function apiPost(path, token, body) {
80
- const res = await apiRequest(`${API_BASE_URL}${path}`, {
130
+ export async function apiPost(path, body) {
131
+ const res = await fetchWithRetry(path, {
81
132
  method: 'POST',
82
- headers: {
83
- Authorization: `Bearer ${token}`,
84
- 'Content-Type': 'application/json',
85
- },
133
+ headers: { 'Content-Type': 'application/json' },
86
134
  body: JSON.stringify(body),
87
135
  });
88
136
  return handleResponse(res);
89
137
  }
90
- export async function apiPatch(path, token, body) {
91
- const res = await apiRequest(`${API_BASE_URL}${path}`, {
138
+ export async function apiPatch(path, body) {
139
+ const res = await fetchWithRetry(path, {
92
140
  method: 'PATCH',
93
- headers: {
94
- Authorization: `Bearer ${token}`,
95
- 'Content-Type': 'application/json',
96
- },
141
+ headers: { 'Content-Type': 'application/json' },
97
142
  body: JSON.stringify(body),
98
143
  });
99
144
  return handleResponse(res);
100
145
  }
101
- export async function apiDelete(path, token) {
102
- const res = await apiRequest(`${API_BASE_URL}${path}`, {
103
- method: 'DELETE',
104
- headers: { Authorization: `Bearer ${token}` },
105
- });
146
+ export async function apiPut(path, body) {
147
+ const init = {
148
+ method: 'PUT',
149
+ headers: { 'Content-Type': 'application/json' },
150
+ };
151
+ if (body !== undefined)
152
+ init.body = JSON.stringify(body);
153
+ const res = await fetchWithRetry(path, init);
154
+ await ensureOk(res);
155
+ }
156
+ export async function apiDelete(path) {
157
+ const res = await fetchWithRetry(path, { method: 'DELETE' });
106
158
  await ensureOk(res);
107
159
  }
108
160
  //# sourceMappingURL=api-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts CHANGED
@@ -25,4 +25,10 @@ export declare function loginFinish(rawCode: string): Promise<void>;
25
25
  * via Bash) and points the caller at the two-phase commands instead.
26
26
  */
27
27
  export declare function loginInteractive(): Promise<void>;
28
+ /**
29
+ * Best-effort server-side revocation of a CLI device session (issue #375).
30
+ * Local credential clearing is the caller's responsibility; this swallows
31
+ * network and server failures so logout is never blocked by the network.
32
+ */
33
+ export declare function revokeDeviceSession(refreshToken: string): Promise<void>;
28
34
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBhD;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CA2CtD"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBhD;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CA2CtD;AAwBD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW7E"}
package/dist/auth.js CHANGED
@@ -117,4 +117,22 @@ async function exchangeAndPersist(code, verifier) {
117
117
  process.stdout.write('\nAuthenticated successfully!\n');
118
118
  process.stdout.write(`Credentials saved to ${CONFIG_DIR}/credentials.json\n`);
119
119
  }
120
+ /**
121
+ * Best-effort server-side revocation of a CLI device session (issue #375).
122
+ * Local credential clearing is the caller's responsibility; this swallows
123
+ * network and server failures so logout is never blocked by the network.
124
+ */
125
+ export async function revokeDeviceSession(refreshToken) {
126
+ const apiUrl = process.env['WORKJOURNAL_API_URL'] ?? 'https://api.workjournal.pro';
127
+ try {
128
+ await fetch(`${apiUrl}/v1/auth/logout`, {
129
+ method: 'POST',
130
+ headers: { 'Content-Type': 'application/json' },
131
+ body: JSON.stringify({ refresh_token: refreshToken }),
132
+ });
133
+ }
134
+ catch {
135
+ // Network errors are not actionable from logout context.
136
+ }
137
+ }
120
138
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,EACN,UAAU,EACV,eAAe,EACf,mBAAmB,EAEnB,cAAc,EAEd,gBAAgB,EAChB,eAAe,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC/B,MAAM,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;IAExC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAe;QACzB,QAAQ;QACR,SAAS;QACT,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IACF,eAAe,CAAC,KAAK,CAAC,CAAC;IAEvB,MAAM,GAAG,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,8EAA8E,CAC9E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,0EAA0E,CAC1E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,eAAe,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;QAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/C,eAAe,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACrC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,wFAAwF;YACvF,iCAAiC;YACjC,kCAAkC;YAClC,0CAA0C,CAC3C,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,SAAS,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAe;QACzB,QAAQ;QACR,SAAS;QACT,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IACF,eAAe,CAAC,KAAK,CAAC,CAAC;IAEvB,MAAM,GAAG,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAErF,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,CAAC;YAAS,CAAC;QACV,EAAE,CAAC,KAAK,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,eAAe,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACzC,eAAe,EAAE,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAAgB;IAC/D,IAAI,IAAmD,CAAC;IACxD,IAAI,CAAC;QACJ,IAAI,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9E,MAAM,KAAK,GAAsB;QAChC,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,UAAU,EAAE,SAAS;QACrB,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;IAEF,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,UAAU,qBAAqB,CAAC,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,YAAoB;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,6BAA6B,CAAC;IACnF,IAAI,CAAC;QACJ,MAAM,KAAK,CAAC,GAAG,MAAM,iBAAiB,EAAE;YACvC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;SACrD,CAAC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACR,yDAAyD;IAC1D,CAAC;AACF,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Boolean flags that route handlers must see in argv but that take no value
3
+ * of their own — so the global parser must not consume the next arg as their
4
+ * "value". `--help --json` was the regression that prompted this set: without
5
+ * it, `--help` was treated as a flag-with-value and ate `--json`, hiding the
6
+ * JSON-output path that the LLM-targeted help variant relies on.
7
+ */
8
+ export declare const ROUTER_BOOLEAN_FLAGS: Set<string>;
9
+ /**
10
+ * Strip the global toggles `--json` / `--verbose` from argv and return both
11
+ * the residual args (preserved verbatim — see the `-b "--json"` value-flag
12
+ * case below) and the parsed boolean state.
13
+ */
14
+ export declare function parseGlobalFlags(rawArgs: string[]): {
15
+ args: string[];
16
+ jsonOutput: boolean;
17
+ verbose: boolean;
18
+ };
19
+ //# sourceMappingURL=cli-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-args.d.ts","sourceRoot":"","sources":["../src/cli-args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,aAA+C,CAAC;AAEjF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG;IACpD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CACjB,CAoCA"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Boolean flags that route handlers must see in argv but that take no value
3
+ * of their own — so the global parser must not consume the next arg as their
4
+ * "value". `--help --json` was the regression that prompted this set: without
5
+ * it, `--help` was treated as a flag-with-value and ate `--json`, hiding the
6
+ * JSON-output path that the LLM-targeted help variant relies on.
7
+ */
8
+ export const ROUTER_BOOLEAN_FLAGS = new Set(['--help', '-h', '--version', '-V']);
9
+ /**
10
+ * Strip the global toggles `--json` / `--verbose` from argv and return both
11
+ * the residual args (preserved verbatim — see the `-b "--json"` value-flag
12
+ * case below) and the parsed boolean state.
13
+ */
14
+ export function parseGlobalFlags(rawArgs) {
15
+ const out = [];
16
+ let json = false;
17
+ let verb = false;
18
+ let i = 0;
19
+ while (i < rawArgs.length) {
20
+ const arg = rawArgs[i];
21
+ if (arg === '--json') {
22
+ json = true;
23
+ i++;
24
+ continue;
25
+ }
26
+ if (arg === '--verbose') {
27
+ verb = true;
28
+ i++;
29
+ continue;
30
+ }
31
+ if (ROUTER_BOOLEAN_FLAGS.has(arg)) {
32
+ out.push(arg);
33
+ i++;
34
+ continue;
35
+ }
36
+ const isValueFlag = arg.startsWith('--') || (arg.startsWith('-') && arg.length === 2 && arg !== '-');
37
+ if (isValueFlag && i + 1 < rawArgs.length) {
38
+ // Preserve the next arg as the value — even if it happens to look
39
+ // like a flag (e.g. `entries write -b "--json"` writes "--json" as
40
+ // the body content; the leading `-b` protects it).
41
+ out.push(arg, rawArgs[i + 1]);
42
+ i += 2;
43
+ continue;
44
+ }
45
+ out.push(arg);
46
+ i++;
47
+ }
48
+ return { args: out, jsonOutput: json, verbose: verb };
49
+ }
50
+ //# sourceMappingURL=cli-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-args.js","sourceRoot":"","sources":["../src/cli-args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAEjF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAiB;IAKjD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAW,CAAC;QACjC,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;YACtB,IAAI,GAAG,IAAI,CAAC;YACZ,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QACD,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACzB,IAAI,GAAG,IAAI,CAAC;YACZ,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QACD,IAAI,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,EAAE,CAAC;YACJ,SAAS;QACV,CAAC;QACD,MAAM,WAAW,GAChB,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;QAClF,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAC3C,kEAAkE;YAClE,mEAAmE;YACnE,mDAAmD;YACnD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAW,CAAC,CAAC;YACxC,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACV,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,EAAE,CAAC;IACL,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACvD,CAAC"}
@@ -3,5 +3,11 @@ export declare function createEntry(workspaceSlug: string, journalSlug: string,
3
3
  export declare function searchEntries(workspaceSlug: string, journalSlug: string, query: string, jsonOutput: boolean): Promise<void>;
4
4
  export declare function lastEntries(workspaceSlug: string, journalSlug: string, count: number, jsonOutput: boolean): Promise<void>;
5
5
  export declare function getEntry(workspaceSlug: string, journalSlug: string, indexRaw: string, jsonOutput: boolean): Promise<void>;
6
+ export interface UpdateEntryOptions {
7
+ title?: string | undefined;
8
+ summary?: string | undefined;
9
+ bodySource?: string | undefined;
10
+ }
11
+ export declare function updateEntry(workspaceSlug: string, journalSlug: string, indexRaw: string, opts: UpdateEntryOptions, jsonOutput: boolean): Promise<void>;
6
12
  export declare function deleteEntry(workspaceSlug: string, journalSlug: string, indexRaw: string, jsonOutput: boolean): Promise<void>;
7
13
  //# sourceMappingURL=entries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/commands/entries.ts"],"names":[],"mappings":"AAYA,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,aAAa,CAClC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,QAAQ,CAC7B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf"}
1
+ {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/commands/entries.ts"],"names":[],"mappings":"AAkBA,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,aAAa,CAClC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED,wBAAsB,QAAQ,CAC7B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAcD,MAAM,WAAW,kBAAkB;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,kBAAkB,EACxB,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Df;AAED,wBAAsB,WAAW,CAChC,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -1,5 +1,6 @@
1
- import { MAX_TITLE_LENGTH } from '@workjournal/shared';
2
- import { API_PATHS, apiDelete, apiGet, apiPost, requireAuth } from '../api-client.js';
1
+ import { readFileSync } from 'node:fs';
2
+ import { MAX_SUMMARY_LENGTH, MAX_TITLE_LENGTH } from '@workjournal/shared';
3
+ import { API_PATHS, apiDelete, apiGet, apiPatch, apiPost } from '../api-client.js';
3
4
  import { formatTable, truncate } from '../formatting.js';
4
5
  function parseIndex(raw) {
5
6
  if (!/^\d+$/.test(raw))
@@ -10,8 +11,7 @@ function parseIndex(raw) {
10
11
  return n;
11
12
  }
12
13
  export async function listEntries(workspaceSlug, journalSlug, jsonOutput) {
13
- const token = await requireAuth();
14
- const result = await apiGet(API_PATHS.entries(workspaceSlug, journalSlug), token);
14
+ const result = await apiGet(API_PATHS.entries(workspaceSlug, journalSlug));
15
15
  if (jsonOutput) {
16
16
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
17
17
  return;
@@ -34,11 +34,11 @@ export async function createEntry(workspaceSlug, journalSlug, title, summary, bo
34
34
  process.stderr.write(`Title must be ${MAX_TITLE_LENGTH} characters or fewer (got ${trimmedTitle.length}).\n`);
35
35
  process.exit(1);
36
36
  }
37
- const token = await requireAuth();
38
- const entry = await apiPost(API_PATHS.entries(workspaceSlug, journalSlug), token, {
37
+ const entry = await apiPost(API_PATHS.entries(workspaceSlug, journalSlug), {
39
38
  title: trimmedTitle,
40
39
  summary,
41
40
  what_changed: body,
41
+ client: 'cli',
42
42
  });
43
43
  if (jsonOutput) {
44
44
  process.stdout.write(`${JSON.stringify(entry, null, 2)}\n`);
@@ -47,9 +47,8 @@ export async function createEntry(workspaceSlug, journalSlug, title, summary, bo
47
47
  process.stdout.write(`Entry created:\n #${entry.index}: ${entry.title}\n`);
48
48
  }
49
49
  export async function searchEntries(workspaceSlug, journalSlug, query, jsonOutput) {
50
- const token = await requireAuth();
51
50
  const params = new URLSearchParams({ q: query });
52
- const result = await apiGet(`${API_PATHS.searchEntries(workspaceSlug, journalSlug)}?${params.toString()}`, token);
51
+ const result = await apiGet(`${API_PATHS.searchEntries(workspaceSlug, journalSlug)}?${params.toString()}`);
53
52
  if (jsonOutput) {
54
53
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
55
54
  return;
@@ -65,8 +64,7 @@ export async function searchEntries(workspaceSlug, journalSlug, query, jsonOutpu
65
64
  }
66
65
  }
67
66
  export async function lastEntries(workspaceSlug, journalSlug, count, jsonOutput) {
68
- const token = await requireAuth();
69
- const result = await apiGet(`${API_PATHS.entries(workspaceSlug, journalSlug)}?limit=${count}&include=body`, token);
67
+ const result = await apiGet(`${API_PATHS.entries(workspaceSlug, journalSlug)}?limit=${count}&include=body`);
70
68
  if (jsonOutput) {
71
69
  process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
72
70
  return;
@@ -89,8 +87,7 @@ export async function getEntry(workspaceSlug, journalSlug, indexRaw, jsonOutput)
89
87
  process.stderr.write('Entry index must be a positive integer.\n');
90
88
  process.exit(1);
91
89
  }
92
- const token = await requireAuth();
93
- const entry = await apiGet(API_PATHS.entry(workspaceSlug, journalSlug, index), token);
90
+ const entry = await apiGet(API_PATHS.entry(workspaceSlug, journalSlug, index));
94
91
  if (jsonOutput) {
95
92
  process.stdout.write(`${JSON.stringify(entry, null, 2)}\n`);
96
93
  return;
@@ -100,14 +97,71 @@ export async function getEntry(workspaceSlug, journalSlug, indexRaw, jsonOutput)
100
97
  process.stdout.write(`${entry.summary}\n\n`);
101
98
  process.stdout.write(`${entry.what_changed}\n`);
102
99
  }
100
+ /**
101
+ * Read the body for `entries update`. `--body -` slurps stdin (file descriptor
102
+ * 0 read synchronously so the caller can pipe markdown in); any other value is
103
+ * treated as a path. Bodies are too long to live on a flag.
104
+ */
105
+ function readBodySource(source) {
106
+ if (source === '-') {
107
+ return readFileSync(0, 'utf8');
108
+ }
109
+ return readFileSync(source, 'utf8');
110
+ }
111
+ export async function updateEntry(workspaceSlug, journalSlug, indexRaw, opts, jsonOutput) {
112
+ const index = parseIndex(indexRaw);
113
+ if (index === null) {
114
+ process.stderr.write('Entry index must be a positive integer.\n');
115
+ process.exit(1);
116
+ }
117
+ const patch = {};
118
+ if (opts.title !== undefined) {
119
+ const trimmed = opts.title.trim();
120
+ if (trimmed.length === 0) {
121
+ process.stderr.write('Title cannot be empty.\n');
122
+ process.exit(1);
123
+ }
124
+ if (trimmed.length > MAX_TITLE_LENGTH) {
125
+ process.stderr.write(`Title must be ${MAX_TITLE_LENGTH} characters or fewer (got ${trimmed.length}).\n`);
126
+ process.exit(1);
127
+ }
128
+ patch.title = trimmed;
129
+ }
130
+ if (opts.summary !== undefined) {
131
+ if (opts.summary.length > MAX_SUMMARY_LENGTH) {
132
+ process.stderr.write(`Summary must be ${MAX_SUMMARY_LENGTH} characters or fewer (got ${opts.summary.length}).\n`);
133
+ process.exit(1);
134
+ }
135
+ patch.summary = opts.summary;
136
+ }
137
+ if (opts.bodySource !== undefined) {
138
+ try {
139
+ patch.what_changed = readBodySource(opts.bodySource);
140
+ }
141
+ catch (err) {
142
+ const message = err instanceof Error ? err.message : String(err);
143
+ process.stderr.write(`Could not read body source: ${message}\n`);
144
+ process.exit(1);
145
+ }
146
+ }
147
+ if (Object.keys(patch).length === 0) {
148
+ process.stderr.write('Nothing to update — pass at least one of -t/--title, -s/--summary, or -b/--body.\n');
149
+ process.exit(1);
150
+ }
151
+ const entry = await apiPatch(API_PATHS.entry(workspaceSlug, journalSlug, index), patch);
152
+ if (jsonOutput) {
153
+ process.stdout.write(`${JSON.stringify(entry, null, 2)}\n`);
154
+ return;
155
+ }
156
+ process.stdout.write(`Entry updated:\n #${entry.index}: ${entry.title}\n`);
157
+ }
103
158
  export async function deleteEntry(workspaceSlug, journalSlug, indexRaw, jsonOutput) {
104
159
  const index = parseIndex(indexRaw);
105
160
  if (index === null) {
106
161
  process.stderr.write('Entry index must be a positive integer.\n');
107
162
  process.exit(1);
108
163
  }
109
- const token = await requireAuth();
110
- await apiDelete(API_PATHS.entry(workspaceSlug, journalSlug, index), token);
164
+ await apiDelete(API_PATHS.entry(workspaceSlug, journalSlug, index));
111
165
  if (jsonOutput) {
112
166
  process.stdout.write(`${JSON.stringify({ deleted: index }, null, 2)}\n`);
113
167
  return;