@aui.io/apollo 0.1.4

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 (194) hide show
  1. package/bin/apollo.js +13 -0
  2. package/node_modules/@aui.io/apollo-cli/bin/apollo.js +79 -0
  3. package/node_modules/@aui.io/apollo-cli/dist/src/commands/auth.d.ts +4 -0
  4. package/node_modules/@aui.io/apollo-cli/dist/src/commands/auth.js +99 -0
  5. package/node_modules/@aui.io/apollo-cli/dist/src/commands/auth.js.map +1 -0
  6. package/node_modules/@aui.io/apollo-cli/dist/src/commands/bundles.d.ts +3 -0
  7. package/node_modules/@aui.io/apollo-cli/dist/src/commands/bundles.js +234 -0
  8. package/node_modules/@aui.io/apollo-cli/dist/src/commands/bundles.js.map +1 -0
  9. package/node_modules/@aui.io/apollo-cli/dist/src/commands/env.d.ts +3 -0
  10. package/node_modules/@aui.io/apollo-cli/dist/src/commands/env.js +34 -0
  11. package/node_modules/@aui.io/apollo-cli/dist/src/commands/env.js.map +1 -0
  12. package/node_modules/@aui.io/apollo-cli/dist/src/commands/hierarchy.d.ts +3 -0
  13. package/node_modules/@aui.io/apollo-cli/dist/src/commands/hierarchy.js +175 -0
  14. package/node_modules/@aui.io/apollo-cli/dist/src/commands/hierarchy.js.map +1 -0
  15. package/node_modules/@aui.io/apollo-cli/dist/src/commands/mockdb.d.ts +3 -0
  16. package/node_modules/@aui.io/apollo-cli/dist/src/commands/mockdb.js +251 -0
  17. package/node_modules/@aui.io/apollo-cli/dist/src/commands/mockdb.js.map +1 -0
  18. package/node_modules/@aui.io/apollo-cli/dist/src/commands/operate.d.ts +3 -0
  19. package/node_modules/@aui.io/apollo-cli/dist/src/commands/operate.js +138 -0
  20. package/node_modules/@aui.io/apollo-cli/dist/src/commands/operate.js.map +1 -0
  21. package/node_modules/@aui.io/apollo-cli/dist/src/commands/profile.d.ts +3 -0
  22. package/node_modules/@aui.io/apollo-cli/dist/src/commands/profile.js +51 -0
  23. package/node_modules/@aui.io/apollo-cli/dist/src/commands/profile.js.map +1 -0
  24. package/node_modules/@aui.io/apollo-cli/dist/src/commands/prompts.d.ts +6 -0
  25. package/node_modules/@aui.io/apollo-cli/dist/src/commands/prompts.js +20 -0
  26. package/node_modules/@aui.io/apollo-cli/dist/src/commands/prompts.js.map +1 -0
  27. package/node_modules/@aui.io/apollo-cli/dist/src/commands/runtime.d.ts +6 -0
  28. package/node_modules/@aui.io/apollo-cli/dist/src/commands/runtime.js +2 -0
  29. package/node_modules/@aui.io/apollo-cli/dist/src/commands/runtime.js.map +1 -0
  30. package/node_modules/@aui.io/apollo-cli/dist/src/commands/shell.d.ts +10 -0
  31. package/node_modules/@aui.io/apollo-cli/dist/src/commands/shell.js +36 -0
  32. package/node_modules/@aui.io/apollo-cli/dist/src/commands/shell.js.map +1 -0
  33. package/node_modules/@aui.io/apollo-cli/dist/src/commands/status.d.ts +3 -0
  34. package/node_modules/@aui.io/apollo-cli/dist/src/commands/status.js +57 -0
  35. package/node_modules/@aui.io/apollo-cli/dist/src/commands/status.js.map +1 -0
  36. package/node_modules/@aui.io/apollo-cli/dist/src/commands/upgrade.d.ts +3 -0
  37. package/node_modules/@aui.io/apollo-cli/dist/src/commands/upgrade.js +35 -0
  38. package/node_modules/@aui.io/apollo-cli/dist/src/commands/upgrade.js.map +1 -0
  39. package/node_modules/@aui.io/apollo-cli/dist/src/commands/workspace.d.ts +3 -0
  40. package/node_modules/@aui.io/apollo-cli/dist/src/commands/workspace.js +170 -0
  41. package/node_modules/@aui.io/apollo-cli/dist/src/commands/workspace.js.map +1 -0
  42. package/node_modules/@aui.io/apollo-cli/dist/src/index.d.ts +10 -0
  43. package/node_modules/@aui.io/apollo-cli/dist/src/index.js +107 -0
  44. package/node_modules/@aui.io/apollo-cli/dist/src/index.js.map +1 -0
  45. package/node_modules/@aui.io/apollo-cli/dist/src/meta.d.ts +4 -0
  46. package/node_modules/@aui.io/apollo-cli/dist/src/meta.js +65 -0
  47. package/node_modules/@aui.io/apollo-cli/dist/src/meta.js.map +1 -0
  48. package/node_modules/@aui.io/apollo-cli/dist/src/output/welcome.d.ts +13 -0
  49. package/node_modules/@aui.io/apollo-cli/dist/src/output/welcome.js +53 -0
  50. package/node_modules/@aui.io/apollo-cli/dist/src/output/welcome.js.map +1 -0
  51. package/node_modules/@aui.io/apollo-cli/package.json +47 -0
  52. package/node_modules/@aui.io/apollo-core/dist/src/api/agent-settings.d.ts +6 -0
  53. package/node_modules/@aui.io/apollo-core/dist/src/api/agent-settings.js +23 -0
  54. package/node_modules/@aui.io/apollo-core/dist/src/api/agent-settings.js.map +1 -0
  55. package/node_modules/@aui.io/apollo-core/dist/src/api/client-types.d.ts +23 -0
  56. package/node_modules/@aui.io/apollo-core/dist/src/api/client-types.js +2 -0
  57. package/node_modules/@aui.io/apollo-core/dist/src/api/client-types.js.map +1 -0
  58. package/node_modules/@aui.io/apollo-core/dist/src/api/identity.d.ts +48 -0
  59. package/node_modules/@aui.io/apollo-core/dist/src/api/identity.js +131 -0
  60. package/node_modules/@aui.io/apollo-core/dist/src/api/identity.js.map +1 -0
  61. package/node_modules/@aui.io/apollo-core/dist/src/api/management.d.ts +92 -0
  62. package/node_modules/@aui.io/apollo-core/dist/src/api/management.js +126 -0
  63. package/node_modules/@aui.io/apollo-core/dist/src/api/management.js.map +1 -0
  64. package/node_modules/@aui.io/apollo-core/dist/src/api/mock-db.d.ts +65 -0
  65. package/node_modules/@aui.io/apollo-core/dist/src/api/mock-db.js +183 -0
  66. package/node_modules/@aui.io/apollo-core/dist/src/api/mock-db.js.map +1 -0
  67. package/node_modules/@aui.io/apollo-core/dist/src/api/runtime-api.d.ts +98 -0
  68. package/node_modules/@aui.io/apollo-core/dist/src/api/runtime-api.js +70 -0
  69. package/node_modules/@aui.io/apollo-core/dist/src/api/runtime-api.js.map +1 -0
  70. package/node_modules/@aui.io/apollo-core/dist/src/api/transport.d.ts +40 -0
  71. package/node_modules/@aui.io/apollo-core/dist/src/api/transport.js +205 -0
  72. package/node_modules/@aui.io/apollo-core/dist/src/api/transport.js.map +1 -0
  73. package/node_modules/@aui.io/apollo-core/dist/src/argv.d.ts +5 -0
  74. package/node_modules/@aui.io/apollo-core/dist/src/argv.js +43 -0
  75. package/node_modules/@aui.io/apollo-core/dist/src/argv.js.map +1 -0
  76. package/node_modules/@aui.io/apollo-core/dist/src/bundle/baseline.d.ts +17 -0
  77. package/node_modules/@aui.io/apollo-core/dist/src/bundle/baseline.js +48 -0
  78. package/node_modules/@aui.io/apollo-core/dist/src/bundle/baseline.js.map +1 -0
  79. package/node_modules/@aui.io/apollo-core/dist/src/bundle/files.d.ts +7 -0
  80. package/node_modules/@aui.io/apollo-core/dist/src/bundle/files.js +69 -0
  81. package/node_modules/@aui.io/apollo-core/dist/src/bundle/files.js.map +1 -0
  82. package/node_modules/@aui.io/apollo-core/dist/src/bundle/materialize.d.ts +14 -0
  83. package/node_modules/@aui.io/apollo-core/dist/src/bundle/materialize.js +196 -0
  84. package/node_modules/@aui.io/apollo-core/dist/src/bundle/materialize.js.map +1 -0
  85. package/node_modules/@aui.io/apollo-core/dist/src/bundle/validate.d.ts +30 -0
  86. package/node_modules/@aui.io/apollo-core/dist/src/bundle/validate.js +36 -0
  87. package/node_modules/@aui.io/apollo-core/dist/src/bundle/validate.js.map +1 -0
  88. package/node_modules/@aui.io/apollo-core/dist/src/config/index.d.ts +11 -0
  89. package/node_modules/@aui.io/apollo-core/dist/src/config/index.js +193 -0
  90. package/node_modules/@aui.io/apollo-core/dist/src/config/index.js.map +1 -0
  91. package/node_modules/@aui.io/apollo-core/dist/src/config/mockdb-keys.d.ts +14 -0
  92. package/node_modules/@aui.io/apollo-core/dist/src/config/mockdb-keys.js +54 -0
  93. package/node_modules/@aui.io/apollo-core/dist/src/config/mockdb-keys.js.map +1 -0
  94. package/node_modules/@aui.io/apollo-core/dist/src/config/store.d.ts +18 -0
  95. package/node_modules/@aui.io/apollo-core/dist/src/config/store.js +99 -0
  96. package/node_modules/@aui.io/apollo-core/dist/src/config/store.js.map +1 -0
  97. package/node_modules/@aui.io/apollo-core/dist/src/config/types.d.ts +62 -0
  98. package/node_modules/@aui.io/apollo-core/dist/src/config/types.js +2 -0
  99. package/node_modules/@aui.io/apollo-core/dist/src/config/types.js.map +1 -0
  100. package/node_modules/@aui.io/apollo-core/dist/src/errors/index.d.ts +42 -0
  101. package/node_modules/@aui.io/apollo-core/dist/src/errors/index.js +74 -0
  102. package/node_modules/@aui.io/apollo-core/dist/src/errors/index.js.map +1 -0
  103. package/node_modules/@aui.io/apollo-core/dist/src/index.d.ts +32 -0
  104. package/node_modules/@aui.io/apollo-core/dist/src/index.js +32 -0
  105. package/node_modules/@aui.io/apollo-core/dist/src/index.js.map +1 -0
  106. package/node_modules/@aui.io/apollo-core/dist/src/output/index.d.ts +29 -0
  107. package/node_modules/@aui.io/apollo-core/dist/src/output/index.js +49 -0
  108. package/node_modules/@aui.io/apollo-core/dist/src/output/index.js.map +1 -0
  109. package/node_modules/@aui.io/apollo-core/dist/src/services/auth.d.ts +10 -0
  110. package/node_modules/@aui.io/apollo-core/dist/src/services/auth.js +83 -0
  111. package/node_modules/@aui.io/apollo-core/dist/src/services/auth.js.map +1 -0
  112. package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.d.ts +37 -0
  113. package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.js +161 -0
  114. package/node_modules/@aui.io/apollo-core/dist/src/services/bundles.js.map +1 -0
  115. package/node_modules/@aui.io/apollo-core/dist/src/services/clients.d.ts +15 -0
  116. package/node_modules/@aui.io/apollo-core/dist/src/services/clients.js +95 -0
  117. package/node_modules/@aui.io/apollo-core/dist/src/services/clients.js.map +1 -0
  118. package/node_modules/@aui.io/apollo-core/dist/src/services/env.service.d.ts +11 -0
  119. package/node_modules/@aui.io/apollo-core/dist/src/services/env.service.js +19 -0
  120. package/node_modules/@aui.io/apollo-core/dist/src/services/env.service.js.map +1 -0
  121. package/node_modules/@aui.io/apollo-core/dist/src/services/hierarchy.d.ts +29 -0
  122. package/node_modules/@aui.io/apollo-core/dist/src/services/hierarchy.js +117 -0
  123. package/node_modules/@aui.io/apollo-core/dist/src/services/hierarchy.js.map +1 -0
  124. package/node_modules/@aui.io/apollo-core/dist/src/services/messaging.d.ts +17 -0
  125. package/node_modules/@aui.io/apollo-core/dist/src/services/messaging.js +99 -0
  126. package/node_modules/@aui.io/apollo-core/dist/src/services/messaging.js.map +1 -0
  127. package/node_modules/@aui.io/apollo-core/dist/src/services/mockdb.d.ts +71 -0
  128. package/node_modules/@aui.io/apollo-core/dist/src/services/mockdb.js +274 -0
  129. package/node_modules/@aui.io/apollo-core/dist/src/services/mockdb.js.map +1 -0
  130. package/node_modules/@aui.io/apollo-core/dist/src/services/profile.service.d.ts +16 -0
  131. package/node_modules/@aui.io/apollo-core/dist/src/services/profile.service.js +29 -0
  132. package/node_modules/@aui.io/apollo-core/dist/src/services/profile.service.js.map +1 -0
  133. package/node_modules/@aui.io/apollo-core/dist/src/services/status.service.d.ts +26 -0
  134. package/node_modules/@aui.io/apollo-core/dist/src/services/status.service.js +109 -0
  135. package/node_modules/@aui.io/apollo-core/dist/src/services/status.service.js.map +1 -0
  136. package/node_modules/@aui.io/apollo-core/dist/src/services/upgrade.d.ts +23 -0
  137. package/node_modules/@aui.io/apollo-core/dist/src/services/upgrade.js +74 -0
  138. package/node_modules/@aui.io/apollo-core/dist/src/services/upgrade.js.map +1 -0
  139. package/node_modules/@aui.io/apollo-core/dist/src/services/workspace.service.d.ts +44 -0
  140. package/node_modules/@aui.io/apollo-core/dist/src/services/workspace.service.js +148 -0
  141. package/node_modules/@aui.io/apollo-core/dist/src/services/workspace.service.js.map +1 -0
  142. package/node_modules/@aui.io/apollo-core/dist/src/skills/install.d.ts +6 -0
  143. package/node_modules/@aui.io/apollo-core/dist/src/skills/install.js +48 -0
  144. package/node_modules/@aui.io/apollo-core/dist/src/skills/install.js.map +1 -0
  145. package/node_modules/@aui.io/apollo-core/dist/src/workspace/store.d.ts +33 -0
  146. package/node_modules/@aui.io/apollo-core/dist/src/workspace/store.js +246 -0
  147. package/node_modules/@aui.io/apollo-core/dist/src/workspace/store.js.map +1 -0
  148. package/node_modules/@aui.io/apollo-core/package.json +48 -0
  149. package/node_modules/@aui.io/apollo-tui/bin/apollo-tui.js +5 -0
  150. package/node_modules/@aui.io/apollo-tui/dist/src/components/glyph.d.ts +19 -0
  151. package/node_modules/@aui.io/apollo-tui/dist/src/components/glyph.js +41 -0
  152. package/node_modules/@aui.io/apollo-tui/dist/src/components/glyph.js.map +1 -0
  153. package/node_modules/@aui.io/apollo-tui/dist/src/index.d.ts +5 -0
  154. package/node_modules/@aui.io/apollo-tui/dist/src/index.js +46 -0
  155. package/node_modules/@aui.io/apollo-tui/dist/src/index.js.map +1 -0
  156. package/node_modules/@aui.io/apollo-tui/dist/src/lib/attractor.d.ts +82 -0
  157. package/node_modules/@aui.io/apollo-tui/dist/src/lib/attractor.js +231 -0
  158. package/node_modules/@aui.io/apollo-tui/dist/src/lib/attractor.js.map +1 -0
  159. package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.d.ts +34 -0
  160. package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.js +100 -0
  161. package/node_modules/@aui.io/apollo-tui/dist/src/lib/commands.js.map +1 -0
  162. package/node_modules/@aui.io/apollo-tui/dist/src/lib/scope.d.ts +14 -0
  163. package/node_modules/@aui.io/apollo-tui/dist/src/lib/scope.js +25 -0
  164. package/node_modules/@aui.io/apollo-tui/dist/src/lib/scope.js.map +1 -0
  165. package/node_modules/@aui.io/apollo-tui/dist/src/lib/sheet.d.ts +25 -0
  166. package/node_modules/@aui.io/apollo-tui/dist/src/lib/sheet.js +99 -0
  167. package/node_modules/@aui.io/apollo-tui/dist/src/lib/sheet.js.map +1 -0
  168. package/node_modules/@aui.io/apollo-tui/dist/src/lib/tabs.d.ts +10 -0
  169. package/node_modules/@aui.io/apollo-tui/dist/src/lib/tabs.js +19 -0
  170. package/node_modules/@aui.io/apollo-tui/dist/src/lib/tabs.js.map +1 -0
  171. package/node_modules/@aui.io/apollo-tui/dist/src/opentui-app.d.ts +1 -0
  172. package/node_modules/@aui.io/apollo-tui/dist/src/opentui-app.js +449 -0
  173. package/node_modules/@aui.io/apollo-tui/dist/src/opentui-app.js.map +1 -0
  174. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/bundle.d.ts +1 -0
  175. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/bundle.js +4 -0
  176. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/bundle.js.map +1 -0
  177. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/chat.d.ts +1 -0
  178. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/chat.js +4 -0
  179. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/chat.js.map +1 -0
  180. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/index.d.ts +5 -0
  181. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/index.js +6 -0
  182. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/index.js.map +1 -0
  183. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/mockdb.d.ts +1 -0
  184. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/mockdb.js +4 -0
  185. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/mockdb.js.map +1 -0
  186. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/overview.d.ts +1 -0
  187. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/overview.js +4 -0
  188. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/overview.js.map +1 -0
  189. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/scope.d.ts +1 -0
  190. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/scope.js +4 -0
  191. package/node_modules/@aui.io/apollo-tui/dist/src/tabs/scope.js.map +1 -0
  192. package/node_modules/@aui.io/apollo-tui/package.json +53 -0
  193. package/package.json +42 -0
  194. package/scripts/setup-shell.mjs +68 -0
