climemo 0.3.0 → 0.3.1

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.
@@ -4,7 +4,7 @@ import { validateToken } from "../lib/auth.js";
4
4
  import { getConfig } from "../lib/config.js";
5
5
  export const loginCommand = new Command("login")
6
6
  .description("Log in to Climemo via browser OAuth")
7
- .option("--provider <provider>", "OAuth provider: github | google", "github")
7
+ .option("--provider <provider>", "OAuth provider: google | github", "google")
8
8
  .action(async (options) => {
9
9
  const config = getConfig();
10
10
  const apiBase = config.apiUrl;
@@ -6,7 +6,8 @@
6
6
  */
7
7
  export declare function resolveToken(flagToken?: string): Promise<string | null>;
8
8
  /**
9
- * Get authenticated headers for API calls
9
+ * Get authenticated headers for API calls.
10
+ * Automatically refreshes token if expired or expiring soon.
10
11
  */
11
12
  export declare function getAuthHeaders(flagToken?: string): Promise<Record<string, string>>;
12
13
  /**
package/dist/lib/auth.js CHANGED
@@ -17,13 +17,38 @@ export async function resolveToken(flagToken) {
17
17
  return getAccessToken();
18
18
  }
19
19
  /**
20
- * Get authenticated headers for API calls
20
+ * Check if a JWT is expired or expiring within thresholdSeconds
21
+ */
22
+ function isTokenExpiringSoon(token, thresholdSeconds = 300) {
23
+ try {
24
+ const parts = token.split(".");
25
+ if (parts.length !== 3)
26
+ return true;
27
+ const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
28
+ if (!payload.exp)
29
+ return true;
30
+ return (payload.exp - Math.floor(Date.now() / 1000)) < thresholdSeconds;
31
+ }
32
+ catch {
33
+ return true;
34
+ }
35
+ }
36
+ /**
37
+ * Get authenticated headers for API calls.
38
+ * Automatically refreshes token if expired or expiring soon.
21
39
  */
22
40
  export async function getAuthHeaders(flagToken) {
23
- const token = await resolveToken(flagToken);
41
+ let token = await resolveToken(flagToken);
24
42
  if (!token) {
25
43
  throw new Error("Not authenticated. Run `climemo login` first.");
26
44
  }
45
+ // Auto-refresh if token is expiring within 5 minutes (skip for CI tokens)
46
+ if (!flagToken && !process.env.CLIMEMO_TOKEN && isTokenExpiringSoon(token)) {
47
+ const refreshed = await refreshAccessToken();
48
+ if (refreshed) {
49
+ token = (await getAccessToken()) || token;
50
+ }
51
+ }
27
52
  return {
28
53
  "Authorization": `Bearer ${token}`,
29
54
  "Content-Type": "application/json",
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG5E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,qBAAqB,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAkB;IACnD,sBAAsB;IACtB,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,0BAA0B;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAEhE,iBAAiB;IACjB,OAAO,cAAc,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAkB;IACrD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,OAAO;QACL,eAAe,EAAE,UAAU,KAAK,EAAE;QAClC,cAAc,EAAE,kBAAkB;KACnC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,YAAY,GAAG,MAAM,eAAe,EAAE,CAAC;IAC7C,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,wBAAwB,EAAE;YAC3D,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;SACtD,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAE1B,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,UAAU,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,iBAAiB,EAAE;YACpD,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,KAAK,EAAE,EAAE;SAChD,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG5E,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,qBAAqB,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAkB;IACnD,sBAAsB;IACtB,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,0BAA0B;IAC1B,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAEhE,iBAAiB;IACjB,OAAO,cAAc,EAAE,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,KAAa,EAAE,mBAA2B,GAAG;IACxE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO,CAAC,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,gBAAgB,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAkB;IACrD,IAAI,KAAK,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,0EAA0E;IAC1E,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3E,MAAM,SAAS,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,GAAG,CAAC,MAAM,cAAc,EAAE,CAAC,IAAI,KAAK,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO;QACL,eAAe,EAAE,UAAU,KAAK,EAAE;QAClC,cAAc,EAAE,kBAAkB;KACnC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,YAAY,GAAG,MAAM,eAAe,EAAE,CAAC;IAC7C,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,wBAAwB,EAAE;YAC3D,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;SACtD,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAE1B,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,UAAU,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,iBAAiB,EAAE;YACpD,OAAO,EAAE,EAAE,eAAe,EAAE,UAAU,KAAK,EAAE,EAAE;SAChD,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "climemo",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "AI 시대의 프로젝트 지식 관리 도구 - CLI for syncing project knowledge",
5
5
  "license": "MIT",
6
6
  "repository": {