@alisio/plugin-google-chat 0.1.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 (69) hide show
  1. package/.agents/skills/google-chat-context/SKILL.md +63 -0
  2. package/LICENSE +21 -0
  3. package/README.md +170 -0
  4. package/cover.svg +25 -0
  5. package/dist/commands.d.ts +10 -0
  6. package/dist/commands.d.ts.map +1 -0
  7. package/dist/commands.js +86 -0
  8. package/dist/commands.js.map +1 -0
  9. package/dist/config.d.ts +86 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +179 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/errors.d.ts +22 -0
  14. package/dist/errors.d.ts.map +1 -0
  15. package/dist/errors.js +44 -0
  16. package/dist/errors.js.map +1 -0
  17. package/dist/http.d.ts +66 -0
  18. package/dist/http.d.ts.map +1 -0
  19. package/dist/http.js +208 -0
  20. package/dist/http.js.map +1 -0
  21. package/dist/index.d.ts +49 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +71 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/oauth.d.ts +78 -0
  26. package/dist/oauth.d.ts.map +1 -0
  27. package/dist/oauth.js +290 -0
  28. package/dist/oauth.js.map +1 -0
  29. package/dist/render.d.ts +18 -0
  30. package/dist/render.d.ts.map +1 -0
  31. package/dist/render.js +50 -0
  32. package/dist/render.js.map +1 -0
  33. package/dist/text.d.ts +26 -0
  34. package/dist/text.d.ts.map +1 -0
  35. package/dist/text.js +63 -0
  36. package/dist/text.js.map +1 -0
  37. package/dist/time.d.ts +12 -0
  38. package/dist/time.d.ts.map +1 -0
  39. package/dist/time.js +24 -0
  40. package/dist/time.js.map +1 -0
  41. package/dist/token-set.d.ts +26 -0
  42. package/dist/token-set.d.ts.map +1 -0
  43. package/dist/token-set.js +62 -0
  44. package/dist/token-set.js.map +1 -0
  45. package/dist/token.d.ts +30 -0
  46. package/dist/token.d.ts.map +1 -0
  47. package/dist/token.js +119 -0
  48. package/dist/token.js.map +1 -0
  49. package/dist/toolkit.d.ts +14 -0
  50. package/dist/toolkit.d.ts.map +1 -0
  51. package/dist/toolkit.js +39 -0
  52. package/dist/toolkit.js.map +1 -0
  53. package/dist/tools.d.ts +5 -0
  54. package/dist/tools.d.ts.map +1 -0
  55. package/dist/tools.js +298 -0
  56. package/dist/tools.js.map +1 -0
  57. package/dist/transport.d.ts +36 -0
  58. package/dist/transport.d.ts.map +1 -0
  59. package/dist/transport.js +114 -0
  60. package/dist/transport.js.map +1 -0
  61. package/dist/validation.d.ts +70 -0
  62. package/dist/validation.d.ts.map +1 -0
  63. package/dist/validation.js +201 -0
  64. package/dist/validation.js.map +1 -0
  65. package/dist/version.d.ts +3 -0
  66. package/dist/version.d.ts.map +1 -0
  67. package/dist/version.js +3 -0
  68. package/dist/version.js.map +1 -0
  69. package/package.json +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,4CAA4C;IAC5C,oJAAoJ;CACrJ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AAE3D,qFAAqF;AACrF,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAExC,qEAAqE;AACrE,SAAS,cAAc,CAAC,KAAa;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACnD,OAAO,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,0BAA0B,CAAC,KAAa;IACtD,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,SAAS,IAAI,KAAK;QAC3B,GAAG,IAAI,cAAc,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACzE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,KAAK,MAAM,SAAS,IAAI,KAAK;QAAE,IAAI,cAAc,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IAC9F,OAAO,KAAK,CAAC;AACf,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,KAAK,CAAC,KAAa,EAAE,GAAW;IAC9C,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,GAAG,IAAI,iBAAiB,CAAC,MAAM;QAAE,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACzF,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,iBAAiB,EAAE,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc,EAAE,GAAG,GAAG,eAAe;IACtE,MAAM,GAAG,GACP,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjG,MAAM,UAAU,GAAG,0BAA0B,CAAC,GAAG,CAAC;SAC/C,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC;SACvB,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC;SAC1B,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjG,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,KAAK,CAAC,GAAG,gBAAgB,OAAO,IAAI,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACnE,CAAC"}