@@ -0,0 +1,205 @@
1
+ import { mkdir, rename, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import path from "node:path";
4
+ import { ApiError, AuthError, CliError } from "../errors/index.js";
5
+ export class Transport {
6
+ options;
7
+ captures = [];
8
+ token;
9
+ fetchImpl;
10
+ constructor(options) {
11
+ this.options = options;
12
+ this.token = options.token;
13
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
14
+ }
15
+ async request(path, requestOptions = {}) {
16
+ const method = requestOptions.method ?? "GET";
17
+ let refreshed = false;
18
+ let networkRetried = false;
19
+ for (;;) {
20
+ try {
21
+ const response = await this.perform(path, requestOptions, method);
22
+ if (response.status === 401 &&
23
+ !refreshed &&
24
+ this.options.refresh !== undefined) {
25
+ this.token = await this.options.refresh();
26
+ refreshed = true;
27
+ continue;
28
+ }
29
+ if (!response.ok)
30
+ throw await this.apiError(path, response);
31
+ if (response.status === 204)
32
+ return undefined;
33
+ return (await parseResponse(response));
34
+ }
35
+ catch (error) {
36
+ if (method === "GET" &&
37
+ !networkRetried &&
38
+ !(error instanceof ApiError) &&
39
+ !(error instanceof AuthError) &&
40
+ !(error instanceof CliError && error.code === "REQUEST_TIMEOUT")) {
41
+ networkRetried = true;
42
+ continue;
43
+ }
44
+ throw error;
45
+ }
46
+ }
47
+ }
48
+ async perform(path, requestOptions, method) {
49
+ const authenticated = requestOptions.authenticated ?? true;
50
+ if (authenticated && this.token === undefined) {
51
+ throw new AuthError(`Authentication is required for ${this.options.service}.`);
52
+ }
53
+ const baseUrl = `${this.options.baseUrl.replace(/\/+$/, "")}/`;
54
+ const url = new URL(path.replace(/^\/+/, ""), baseUrl);
55
+ for (const [key, value] of Object.entries(requestOptions.query ?? {})) {
56
+ if (value !== undefined)
57
+ url.searchParams.append(key, String(value));
58
+ }
59
+ const headers = new Headers(requestOptions.headers);
60
+ headers.set("accept", "application/json");
61
+ if (authenticated && this.token !== undefined) {
62
+ const authHeader = this.options.authHeader ?? "authorization";
63
+ headers.set(authHeader, authHeader.toLowerCase() === "authorization"
64
+ ? `Bearer ${this.token}`
65
+ : this.token);
66
+ }
67
+ if (this.options.orgId !== undefined && this.options.orgHeader !== undefined) {
68
+ headers.set(this.options.orgHeader, this.options.orgId);
69
+ }
70
+ if (requestOptions.attribution === true) {
71
+ if (this.options.userId === undefined) {
72
+ throw new AuthError("User attribution is required for this operation.");
73
+ }
74
+ headers.set("x-aui-user-id", this.options.userId);
75
+ }
76
+ const body = requestOptions.body === undefined
77
+ ? undefined
78
+ : JSON.stringify(requestOptions.body);
79
+ if (body !== undefined)
80
+ headers.set("content-type", "application/json");
81
+ const controller = new AbortController();
82
+ const timer = setTimeout(() => controller.abort(), this.options.timeoutMs);
83
+ const started = performance.now();
84
+ const capture = {
85
+ method,
86
+ url: url.toString(),
87
+ headers: redactHeaders(headers),
88
+ ...(requestOptions.body === undefined
89
+ ? {}
90
+ : { body: redact(requestOptions.body) }),
91
+ durationMs: 0,
92
+ };
93
+ try {
94
+ const response = await this.fetchImpl(url, {
95
+ method,
96
+ headers,
97
+ signal: controller.signal,
98
+ ...(body === undefined ? {} : { body }),
99
+ });
100
+ capture.status = response.status;
101
+ return response;
102
+ }
103
+ catch (error) {
104
+ if (controller.signal.aborted) {
105
+ throw new CliError(`${this.options.service} request timed out after ${this.options.timeoutMs}ms.`, { code: "REQUEST_TIMEOUT", cause: error });
106
+ }
107
+ throw error;
108
+ }
109
+ finally {
110
+ clearTimeout(timer);
111
+ capture.durationMs = Math.round(performance.now() - started);
112
+ this.captures.push(capture);
113
+ if (this.captures.length > 50)
114
+ this.captures.shift();
115
+ await this.persistCaptures();
116
+ }
117
+ }
118
+ async persistCaptures() {
119
+ const configured = this.options.capturePath;
120
+ const target = configured === false || (configured === undefined && process.env.NODE_ENV === "test")
121
+ ? undefined
122
+ : configured ?? path.join(homedir(), ".apollo", "last-requests.json");
123
+ if (!target)
124
+ return;
125
+ try {
126
+ await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
127
+ const temporary = `${target}.${process.pid}.tmp`;
128
+ await writeFile(temporary, `${JSON.stringify(this.captures, null, 2)}\n`, {
129
+ encoding: "utf8",
130
+ mode: 0o600,
131
+ });
132
+ await rename(temporary, target);
133
+ }
134
+ catch {
135
+ // Request capture must never make a successful API request fail.
136
+ }
137
+ }
138
+ async apiError(path, response) {
139
+ const detail = await parseResponse(response);
140
+ const message = extractMessage(detail, response.statusText);
141
+ return new ApiError({
142
+ service: this.options.service,
143
+ status: response.status,
144
+ path,
145
+ message,
146
+ detail,
147
+ ...(authSuggestion(response.status) === undefined
148
+ ? {}
149
+ : { suggestion: authSuggestion(response.status) }),
150
+ });
151
+ }
152
+ }
153
+ async function parseResponse(response) {
154
+ const text = await response.text();
155
+ if (text === "")
156
+ return undefined;
157
+ const contentType = response.headers.get("content-type") ?? "";
158
+ if (contentType.includes("json")) {
159
+ try {
160
+ return JSON.parse(text);
161
+ }
162
+ catch {
163
+ return text;
164
+ }
165
+ }
166
+ return text;
167
+ }
168
+ function extractMessage(detail, fallback) {
169
+ if (typeof detail === "string" && detail !== "")
170
+ return detail;
171
+ if (typeof detail === "object" && detail !== null && "detail" in detail) {
172
+ const value = detail.detail;
173
+ if (typeof value === "string")
174
+ return value;
175
+ }
176
+ return fallback || "API request failed.";
177
+ }
178
+ function authSuggestion(status) {
179
+ return status === 401 || status === 403
180
+ ? "Run `apollo login` and verify your organization access."
181
+ : undefined;
182
+ }
183
+ function redactHeaders(headers) {
184
+ return Object.fromEntries([...headers.entries()].map(([key, value]) => [
185
+ key,
186
+ isSensitive(key) ? "***" : value,
187
+ ]));
188
+ }
189
+ function redact(value, key = "") {
190
+ if (isSensitive(key))
191
+ return "***";
192
+ if (Array.isArray(value))
193
+ return value.map((item) => redact(item));
194
+ if (typeof value === "object" && value !== null) {
195
+ return Object.fromEntries(Object.entries(value).map(([childKey, childValue]) => [
196
+ childKey,
197
+ redact(childValue, childKey),
198
+ ]));
199
+ }
200
+ return value;
201
+ }
202
+ function isSensitive(key) {
203
+ return /authorization|token|key|secret/i.test(key);
204
+ }
205
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/api/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Move push-only message flags that appear before the `push` subcommand so
3
+ * `apollo --json -m "…" push` parses the same as `apollo --json push -m "…"`.
4
+ */
5
+ export declare function normalizeArgv(argv: string[]): string[];
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Move push-only message flags that appear before the `push` subcommand so
3
+ * `apollo --json -m "…" push` parses the same as `apollo --json push -m "…"`.
4
+ */
5
+ export function normalizeArgv(argv) {
6
+ const start = argv[0] === process.execPath || argv[0]?.endsWith("node") ? 2 : 0;
7
+ const prefix = argv.slice(0, start);
8
+ const args = argv.slice(start);
9
+ const pushIndex = args.findIndex((arg) => arg === "push");
10
+ if (pushIndex === -1)
11
+ return argv;
12
+ const moved = [];
13
+ let index = 0;
14
+ let commandIndex = pushIndex;
15
+ while (index < commandIndex) {
16
+ const arg = args[index];
17
+ if (arg === undefined)
18
+ break;
19
+ if (arg === "-m" || arg === "--message") {
20
+ const value = args[index + 1];
21
+ if (value === undefined || value.startsWith("-")) {
22
+ index += 1;
23
+ continue;
24
+ }
25
+ moved.push(arg, value);
26
+ args.splice(index, 2);
27
+ commandIndex -= 2;
28
+ continue;
29
+ }
30
+ if (arg.startsWith("--message=")) {
31
+ moved.push(arg);
32
+ args.splice(index, 1);
33
+ commandIndex -= 1;
34
+ continue;
35
+ }
36
+ index += 1;
37
+ }
38
+ if (moved.length === 0)
39
+ return argv;
40
+ args.splice(commandIndex + 1, 0, ...moved);
41
+ return [...prefix, ...args];
42
+ }
43
+ //# sourceMappingURL=argv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argv.js","sourceRoot":"","sources":["../../src/argv.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,MAAM,KAAK,GACT,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;IAC1D,IAAI,SAAS,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,OAAO,KAAK,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM;QAC7B,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjD,KAAK,IAAI,CAAC,CAAC;gBACX,SAAS;YACX,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACtB,YAAY,IAAI,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACtB,YAAY,IAAI,CAAC,CAAC;YAClB,SAAS;QACX,CAAC;QACD,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,17 @@
1
+ export interface Baseline {
2
+ configVersion: 1;
3
+ agentId: string;
4
+ versionTag: string;
5
+ files: Record<string, string>;
6
+ fileLayout?: Record<string, string>;
7
+ writtenAt: string;
8
+ }
9
+ export interface FileDiff {
10
+ added: string[];
11
+ changed: string[];
12
+ removed: string[];
13
+ }
14
+ export declare function writeBaseline(home: string, agentId: string, versionTag: string, files: Record<string, string>, fileLayout?: Record<string, string>): Promise<void>;
15
+ export declare function readBaseline(home: string, agentId: string): Promise<Baseline | null>;
16
+ export declare function diffHashes(baseline: Record<string, string>, currentFiles: Record<string, string>): FileDiff;
17
+ export declare function isClean(diff: FileDiff): boolean;
@@ -0,0 +1,48 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { hashFiles } from "./files.js";
4
+ function baselinePath(home, agentId) {
5
+ return path.join(home, ".apollo", "baselines", agentId, "baseline.json");
6
+ }
7
+ export async function writeBaseline(home, agentId, versionTag, files, fileLayout) {
8
+ const target = baselinePath(home, agentId);
9
+ await mkdir(path.dirname(target), { recursive: true, mode: 0o700 });
10
+ const baseline = {
11
+ configVersion: 1,
12
+ agentId,
13
+ versionTag,
14
+ files: hashFiles(files),
15
+ ...(fileLayout ? { fileLayout } : {}),
16
+ writtenAt: new Date().toISOString(),
17
+ };
18
+ await writeFile(target, `${JSON.stringify(baseline, null, 2)}\n`, {
19
+ encoding: "utf8",
20
+ mode: 0o600,
21
+ });
22
+ }
23
+ export async function readBaseline(home, agentId) {
24
+ try {
25
+ return JSON.parse(await readFile(baselinePath(home, agentId), "utf8"));
26
+ }
27
+ catch (error) {
28
+ if (error.code === "ENOENT")
29
+ return null;
30
+ throw error;
31
+ }
32
+ }
33
+ export function diffHashes(baseline, currentFiles) {
34
+ const current = hashFiles(currentFiles);
35
+ const previousPaths = new Set(Object.keys(baseline));
36
+ const currentPaths = new Set(Object.keys(current));
37
+ return {
38
+ added: [...currentPaths].filter((item) => !previousPaths.has(item)).sort(),
39
+ changed: [...currentPaths]
40
+ .filter((item) => previousPaths.has(item) && current[item] !== baseline[item])
41
+ .sort(),
42
+ removed: [...previousPaths].filter((item) => !currentPaths.has(item)).sort(),
43
+ };
44
+ }
45
+ export function isClean(diff) {
46
+ return diff.added.length === 0 && diff.changed.length === 0 && diff.removed.length === 0;
47
+ }
48
+ //# sourceMappingURL=baseline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../../src/bundle/baseline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface ProgramFiles {
2
+ root: string;
3
+ files: Record<string, string>;
4
+ }
5
+ export declare function readProgramFiles(root: string): Promise<ProgramFiles>;
6
+ export declare function hashFiles(files: Record<string, string>): Record<string, string>;
7
+ export declare function contentDigest(files: Record<string, string>): string;
@@ -0,0 +1,69 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readdir, readFile, stat } from "node:fs/promises";
3
+ import path from "node:path";
4
+ const EXCLUDED_ROOTS = new Set([
5
+ ".git",
6
+ ".cursor",
7
+ ".claude",
8
+ ".opencode",
9
+ "scenarios",
10
+ "node_modules",
11
+ "dist",
12
+ ]);
13
+ const EXCLUDED_FILES = new Set([".apollorc", ".apollo-baseline.json"]);
14
+ function isHidden(name) {
15
+ return name.startsWith(".");
16
+ }
17
+ function looksBinary(content) {
18
+ const sample = content.subarray(0, Math.min(content.length, 8_192));
19
+ return sample.includes(0);
20
+ }
21
+ export async function readProgramFiles(root) {
22
+ const absoluteRoot = path.resolve(root);
23
+ const rootStat = await stat(absoluteRoot);
24
+ if (!rootStat.isDirectory()) {
25
+ throw new Error(`Program path is not a directory: ${absoluteRoot}`);
26
+ }
27
+ const files = {};
28
+ async function walk(directory, relativeDirectory = "") {
29
+ const entries = await readdir(directory, { withFileTypes: true });
30
+ entries.sort((left, right) => left.name.localeCompare(right.name));
31
+ for (const entry of entries) {
32
+ if (EXCLUDED_FILES.has(entry.name) ||
33
+ isHidden(entry.name) ||
34
+ (relativeDirectory === "" && EXCLUDED_ROOTS.has(entry.name))) {
35
+ continue;
36
+ }
37
+ const relativePath = path.posix.join(relativeDirectory.split(path.sep).join(path.posix.sep), entry.name);
38
+ const absolutePath = path.join(directory, entry.name);
39
+ if (entry.isDirectory()) {
40
+ await walk(absolutePath, relativePath);
41
+ continue;
42
+ }
43
+ if (!entry.isFile())
44
+ continue;
45
+ const content = await readFile(absolutePath);
46
+ if (looksBinary(content))
47
+ continue;
48
+ files[relativePath] = content.toString("utf8");
49
+ }
50
+ }
51
+ await walk(absoluteRoot);
52
+ return { root: absoluteRoot, files };
53
+ }
54
+ export function hashFiles(files) {
55
+ return Object.fromEntries(Object.entries(files)
56
+ .sort(([left], [right]) => left.localeCompare(right))
57
+ .map(([relativePath, content]) => [
58
+ relativePath,
59
+ createHash("sha256").update(content, "utf8").digest("hex"),
60
+ ]));
61
+ }
62
+ export function contentDigest(files) {
63
+ const hash = createHash("sha256");
64
+ for (const [relativePath, content] of Object.entries(files).sort(([a], [b]) => a.localeCompare(b))) {
65
+ hash.update(relativePath).update("\0").update(content).update("\0");
66
+ }
67
+ return hash.digest("hex");
68
+ }
69
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/bundle/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface BundleDocument {
2
+ files?: Record<string, unknown>;
3
+ metadata?: {
4
+ file_layout?: Record<string, string>;
5
+ };
6
+ [key: string]: unknown;
7
+ }
8
+ export declare function bundleFileLayout(bundle: BundleDocument): Record<string, string> | undefined;
9
+ export declare function assembleBundle(files: Record<string, string>, previousLayout?: Record<string, string>): BundleDocument;
10
+ export declare function bundleFiles(bundle: BundleDocument): Record<string, string>;
11
+ export declare function writeBundleFiles(destination: string, files: Record<string, string>): Promise<{
12
+ written: string[];
13
+ removed: string[];
14
+ }>;
@@ -0,0 +1,196 @@
1
+ import { mkdir, readdir, rmdir, unlink, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import YAML from "yaml";
4
+ import { readProgramFiles } from "./files.js";
5
+ export function bundleFileLayout(bundle) {
6
+ const layout = bundle.metadata?.file_layout;
7
+ return layout ? { ...layout } : undefined;
8
+ }
9
+ export function assembleBundle(files, previousLayout = {}) {
10
+ const layout = {};
11
+ const bundle = {
12
+ schema_version: 2,
13
+ metadata: { file_layout: layout },
14
+ };
15
+ for (const [relativePath, content] of Object.entries(files).sort(([left], [right]) => left.localeCompare(right))) {
16
+ const safePath = safeRelativePath(relativePath);
17
+ const pointer = previousLayout[safePath] ?? pointerForPath(safePath);
18
+ layout[safePath] = pointer;
19
+ setPointer(bundle, pointer, parseFile(safePath, content));
20
+ }
21
+ return bundle;
22
+ }
23
+ function pointerValue(document, pointer) {
24
+ let current = document;
25
+ for (const part of pointerParts(pointer)) {
26
+ if (["__proto__", "prototype", "constructor"].includes(part)) {
27
+ throw new Error(`Unsafe bundle pointer: ${pointer}`);
28
+ }
29
+ if (typeof current !== "object" || current === null || Array.isArray(current)) {
30
+ return undefined;
31
+ }
32
+ current = current[part];
33
+ }
34
+ return current;
35
+ }
36
+ function serialise(relativePath, value) {
37
+ if (typeof value === "string")
38
+ return value;
39
+ if (relativePath.endsWith(".json"))
40
+ return `${JSON.stringify(value, null, 2)}\n`;
41
+ return YAML.stringify(value);
42
+ }
43
+ function parseFile(relativePath, content) {
44
+ if (relativePath.endsWith(".yaml") || relativePath.endsWith(".yml")) {
45
+ return YAML.parse(content);
46
+ }
47
+ if (relativePath.endsWith(".json"))
48
+ return JSON.parse(content);
49
+ return content;
50
+ }
51
+ function pointerForPath(relativePath) {
52
+ const parts = relativePath.split("/");
53
+ const file = parts.at(-1);
54
+ if (!file)
55
+ throw new Error(`Invalid empty bundle path: ${relativePath}`);
56
+ if (relativePath === "policies/global.yaml" || relativePath === "policies/global.yml") {
57
+ return "/policies";
58
+ }
59
+ const stem = /\.(?:ya?ml|json)$/.test(file)
60
+ ? file.replace(/\.(?:ya?ml|json)$/, "")
61
+ : file;
62
+ return `/${[...parts.slice(0, -1), stem].map(encodePointerPart).join("/")}`;
63
+ }
64
+ function encodePointerPart(value) {
65
+ return value.replaceAll("~", "~0").replaceAll("/", "~1");
66
+ }
67
+ function setPointer(document, pointer, value) {
68
+ const parts = pointerParts(pointer);
69
+ if (parts.length === 0 || ["metadata", "schema_version"].includes(parts[0] ?? "")) {
70
+ throw new Error(`Bundle file_layout uses a reserved pointer: ${pointer}`);
71
+ }
72
+ let current = document;
73
+ for (const [index, part] of parts.entries()) {
74
+ if (["__proto__", "prototype", "constructor"].includes(part)) {
75
+ throw new Error(`Unsafe bundle pointer: ${pointer}`);
76
+ }
77
+ const final = index === parts.length - 1;
78
+ if (final) {
79
+ if (current[part] !== undefined) {
80
+ throw new Error(`Multiple files map to bundle pointer ${pointer}.`);
81
+ }
82
+ current[part] = value;
83
+ return;
84
+ }
85
+ const existing = current[part];
86
+ if (existing === undefined) {
87
+ const next = {};
88
+ current[part] = next;
89
+ current = next;
90
+ }
91
+ else if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
92
+ current = existing;
93
+ }
94
+ else {
95
+ throw new Error(`Bundle pointer collides with a value: ${pointer}`);
96
+ }
97
+ }
98
+ }
99
+ function pointerParts(pointer) {
100
+ if (!pointer.startsWith("/"))
101
+ throw new Error(`Invalid bundle pointer: ${pointer}`);
102
+ return pointer
103
+ .slice(1)
104
+ .split("/")
105
+ .filter(Boolean)
106
+ .map((part) => part.replaceAll("~1", "/").replaceAll("~0", "~"));
107
+ }
108
+ function safeRelativePath(relativePath) {
109
+ const normalised = path.posix.normalize(relativePath.replaceAll("\\", "/"));
110
+ if (path.posix.isAbsolute(normalised) ||
111
+ normalised === ".." ||
112
+ normalised.startsWith("../")) {
113
+ throw new Error(`Bundle path escapes the destination: ${relativePath}`);
114
+ }
115
+ return normalised;
116
+ }
117
+ export function bundleFiles(bundle) {
118
+ const direct = bundle.files;
119
+ if (direct && typeof direct === "object" && !Array.isArray(direct)) {
120
+ return Object.fromEntries(Object.entries(direct)
121
+ .filter((entry) => typeof entry[1] === "string")
122
+ .map(([relativePath, content]) => [safeRelativePath(relativePath), content]));
123
+ }
124
+ const layout = bundle.metadata?.file_layout;
125
+ if (!layout) {
126
+ const strings = Object.entries(bundle).filter((entry) => typeof entry[1] === "string");
127
+ return Object.fromEntries(strings.map(([relativePath, content]) => [safeRelativePath(relativePath), content]));
128
+ }
129
+ const files = {};
130
+ for (const [relativePath, pointer] of Object.entries(layout)) {
131
+ const value = pointerValue(bundle, pointer);
132
+ if (value !== undefined) {
133
+ const safePath = safeRelativePath(relativePath);
134
+ files[safePath] = serialise(safePath, value);
135
+ }
136
+ }
137
+ return files;
138
+ }
139
+ export async function writeBundleFiles(destination, files) {
140
+ const root = path.resolve(destination);
141
+ await mkdir(root, { recursive: true });
142
+ const desired = new Map(Object.entries(files).map(([relativePath, content]) => [
143
+ safeRelativePath(relativePath),
144
+ content,
145
+ ]));
146
+ const removed = [];
147
+ try {
148
+ const existing = await readProgramFiles(root);
149
+ for (const relativePath of Object.keys(existing.files).sort()) {
150
+ if (desired.has(relativePath))
151
+ continue;
152
+ await unlink(resolveInside(root, relativePath));
153
+ removed.push(relativePath);
154
+ }
155
+ }
156
+ catch (error) {
157
+ if (error.code !== "ENOENT")
158
+ throw error;
159
+ }
160
+ for (const [relativePath, content] of desired) {
161
+ const target = resolveInside(root, relativePath);
162
+ await mkdir(path.dirname(target), { recursive: true });
163
+ await writeFile(target, content, "utf8");
164
+ }
165
+ await removeEmptyDirectories(root);
166
+ return { written: [...desired.keys()].sort(), removed };
167
+ }
168
+ function resolveInside(root, relativePath) {
169
+ const safePath = safeRelativePath(relativePath);
170
+ const target = path.resolve(root, safePath);
171
+ if (target !== root && !target.startsWith(`${root}${path.sep}`)) {
172
+ throw new Error(`Bundle path escapes the destination: ${relativePath}`);
173
+ }
174
+ return target;
175
+ }
176
+ async function removeEmptyDirectories(root) {
177
+ async function walk(directory) {
178
+ const entries = await readdir(directory, { withFileTypes: true });
179
+ let empty = true;
180
+ for (const entry of entries) {
181
+ const child = path.join(directory, entry.name);
182
+ if (entry.isDirectory()) {
183
+ if (await walk(child)) {
184
+ await rmdir(child);
185
+ continue;
186
+ }
187
+ empty = false;
188
+ continue;
189
+ }
190
+ empty = false;
191
+ }
192
+ return empty;
193
+ }
194
+ await walk(root);
195
+ }
196
+ //# sourceMappingURL=materialize.js.map