package/dist/time.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Injectable time seams. Tests pass a fixed clock and a recording sleep so no
3
+ * test ever waits on a wall clock or reaches the network.
4
+ */
5
+ export interface Clock {
6
+ now(): number;
7
+ }
8
+ export declare const systemClock: Clock;
9
+ export type Sleep = (milliseconds: number, signal?: AbortSignal) => Promise<void>;
10
+ /** Sleep that rejects immediately when the supplied signal aborts. */
11
+ export declare const systemSleep: Sleep;
12
+ //# sourceMappingURL=time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,KAAK;IACpB,GAAG,IAAI,MAAM,CAAC;CACf;AAED,eAAO,MAAM,WAAW,EAAE,KAAiC,CAAC;AAE5D,MAAM,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAQlF,sEAAsE;AACtE,eAAO,MAAM,WAAW,EAAE,KAgBtB,CAAC"}
package/dist/time.js ADDED
@@ -0,0 +1,24 @@
1
+ export const systemClock = { now: () => Date.now() };
2
+ function abortError() {
3
+ const error = new Error("aborted");
4
+ error.name = "AbortError";
5
+ return error;
6
+ }
7
+ /** Sleep that rejects immediately when the supplied signal aborts. */
8
+ export const systemSleep = (milliseconds, signal) => new Promise((resolve, reject) => {
9
+ if (signal?.aborted) {
10
+ reject(abortError());
11
+ return;
12
+ }
13
+ const timer = setTimeout(() => {
14
+ signal?.removeEventListener("abort", onAbort);
15
+ resolve();
16
+ }, milliseconds);
17
+ function onAbort() {
18
+ clearTimeout(timer);
19
+ signal?.removeEventListener("abort", onAbort);
20
+ reject(abortError());
21
+ }
22
+ signal?.addEventListener("abort", onAbort, { once: true });
23
+ });
24
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,WAAW,GAAU,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AAI5D,SAAS,UAAU;IACjB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC;IAC1B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,WAAW,GAAU,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,CACzD,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IACpC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,YAAY,CAAC,CAAC;IACjB,SAAS,OAAO;QACd,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACvB,CAAC;IACD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * An OAuth token set. The access and refresh tokens are attached as
3
+ * non-enumerable properties, so `JSON.stringify` and `util.inspect` never reveal
4
+ * them. Only `serializeTokenSet` writes them, and only into the plugin-owned
5
+ * `0600` token file.
6
+ */
7
+ export interface TokenSet {
8
+ readonly accessToken: string;
9
+ readonly refreshToken: string | undefined;
10
+ readonly expiry: number | undefined;
11
+ readonly scopes: readonly string[];
12
+ readonly tokenType: string;
13
+ }
14
+ export declare function createTokenSet(input: {
15
+ accessToken: string;
16
+ refreshToken: string | undefined;
17
+ expiry: number | undefined;
18
+ scopes: readonly string[];
19
+ tokenType: string;
20
+ }): TokenSet;
21
+ /** Serialize for disk. This is the only place token material is written out. */
22
+ export declare function serializeTokenSet(token: TokenSet): string;
23
+ /** Validate a parsed token file. Never echoes any value on failure. */
24
+ export declare function parseTokenSet(raw: unknown): TokenSet;
25
+ export declare function isExpired(token: TokenSet, now: number, skewMs: number): boolean;
26
+ //# sourceMappingURL=token-set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-set.d.ts","sourceRoot":"","sources":["../src/token-set.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,QAAQ,CAyBX;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAUzD;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAqBpD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAG/E"}
@@ -0,0 +1,62 @@
1
+ import { GoogleChatError } from "./errors.js";
2
+ export function createTokenSet(input) {
3
+ const token = {};
4
+ Object.defineProperties(token, {
5
+ accessToken: {
6
+ value: input.accessToken,
7
+ enumerable: false,
8
+ writable: false,
9
+ configurable: false,
10
+ },
11
+ refreshToken: {
12
+ value: input.refreshToken,
13
+ enumerable: false,
14
+ writable: false,
15
+ configurable: false,
16
+ },
17
+ expiry: { value: input.expiry, enumerable: true, writable: false, configurable: false },
18
+ scopes: {
19
+ value: Object.freeze([...input.scopes]),
20
+ enumerable: true,
21
+ writable: false,
22
+ configurable: false,
23
+ },
24
+ tokenType: { value: input.tokenType, enumerable: true, writable: false, configurable: false },
25
+ });
26
+ return Object.freeze(token);
27
+ }
28
+ /** Serialize for disk. This is the only place token material is written out. */
29
+ export function serializeTokenSet(token) {
30
+ const record = {
31
+ version: 1,
32
+ accessToken: token.accessToken,
33
+ expiry: token.expiry ?? null,
34
+ scopes: [...token.scopes],
35
+ tokenType: token.tokenType,
36
+ };
37
+ if (token.refreshToken !== undefined)
38
+ record.refreshToken = token.refreshToken;
39
+ return `${JSON.stringify(record, null, 2)}\n`;
40
+ }
41
+ /** Validate a parsed token file. Never echoes any value on failure. */
42
+ export function parseTokenSet(raw) {
43
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
44
+ throw new GoogleChatError("configuration missing or invalid", "the stored Google Chat token file is malformed; delete it and run google-chat-auth again");
45
+ const value = raw;
46
+ const accessToken = value.accessToken;
47
+ if (typeof accessToken !== "string" || accessToken === "")
48
+ throw new GoogleChatError("configuration missing or invalid", "the stored Google Chat token file has no access token; run google-chat-auth again");
49
+ const refreshToken = typeof value.refreshToken === "string" ? value.refreshToken : undefined;
50
+ const expiry = typeof value.expiry === "number" && Number.isFinite(value.expiry) ? value.expiry : undefined;
51
+ const scopes = Array.isArray(value.scopes)
52
+ ? value.scopes.filter((scope) => typeof scope === "string")
53
+ : [];
54
+ const tokenType = typeof value.tokenType === "string" ? value.tokenType : "Bearer";
55
+ return createTokenSet({ accessToken, refreshToken, expiry, scopes, tokenType });
56
+ }
57
+ export function isExpired(token, now, skewMs) {
58
+ if (token.expiry === undefined)
59
+ return false;
60
+ return now >= token.expiry - skewMs;
61
+ }
62
+ //# sourceMappingURL=token-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-set.js","sourceRoot":"","sources":["../src/token-set.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { OAuthConfig } from "./config.js";
2
+ import type { Clock } from "./time.js";
3
+ import { type TokenSet } from "./token-set.js";
4
+ import type { Fetcher } from "./transport.js";
5
+ export * from "./token-set.js";
6
+ /** Plugin-owned token persistence at `<configHome>/google-chat/token.json`. */
7
+ export declare class TokenStore {
8
+ readonly path: string;
9
+ constructor(path: string);
10
+ read(): TokenSet | null;
11
+ /** Atomically write the token file with `0600`, creating parents with `0700`. */
12
+ write(token: TokenSet): void;
13
+ clear(): void;
14
+ }
15
+ export interface RefreshContext {
16
+ oauth: OAuthConfig;
17
+ fetcher: Fetcher;
18
+ clock: Clock;
19
+ signal: AbortSignal;
20
+ skewMs: number;
21
+ }
22
+ /**
23
+ * Return a usable access token, refreshing once when the stored token is
24
+ * expired. A refresh failure that reports `invalid_grant` clears the store so
25
+ * the operator is told to re-authorize instead of retrying a dead token.
26
+ */
27
+ export declare function obtainAccessToken(store: TokenStore, context: RefreshContext, options?: {
28
+ force?: boolean;
29
+ }): Promise<TokenSet>;
30
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,cAAc,gBAAgB,CAAC;AAE/B,+EAA+E;AAC/E,qBAAa,UAAU;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,IAAI,EAAE,MAAM,EAEvB;IAED,IAAI,IAAI,QAAQ,GAAG,IAAI,CAqBtB;IAED,iFAAiF;IACjF,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CA2B3B;IAED,KAAK,IAAI,IAAI,CAMZ;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,QAAQ,CAAC,CA4CnB"}
package/dist/token.js ADDED
@@ -0,0 +1,119 @@
1
+ import { chmodSync, closeSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeSync, } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { GoogleChatError } from "./errors.js";
4
+ import { refreshAccessToken } from "./oauth.js";
5
+ import { createTokenSet, isExpired, parseTokenSet, serializeTokenSet, } from "./token-set.js";
6
+ export * from "./token-set.js";
7
+ /** Plugin-owned token persistence at `<configHome>/google-chat/token.json`. */
8
+ export class TokenStore {
9
+ path;
10
+ constructor(path) {
11
+ this.path = path;
12
+ }
13
+ read() {
14
+ let text;
15
+ try {
16
+ text = readFileSync(this.path, "utf8");
17
+ }
18
+ catch (error) {
19
+ if (error.code === "ENOENT")
20
+ return null;
21
+ throw new GoogleChatError("configuration missing or invalid", "the stored Google Chat token file could not be read");
22
+ }
23
+ let parsed;
24
+ try {
25
+ parsed = JSON.parse(text);
26
+ }
27
+ catch {
28
+ throw new GoogleChatError("configuration missing or invalid", "the stored Google Chat token file is not valid JSON; delete it and run google-chat-auth again");
29
+ }
30
+ return parseTokenSet(parsed);
31
+ }
32
+ /** Atomically write the token file with `0600`, creating parents with `0700`. */
33
+ write(token) {
34
+ const directory = dirname(this.path);
35
+ mkdirSync(directory, { recursive: true, mode: 0o700 });
36
+ try {
37
+ chmodSync(directory, 0o700);
38
+ }
39
+ catch {
40
+ // Hardening only.
41
+ }
42
+ const temp = `${this.path}.${process.pid}.tmp`;
43
+ const descriptor = openSync(temp, "w", 0o600);
44
+ try {
45
+ writeSync(descriptor, serializeTokenSet(token), 0, "utf8");
46
+ fsyncSync(descriptor);
47
+ }
48
+ finally {
49
+ closeSync(descriptor);
50
+ }
51
+ try {
52
+ chmodSync(temp, 0o600);
53
+ }
54
+ catch {
55
+ // Hardening only.
56
+ }
57
+ renameSync(temp, this.path);
58
+ try {
59
+ chmodSync(this.path, 0o600);
60
+ }
61
+ catch {
62
+ // Hardening only.
63
+ }
64
+ }
65
+ clear() {
66
+ try {
67
+ rmSync(this.path, { force: true });
68
+ }
69
+ catch {
70
+ // Best effort; the file may already be absent.
71
+ }
72
+ }
73
+ }
74
+ /**
75
+ * Return a usable access token, refreshing once when the stored token is
76
+ * expired. A refresh failure that reports `invalid_grant` clears the store so
77
+ * the operator is told to re-authorize instead of retrying a dead token.
78
+ */
79
+ export async function obtainAccessToken(store, context, options = {}) {
80
+ const current = store.read();
81
+ if (current === null)
82
+ throw new GoogleChatError("not authenticated", "no stored Google authorization; run google-chat-auth to authorize a user account");
83
+ if (options.force !== true && !isExpired(current, context.clock.now(), context.skewMs))
84
+ return current;
85
+ if (current.refreshToken === undefined)
86
+ throw new GoogleChatError("not authenticated", "the stored Google authorization expired and has no refresh token; run google-chat-auth again");
87
+ let refreshed;
88
+ try {
89
+ refreshed = await refreshAccessToken({
90
+ config: context.oauth,
91
+ refreshToken: current.refreshToken,
92
+ fetcher: context.fetcher,
93
+ signal: context.signal,
94
+ });
95
+ }
96
+ catch (error) {
97
+ if (error instanceof GoogleChatError && error.code === "not authenticated") {
98
+ try {
99
+ store.clear();
100
+ }
101
+ catch {
102
+ // Clearing is best effort; the original error is what matters.
103
+ }
104
+ }
105
+ throw error;
106
+ }
107
+ const next = createTokenSet({
108
+ accessToken: refreshed.accessToken,
109
+ refreshToken: refreshed.refreshToken ?? current.refreshToken,
110
+ expiry: refreshed.expiresIn === undefined
111
+ ? current.expiry
112
+ : context.clock.now() + refreshed.expiresIn * 1000,
113
+ scopes: refreshed.scopes.length > 0 ? refreshed.scopes : current.scopes,
114
+ tokenType: refreshed.tokenType,
115
+ });
116
+ store.write(next);
117
+ return next;
118
+ }
119
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,MAAM,EACN,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,EACL,cAAc,EACd,SAAS,EACT,aAAa,EACb,iBAAiB,GAElB,MAAM,gBAAgB,CAAC;AAGxB,cAAc,gBAAgB,CAAC;AAE/B,+EAA+E;AAC/E,MAAM,OAAO,UAAU;IACZ,IAAI,CAAS;IAEtB,YAAY,IAAY;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,IAAI;QACF,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACpE,MAAM,IAAI,eAAe,CACvB,kCAAkC,EAClC,qDAAqD,CACtD,CAAC;QACJ,CAAC;QACD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,eAAe,CACvB,kCAAkC,EAClC,+FAA+F,CAChG,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,iFAAiF;IACjF,KAAK,CAAC,KAAe;QACnB,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;QAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC;YACH,SAAS,CAAC,UAAU,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YAC3D,SAAS,CAAC,UAAU,CAAC,CAAC;QACxB,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,UAAU,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,CAAC;YACH,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;QACD,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,+CAA+C;QACjD,CAAC;IACH,CAAC;CACF;AAUD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAiB,EACjB,OAAuB,EACvB,OAAO,GAAwB,EAAE;IAEjC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,KAAK,IAAI;QAClB,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,kFAAkF,CACnF,CAAC;IACJ,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC;QACpF,OAAO,OAAO,CAAC;IACjB,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;QACpC,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,8FAA8F,CAC/F,CAAC;IACJ,IAAI,SAAyD,CAAC;IAC9D,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,kBAAkB,CAAC;YACnC,MAAM,EAAE,OAAO,CAAC,KAAK;YACrB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YAC3E,IAAI,CAAC;gBACH,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,+DAA+D;YACjE,CAAC;QACH,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,cAAc,CAAC;QAC1B,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,YAAY,EAAE,SAAS,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY;QAC5D,MAAM,EACJ,SAAS,CAAC,SAAS,KAAK,SAAS;YAC/B,CAAC,CAAC,OAAO,CAAC,MAAM;YAChB,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,SAAS,GAAG,IAAI;QACtD,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM;QACvE,SAAS,EAAE,SAAS,CAAC,SAAS;KAC/B,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { JsonSchema, ToolDefinition } from "@alisio/sdk";
2
+ export interface ToolSpec {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JsonSchema;
6
+ run(input: Record<string, unknown>, context: {
7
+ signal: AbortSignal;
8
+ }): Promise<string>;
9
+ }
10
+ /** A read-only tool: it transmits data but never mutates remote state. */
11
+ export declare function externalTool(spec: ToolSpec): ToolDefinition;
12
+ /** A mutating tool. Capability gating happens inside `run`, before any request. */
13
+ export declare function writeTool(spec: ToolSpec): ToolDefinition;
14
+ //# sourceMappingURL=toolkit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolkit.d.ts","sourceRoot":"","sources":["../src/toolkit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAc,MAAM,aAAa,CAAC;AAG1E,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxF;AAMD,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAc3D;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAcxD"}
@@ -0,0 +1,39 @@
1
+ import { safeMessage } from "./errors.js";
2
+ function errorResult(error) {
3
+ return { isError: true, content: [{ type: "text", text: safeMessage(error) }] };
4
+ }
5
+ /** A read-only tool: it transmits data but never mutates remote state. */
6
+ export function externalTool(spec) {
7
+ return {
8
+ name: spec.name,
9
+ description: spec.description,
10
+ effect: "external",
11
+ inputSchema: spec.inputSchema,
12
+ async execute(input, context) {
13
+ try {
14
+ return { content: [{ type: "text", text: await spec.run(input, context) }] };
15
+ }
16
+ catch (error) {
17
+ return errorResult(error);
18
+ }
19
+ },
20
+ };
21
+ }
22
+ /** A mutating tool. Capability gating happens inside `run`, before any request. */
23
+ export function writeTool(spec) {
24
+ return {
25
+ name: spec.name,
26
+ description: spec.description,
27
+ effect: "write",
28
+ inputSchema: spec.inputSchema,
29
+ async execute(input, context) {
30
+ try {
31
+ return { content: [{ type: "text", text: await spec.run(input, context) }] };
32
+ }
33
+ catch (error) {
34
+ return errorResult(error);
35
+ }
36
+ },
37
+ };
38
+ }
39
+ //# sourceMappingURL=toolkit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolkit.js","sourceRoot":"","sources":["../src/toolkit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAS1C,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AAClF,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,UAAU;QAClB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO;YAC1B,IAAI,CAAC;gBACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,OAAO;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO;YAC1B,IAAI,CAAC;gBACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ToolDefinition } from "@alisio/sdk";
2
+ import type { GoogleChatClient } from "./http.js";
3
+ /** Build the seven Google Chat tools. Reads are `external`; mutations are `write`. */
4
+ export declare function createGoogleChatTools(client: GoogleChatClient): ToolDefinition[];
5
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,WAAW,CAAC;AAmD9D,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,cAAc,EAAE,CAqThF"}