@oharness/engine 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 (256) hide show
  1. package/dist/agent/agent.d.ts +196 -0
  2. package/dist/agent/agent.js +758 -0
  3. package/dist/agent/agent.js.map +1 -0
  4. package/dist/agent/compaction.d.ts +68 -0
  5. package/dist/agent/compaction.js +179 -0
  6. package/dist/agent/compaction.js.map +1 -0
  7. package/dist/agent/hooks.d.ts +77 -0
  8. package/dist/agent/hooks.js +152 -0
  9. package/dist/agent/hooks.js.map +1 -0
  10. package/dist/agent/memory.d.ts +45 -0
  11. package/dist/agent/memory.js +147 -0
  12. package/dist/agent/memory.js.map +1 -0
  13. package/dist/agent/overflow.d.ts +35 -0
  14. package/dist/agent/overflow.js +69 -0
  15. package/dist/agent/overflow.js.map +1 -0
  16. package/dist/agent/permissions.d.ts +181 -0
  17. package/dist/agent/permissions.js +289 -0
  18. package/dist/agent/permissions.js.map +1 -0
  19. package/dist/agent/prompt.d.ts +25 -0
  20. package/dist/agent/prompt.js +63 -0
  21. package/dist/agent/prompt.js.map +1 -0
  22. package/dist/agent/session.d.ts +108 -0
  23. package/dist/agent/session.js +231 -0
  24. package/dist/agent/session.js.map +1 -0
  25. package/dist/agent/settings.d.ts +37 -0
  26. package/dist/agent/settings.js +113 -0
  27. package/dist/agent/settings.js.map +1 -0
  28. package/dist/agent/skills.d.ts +58 -0
  29. package/dist/agent/skills.js +225 -0
  30. package/dist/agent/skills.js.map +1 -0
  31. package/dist/agent/store.d.ts +308 -0
  32. package/dist/agent/store.js +596 -0
  33. package/dist/agent/store.js.map +1 -0
  34. package/dist/agent/subagent.d.ts +44 -0
  35. package/dist/agent/subagent.js +138 -0
  36. package/dist/agent/subagent.js.map +1 -0
  37. package/dist/agent/titles.d.ts +8 -0
  38. package/dist/agent/titles.js +23 -0
  39. package/dist/agent/titles.js.map +1 -0
  40. package/dist/agent/workspace.d.ts +60 -0
  41. package/dist/agent/workspace.js +156 -0
  42. package/dist/agent/workspace.js.map +1 -0
  43. package/dist/artifacts/publish.d.ts +94 -0
  44. package/dist/artifacts/publish.js +104 -0
  45. package/dist/artifacts/publish.js.map +1 -0
  46. package/dist/artifacts/store.d.ts +324 -0
  47. package/dist/artifacts/store.js +500 -0
  48. package/dist/artifacts/store.js.map +1 -0
  49. package/dist/auth/index.d.ts +13 -0
  50. package/dist/auth/index.js +10 -0
  51. package/dist/auth/index.js.map +1 -0
  52. package/dist/auth/manager.d.ts +83 -0
  53. package/dist/auth/manager.js +266 -0
  54. package/dist/auth/manager.js.map +1 -0
  55. package/dist/auth/oauth.d.ts +83 -0
  56. package/dist/auth/oauth.js +327 -0
  57. package/dist/auth/oauth.js.map +1 -0
  58. package/dist/auth/providers/account.d.ts +59 -0
  59. package/dist/auth/providers/account.js +282 -0
  60. package/dist/auth/providers/account.js.map +1 -0
  61. package/dist/auth/providers/anthropic.d.ts +24 -0
  62. package/dist/auth/providers/anthropic.js +209 -0
  63. package/dist/auth/providers/anthropic.js.map +1 -0
  64. package/dist/auth/providers/generic.d.ts +57 -0
  65. package/dist/auth/providers/generic.js +155 -0
  66. package/dist/auth/providers/generic.js.map +1 -0
  67. package/dist/auth/providers/official.d.ts +3 -0
  68. package/dist/auth/providers/official.js +90 -0
  69. package/dist/auth/providers/official.js.map +1 -0
  70. package/dist/auth/providers/ottoport.d.ts +3 -0
  71. package/dist/auth/providers/ottoport.js +60 -0
  72. package/dist/auth/providers/ottoport.js.map +1 -0
  73. package/dist/auth/store.d.ts +22 -0
  74. package/dist/auth/store.js +138 -0
  75. package/dist/auth/store.js.map +1 -0
  76. package/dist/auth/types.d.ts +167 -0
  77. package/dist/auth/types.js +16 -0
  78. package/dist/auth/types.js.map +1 -0
  79. package/dist/config.d.ts +197 -0
  80. package/dist/config.js +195 -0
  81. package/dist/config.js.map +1 -0
  82. package/dist/core/errors.d.ts +46 -0
  83. package/dist/core/errors.js +83 -0
  84. package/dist/core/errors.js.map +1 -0
  85. package/dist/core/tokens.d.ts +12 -0
  86. package/dist/core/tokens.js +56 -0
  87. package/dist/core/tokens.js.map +1 -0
  88. package/dist/core/types.d.ts +91 -0
  89. package/dist/core/types.js +49 -0
  90. package/dist/core/types.js.map +1 -0
  91. package/dist/harness.d.ts +302 -0
  92. package/dist/harness.js +695 -0
  93. package/dist/harness.js.map +1 -0
  94. package/dist/index.d.ts +32 -0
  95. package/dist/index.js +21 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/mcp/client.d.ts +55 -0
  98. package/dist/mcp/client.js +199 -0
  99. package/dist/mcp/client.js.map +1 -0
  100. package/dist/mcp/index.d.ts +13 -0
  101. package/dist/mcp/index.js +8 -0
  102. package/dist/mcp/index.js.map +1 -0
  103. package/dist/mcp/manager.d.ts +77 -0
  104. package/dist/mcp/manager.js +325 -0
  105. package/dist/mcp/manager.js.map +1 -0
  106. package/dist/mcp/oauth.d.ts +63 -0
  107. package/dist/mcp/oauth.js +302 -0
  108. package/dist/mcp/oauth.js.map +1 -0
  109. package/dist/mcp/protocol.d.ts +130 -0
  110. package/dist/mcp/protocol.js +14 -0
  111. package/dist/mcp/protocol.js.map +1 -0
  112. package/dist/mcp/registry.d.ts +52 -0
  113. package/dist/mcp/registry.js +100 -0
  114. package/dist/mcp/registry.js.map +1 -0
  115. package/dist/mcp/registry.json +293 -0
  116. package/dist/mcp/secrets.d.ts +20 -0
  117. package/dist/mcp/secrets.js +75 -0
  118. package/dist/mcp/secrets.js.map +1 -0
  119. package/dist/mcp/transport.d.ts +51 -0
  120. package/dist/mcp/transport.js +158 -0
  121. package/dist/mcp/transport.js.map +1 -0
  122. package/dist/paths.d.ts +37 -0
  123. package/dist/paths.js +63 -0
  124. package/dist/paths.js.map +1 -0
  125. package/dist/plugins.d.ts +55 -0
  126. package/dist/plugins.js +201 -0
  127. package/dist/plugins.js.map +1 -0
  128. package/dist/providers/builtin.d.ts +23 -0
  129. package/dist/providers/builtin.js +141 -0
  130. package/dist/providers/builtin.js.map +1 -0
  131. package/dist/providers/catalog.d.ts +129 -0
  132. package/dist/providers/catalog.js +254 -0
  133. package/dist/providers/catalog.js.map +1 -0
  134. package/dist/providers/catalog.json +472 -0
  135. package/dist/providers/discovery.d.ts +16 -0
  136. package/dist/providers/discovery.js +161 -0
  137. package/dist/providers/discovery.js.map +1 -0
  138. package/dist/providers/http.d.ts +24 -0
  139. package/dist/providers/http.js +139 -0
  140. package/dist/providers/http.js.map +1 -0
  141. package/dist/providers/index.d.ts +10 -0
  142. package/dist/providers/index.js +8 -0
  143. package/dist/providers/index.js.map +1 -0
  144. package/dist/providers/piai.d.ts +124 -0
  145. package/dist/providers/piai.js +551 -0
  146. package/dist/providers/piai.js.map +1 -0
  147. package/dist/providers/registry.d.ts +65 -0
  148. package/dist/providers/registry.js +195 -0
  149. package/dist/providers/registry.js.map +1 -0
  150. package/dist/providers/resilient.d.ts +46 -0
  151. package/dist/providers/resilient.js +117 -0
  152. package/dist/providers/resilient.js.map +1 -0
  153. package/dist/providers/types.d.ts +182 -0
  154. package/dist/providers/types.js +50 -0
  155. package/dist/providers/types.js.map +1 -0
  156. package/dist/schedule/cron.d.ts +35 -0
  157. package/dist/schedule/cron.js +125 -0
  158. package/dist/schedule/cron.js.map +1 -0
  159. package/dist/schedule/scheduler.d.ts +87 -0
  160. package/dist/schedule/scheduler.js +237 -0
  161. package/dist/schedule/scheduler.js.map +1 -0
  162. package/dist/storage/kv.d.ts +56 -0
  163. package/dist/storage/kv.js +173 -0
  164. package/dist/storage/kv.js.map +1 -0
  165. package/dist/storage/migrate.d.ts +11 -0
  166. package/dist/storage/migrate.js +93 -0
  167. package/dist/storage/migrate.js.map +1 -0
  168. package/dist/storage/project.d.ts +9 -0
  169. package/dist/storage/project.js +57 -0
  170. package/dist/storage/project.js.map +1 -0
  171. package/dist/storage/records.d.ts +32 -0
  172. package/dist/storage/records.js +48 -0
  173. package/dist/storage/records.js.map +1 -0
  174. package/dist/sync/client.d.ts +79 -0
  175. package/dist/sync/client.js +118 -0
  176. package/dist/sync/client.js.map +1 -0
  177. package/dist/sync/mirror.d.ts +85 -0
  178. package/dist/sync/mirror.js +389 -0
  179. package/dist/sync/mirror.js.map +1 -0
  180. package/dist/sync/protocol.d.ts +67 -0
  181. package/dist/sync/protocol.js +16 -0
  182. package/dist/sync/protocol.js.map +1 -0
  183. package/dist/sync/settings.d.ts +56 -0
  184. package/dist/sync/settings.js +60 -0
  185. package/dist/sync/settings.js.map +1 -0
  186. package/dist/tools/builtin/artifact.d.ts +16 -0
  187. package/dist/tools/builtin/artifact.js +134 -0
  188. package/dist/tools/builtin/artifact.js.map +1 -0
  189. package/dist/tools/builtin/bash.d.ts +3 -0
  190. package/dist/tools/builtin/bash.js +142 -0
  191. package/dist/tools/builtin/bash.js.map +1 -0
  192. package/dist/tools/builtin/fs.d.ts +19 -0
  193. package/dist/tools/builtin/fs.js +280 -0
  194. package/dist/tools/builtin/fs.js.map +1 -0
  195. package/dist/tools/builtin/index.d.ts +22 -0
  196. package/dist/tools/builtin/index.js +42 -0
  197. package/dist/tools/builtin/index.js.map +1 -0
  198. package/dist/tools/builtin/mcp-resource.d.ts +3 -0
  199. package/dist/tools/builtin/mcp-resource.js +220 -0
  200. package/dist/tools/builtin/mcp-resource.js.map +1 -0
  201. package/dist/tools/builtin/memory.d.ts +10 -0
  202. package/dist/tools/builtin/memory.js +76 -0
  203. package/dist/tools/builtin/memory.js.map +1 -0
  204. package/dist/tools/builtin/recall.d.ts +13 -0
  205. package/dist/tools/builtin/recall.js +163 -0
  206. package/dist/tools/builtin/recall.js.map +1 -0
  207. package/dist/tools/builtin/search.d.ts +3 -0
  208. package/dist/tools/builtin/search.js +240 -0
  209. package/dist/tools/builtin/search.js.map +1 -0
  210. package/dist/tools/builtin/skill.d.ts +10 -0
  211. package/dist/tools/builtin/skill.js +46 -0
  212. package/dist/tools/builtin/skill.js.map +1 -0
  213. package/dist/tools/builtin/task.d.ts +9 -0
  214. package/dist/tools/builtin/task.js +68 -0
  215. package/dist/tools/builtin/task.js.map +1 -0
  216. package/dist/tools/builtin/todo.d.ts +20 -0
  217. package/dist/tools/builtin/todo.js +63 -0
  218. package/dist/tools/builtin/todo.js.map +1 -0
  219. package/dist/tools/define.d.ts +19 -0
  220. package/dist/tools/define.js +39 -0
  221. package/dist/tools/define.js.map +1 -0
  222. package/dist/tools/index.d.ts +7 -0
  223. package/dist/tools/index.js +5 -0
  224. package/dist/tools/index.js.map +1 -0
  225. package/dist/tools/registry.d.ts +39 -0
  226. package/dist/tools/registry.js +101 -0
  227. package/dist/tools/registry.js.map +1 -0
  228. package/dist/tools/types.d.ts +112 -0
  229. package/dist/tools/types.js +22 -0
  230. package/dist/tools/types.js.map +1 -0
  231. package/dist/util/id.d.ts +9 -0
  232. package/dist/util/id.js +19 -0
  233. package/dist/util/id.js.map +1 -0
  234. package/dist/util/json.d.ts +25 -0
  235. package/dist/util/json.js +100 -0
  236. package/dist/util/json.js.map +1 -0
  237. package/dist/util/jwt.d.ts +74 -0
  238. package/dist/util/jwt.js +177 -0
  239. package/dist/util/jwt.js.map +1 -0
  240. package/dist/util/logger.d.ts +13 -0
  241. package/dist/util/logger.js +59 -0
  242. package/dist/util/logger.js.map +1 -0
  243. package/dist/util/queue.d.ts +26 -0
  244. package/dist/util/queue.js +106 -0
  245. package/dist/util/queue.js.map +1 -0
  246. package/dist/util/schema.d.ts +17 -0
  247. package/dist/util/schema.js +98 -0
  248. package/dist/util/schema.js.map +1 -0
  249. package/dist/util/shell.d.ts +20 -0
  250. package/dist/util/shell.js +24 -0
  251. package/dist/util/shell.js.map +1 -0
  252. package/official.json +4 -0
  253. package/package.json +38 -0
  254. package/skills/artifact-authoring/SKILL.md +81 -0
  255. package/skills/canvas/SKILL.md +85 -0
  256. package/skills/skill-authoring/SKILL.md +85 -0
@@ -0,0 +1,155 @@
1
+ import { refreshCredential, startAuthCodeFlow, startDeviceFlow, startLoopbackFlow, } from "../oauth.js";
2
+ import { isExpired } from "../types.js";
3
+ /** Build a plain API-key auth provider. */
4
+ export function apiKeyProvider(opts) {
5
+ const header = opts.header ?? "authorization";
6
+ const format = opts.format ?? ((key) => `Bearer ${key}`);
7
+ const endpoint = () => {
8
+ const moved = opts.baseUrl?.();
9
+ return moved ? { baseUrl: moved } : {};
10
+ };
11
+ return {
12
+ id: opts.id,
13
+ label: opts.label,
14
+ methods: [
15
+ {
16
+ type: "api",
17
+ label: "API key",
18
+ prompts: [
19
+ {
20
+ type: "text",
21
+ key: "key",
22
+ message: `${opts.label} API key`,
23
+ placeholder: opts.placeholder,
24
+ secret: true,
25
+ validate: opts.validate,
26
+ },
27
+ ],
28
+ },
29
+ ],
30
+ async loader(credential) {
31
+ for (const name of opts.envVars ?? []) {
32
+ const value = process.env[name];
33
+ if (value) {
34
+ return { headers: { [header]: format(value) }, source: `env:${name}`, ...endpoint() };
35
+ }
36
+ }
37
+ if (credential?.type === "api") {
38
+ return { headers: { [header]: format(credential.key) }, source: "stored:api", ...endpoint() };
39
+ }
40
+ return undefined;
41
+ },
42
+ async discover() {
43
+ for (const name of opts.envVars ?? []) {
44
+ const value = process.env[name];
45
+ if (value)
46
+ return { credential: { type: "api", key: value }, source: `env:${name}` };
47
+ }
48
+ return undefined;
49
+ },
50
+ };
51
+ }
52
+ /**
53
+ * Build an OAuth auth provider covering the flows a terminal app can actually
54
+ * complete: device code, loopback redirect, or paste-the-code.
55
+ */
56
+ export function oauthProvider(opts) {
57
+ const header = opts.header ?? "authorization";
58
+ const format = opts.format ?? ((token) => `Bearer ${token}`);
59
+ const methods = [];
60
+ if (opts.deviceCodeUrl) {
61
+ methods.push({
62
+ type: "oauth",
63
+ label: `Sign in to ${opts.label} (device code)`,
64
+ authorize: async () => startDeviceFlow({
65
+ deviceCodeUrl: opts.deviceCodeUrl,
66
+ tokenUrl: opts.tokenUrl,
67
+ clientId: opts.clientId,
68
+ scope: opts.scope,
69
+ headers: opts.headers,
70
+ }),
71
+ });
72
+ }
73
+ if (opts.authorizeUrl) {
74
+ methods.push({
75
+ type: "oauth",
76
+ label: `Sign in to ${opts.label} (browser)`,
77
+ authorize: async () => {
78
+ const shared = {
79
+ authorizeUrl: opts.authorizeUrl,
80
+ tokenUrl: opts.tokenUrl,
81
+ clientId: opts.clientId,
82
+ clientSecret: opts.clientSecret,
83
+ scope: opts.scope,
84
+ extraParams: opts.extraParams,
85
+ headers: opts.headers,
86
+ };
87
+ // A loopback listener is nicer, but is useless over SSH or in a
88
+ // container where the browser cannot reach 127.0.0.1.
89
+ return opts.preferPasteCode
90
+ ? startAuthCodeFlow({ ...shared, redirectUri: "urn:ietf:wg:oauth:2.0:oob" })
91
+ : startLoopbackFlow(shared);
92
+ },
93
+ });
94
+ }
95
+ if (opts.envVars?.length) {
96
+ methods.push({
97
+ type: "api",
98
+ label: "API key",
99
+ prompts: [{ type: "text", key: "key", message: `${opts.label} API key`, secret: true }],
100
+ });
101
+ }
102
+ return {
103
+ id: opts.id,
104
+ label: opts.label,
105
+ methods,
106
+ async loader(credential) {
107
+ for (const name of opts.envVars ?? []) {
108
+ const value = process.env[name];
109
+ if (value) {
110
+ return {
111
+ headers: { [header]: format(value), ...opts.extraHeaders },
112
+ removeHeaders: opts.removeHeaders,
113
+ source: `env:${name}`,
114
+ };
115
+ }
116
+ }
117
+ if (credential?.type === "oauth") {
118
+ return {
119
+ headers: { [header]: format(credential.access), ...opts.extraHeaders },
120
+ removeHeaders: opts.removeHeaders,
121
+ ...(credential.baseUrl ? { baseUrl: credential.baseUrl } : {}),
122
+ source: "stored:oauth",
123
+ };
124
+ }
125
+ if (credential?.type === "api") {
126
+ return {
127
+ headers: { [header]: format(credential.key), ...opts.extraHeaders },
128
+ removeHeaders: opts.removeHeaders,
129
+ source: "stored:api",
130
+ };
131
+ }
132
+ return undefined;
133
+ },
134
+ async refresh(credential) {
135
+ if (!isExpired(credential))
136
+ return undefined;
137
+ return refreshCredential(credential, {
138
+ tokenUrl: opts.tokenUrl,
139
+ clientId: opts.clientId,
140
+ clientSecret: opts.clientSecret,
141
+ headers: opts.headers,
142
+ scope: opts.scope,
143
+ });
144
+ },
145
+ async discover() {
146
+ for (const name of opts.envVars ?? []) {
147
+ const value = process.env[name];
148
+ if (value)
149
+ return { credential: { type: "api", key: value }, source: `env:${name}` };
150
+ }
151
+ return undefined;
152
+ },
153
+ };
154
+ }
155
+ //# sourceMappingURL=generic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic.js","sourceRoot":"","sources":["../../../src/auth/providers/generic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AuthProvider } from "../types.ts";
2
+ export declare function officialBaseUrl(): string;
3
+ export declare const officialAuth: AuthProvider;
@@ -0,0 +1,90 @@
1
+ import { isExpired } from "../types.js";
2
+ import { accountSignIn, bearer, refreshSession } from "./account.js";
3
+ /**
4
+ * The official plan — an OHarness account and nothing else asked for.
5
+ *
6
+ * Two credentials reach it, and they are the same account either way:
7
+ *
8
+ * - The session from signing in, held here and refreshed like any OAuth token.
9
+ * - An `oh-` key the account holder created on the OHarness site. It is not a
10
+ * second wallet, only a second key to the same one — CI and SDKs need
11
+ * something that does not expire, and `OHARNESS_API_KEY` is how that key is
12
+ * carried into a process, not a separate thing issued to a machine.
13
+ *
14
+ * What is deliberately absent is any upstream credential. The models are
15
+ * served by a gateway that holds the OpenAI, Anthropic and Google keys; usage
16
+ * is metered against the account's balance on the way through. Which gateway
17
+ * that is stays an implementation detail — the subscriber never learns it, and
18
+ * moving it is a change to `DEFAULT_BASE_URL` rather than to anyone's setup.
19
+ */
20
+ /**
21
+ * Where official-plan requests go.
22
+ *
23
+ * This is the metering endpoint, not the upstream gateway: it is what reads
24
+ * the account, checks the balance and writes the ledger entry, and only then
25
+ * forwards. Pointing it at the upstream instead skips the half of the request
26
+ * that knows who is asking — the upstream sees an account token where it wants
27
+ * its own key and answers `invalid_api_key`, which is a confusing way to be
28
+ * told the meter is not in the path. `OHARNESS_BASE_URL` moves it for a
29
+ * staging or self-hosted deployment.
30
+ *
31
+ * A domain of ours rather than the host's generated one, because this string
32
+ * is compiled into every desktop build and the desktop reads no environment:
33
+ * whatever is written here is where installed copies go until they are
34
+ * replaced. A hosting subdomain would make "move the gateway" and "abandon
35
+ * everyone who has not updated" the same act.
36
+ */
37
+ const DEFAULT_BASE_URL = "https://api.oharness.ai";
38
+ export function officialBaseUrl() {
39
+ return (process.env["OHARNESS_BASE_URL"] ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
40
+ }
41
+ export const officialAuth = {
42
+ id: "official",
43
+ label: "OHarness",
44
+ methods: [
45
+ accountSignIn("Sign in to your OHarness account"),
46
+ {
47
+ type: "api",
48
+ label: "OHarness API key",
49
+ prompts: [
50
+ {
51
+ type: "text",
52
+ key: "key",
53
+ message: "OHarness API key",
54
+ placeholder: "oh-…",
55
+ secret: true,
56
+ validate: (value) => /^\S+$/.test(value) && !/^["']|["']$/.test(value)
57
+ ? undefined
58
+ : "paste the key alone — no quotes or spaces",
59
+ },
60
+ ],
61
+ },
62
+ ],
63
+ async loader(credential) {
64
+ const envKey = process.env["OHARNESS_API_KEY"];
65
+ if (envKey)
66
+ return bearer(envKey, "env:OHARNESS_API_KEY");
67
+ if (credential?.type === "oauth" && !isExpired(credential)) {
68
+ return {
69
+ ...bearer(credential.access, "stored:account"),
70
+ // The gateway may pin an account to a regional host at login.
71
+ ...(credential.baseUrl ? { baseUrl: credential.baseUrl } : {}),
72
+ };
73
+ }
74
+ if (credential?.type === "api")
75
+ return bearer(credential.key, "stored:api");
76
+ return undefined;
77
+ },
78
+ async refresh(credential) {
79
+ if (!isExpired(credential))
80
+ return undefined;
81
+ return refreshSession(credential);
82
+ },
83
+ async discover() {
84
+ const envKey = process.env["OHARNESS_API_KEY"];
85
+ if (!envKey)
86
+ return undefined;
87
+ return { credential: { type: "api", key: envKey }, source: "env:OHARNESS_API_KEY" };
88
+ },
89
+ };
90
+ //# sourceMappingURL=official.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"official.js","sourceRoot":"","sources":["../../../src/auth/providers/official.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAErE;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAEnD,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAiB;IACxC,EAAE,EAAE,UAAU;IACd,KAAK,EAAE,UAAU;IAEjB,OAAO,EAAE;QACP,aAAa,CAAC,kCAAkC,CAAC;QACjD;YACE,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,kBAAkB;YACzB,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,GAAG,EAAE,KAAK;oBACV,OAAO,EAAE,kBAAkB;oBAC3B,WAAW,EAAE,MAAM;oBACnB,MAAM,EAAE,IAAI;oBACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;wBAC/C,CAAC,CAAC,SAAS;wBACX,CAAC,CAAC,2CAA2C;iBAClD;aACF;SACF;KACF;IAED,KAAK,CAAC,MAAM,CAAC,UAAU;QACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAC/C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAE1D,IAAI,UAAU,EAAE,IAAI,KAAK,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3D,OAAO;gBACL,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,gBAAgB,CAAC;gBAC9C,8DAA8D;gBAC9D,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/D,CAAC;QACJ,CAAC;QAED,IAAI,UAAU,EAAE,IAAI,KAAK,KAAK;YAAE,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAE5E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAA2B;QACvC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;YAAE,OAAO,SAAS,CAAC;QAC7C,OAAO,cAAc,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;IACtF,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AuthProvider } from "../types.ts";
2
+ export declare function ottoportBaseUrl(): string;
3
+ export declare const ottoportAuth: AuthProvider;
@@ -0,0 +1,60 @@
1
+ import { apiKeyProvider } from "./generic.js";
2
+ /**
3
+ * OttoPort — an OpenAI-compatible gateway, brought by the user.
4
+ *
5
+ * This entry is for someone who has their own OttoPort account: they create a
6
+ * key in OttoPort's console and paste it here, and their usage is billed
7
+ * against their own credit balance there. It is an ordinary vendor entry, no
8
+ * different in kind from OpenAI or OpenRouter.
9
+ *
10
+ * It is *not* the official OHarness plan. That plan happens to route through
11
+ * this gateway today, but the subscriber never holds an OttoPort key and never
12
+ * sees an OttoPort account — see `official.ts`. Keeping the two apart is what
13
+ * lets the plan's billing, quota and upstream be ours to change.
14
+ */
15
+ /**
16
+ * The gateway. Per-deployment, so staging and self-hosted work unchanged:
17
+ * `OTTOPORT_BASE_URL` moves it without a release.
18
+ */
19
+ const DEFAULT_BASE_URL = "https://ottoport.ai";
20
+ /** Where the API sits under the host. Stated once; two things below need it. */
21
+ const API_PATH = "/api/v1";
22
+ export function ottoportBaseUrl() {
23
+ return (process.env["OTTOPORT_BASE_URL"] ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
24
+ }
25
+ /**
26
+ * The endpoint to call, when the environment has moved it — and nothing at
27
+ * all when it has not.
28
+ *
29
+ * The variable names a *host*, which is how it is documented and how anyone
30
+ * would think to set it, while what the wire needs is the API root. Appending
31
+ * the path here is what makes `OTTOPORT_BASE_URL=https://staging.ottoport.ai`
32
+ * do what it says instead of sending every completion to a 404 one level up.
33
+ * A value that already carries the path is left alone, since typing the whole
34
+ * root is the other obvious reading.
35
+ *
36
+ * Silent when unset, deliberately: the catalog's `baseUrl` is the default, and
37
+ * a user catalog is the other way to move this endpoint. An override that
38
+ * returned the default anyway would outrank that file for no reason.
39
+ */
40
+ function movedEndpoint() {
41
+ const moved = process.env["OTTOPORT_BASE_URL"];
42
+ if (!moved)
43
+ return undefined;
44
+ const host = moved.replace(/\/+$/, "");
45
+ return host.endsWith(API_PATH) ? host : `${host}${API_PATH}`;
46
+ }
47
+ export const ottoportAuth = apiKeyProvider({
48
+ id: "ottoport",
49
+ label: "OttoPort",
50
+ envVars: ["OTTOPORT_API_KEY"],
51
+ placeholder: "op-…",
52
+ baseUrl: movedEndpoint,
53
+ // Deliberately loose about the prefix: rejecting a key the gateway would
54
+ // have accepted is worse than passing a typo through to a 401. Quotes and
55
+ // spaces are the real failure — they come from pasting `KEY="op-…"`.
56
+ validate: (value) => /^\S+$/.test(value) && !/^["']|["']$/.test(value)
57
+ ? undefined
58
+ : "paste the key alone — no quotes or spaces",
59
+ });
60
+ //# sourceMappingURL=ottoport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ottoport.js","sourceRoot":"","sources":["../../../src/auth/providers/ottoport.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;;;;;;GAYG;AAEH;;;GAGG;AACH,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C,gFAAgF;AAChF,MAAM,QAAQ,GAAG,SAAS,CAAC;AAE3B,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACpF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,aAAa;IACpB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,QAAQ,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAiB,cAAc,CAAC;IACvD,EAAE,EAAE,UAAU;IACd,KAAK,EAAE,UAAU;IACjB,OAAO,EAAE,CAAC,kBAAkB,CAAC;IAC7B,WAAW,EAAE,MAAM;IACnB,OAAO,EAAE,aAAa;IACtB,yEAAyE;IACzE,0EAA0E;IAC1E,qEAAqE;IACrE,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/C,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,2CAA2C;CAClD,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { Credential } from "./types.ts";
2
+ /**
3
+ * Credential storage.
4
+ *
5
+ * Written 0600 in a 0700 directory: these are live access tokens, and on a
6
+ * shared machine a world-readable auth file is the whole security story.
7
+ * Writes go through a temp file + rename so a crash mid-write cannot leave a
8
+ * truncated credential set behind.
9
+ */
10
+ export declare class AuthStore {
11
+ private readonly file;
12
+ private cache?;
13
+ constructor(file?: string);
14
+ get location(): string;
15
+ all(): Promise<Record<string, Credential>>;
16
+ get(providerId: string): Promise<Credential | undefined>;
17
+ set(providerId: string, credential: Credential): Promise<void>;
18
+ remove(providerId: string): Promise<boolean>;
19
+ /** Drop the in-memory copy so the next read comes from disk. */
20
+ invalidate(): void;
21
+ private persist;
22
+ }
@@ -0,0 +1,138 @@
1
+ import { userPath } from "../paths.js";
2
+ import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { parseJson } from "../util/json.js";
5
+ const FILE_MODE = 0o600;
6
+ const DIR_MODE = 0o700;
7
+ /**
8
+ * Credential storage.
9
+ *
10
+ * Written 0600 in a 0700 directory: these are live access tokens, and on a
11
+ * shared machine a world-readable auth file is the whole security story.
12
+ * Writes go through a temp file + rename so a crash mid-write cannot leave a
13
+ * truncated credential set behind.
14
+ */
15
+ export class AuthStore {
16
+ file;
17
+ cache;
18
+ constructor(file) {
19
+ this.file =
20
+ file ??
21
+ process.env["OHARNESS_AUTH_FILE"] ??
22
+ userPath("auth.json");
23
+ }
24
+ get location() {
25
+ return this.file;
26
+ }
27
+ async all() {
28
+ if (this.cache)
29
+ return this.cache;
30
+ // An env override lets CI inject credentials without touching disk.
31
+ const inline = process.env["OHARNESS_AUTH_CONTENT"];
32
+ if (inline) {
33
+ const parsed = parseJson(inline);
34
+ if (parsed.ok) {
35
+ this.cache = parsed.value;
36
+ return this.cache;
37
+ }
38
+ }
39
+ let raw;
40
+ try {
41
+ raw = await readFile(this.file, "utf8");
42
+ }
43
+ catch {
44
+ this.cache = {};
45
+ return this.cache;
46
+ }
47
+ const parsed = parseJson(raw);
48
+ if (!parsed.ok) {
49
+ // A corrupt auth file should not be fatal — treat it as empty and let
50
+ // the user log in again rather than blocking every request.
51
+ this.cache = {};
52
+ return this.cache;
53
+ }
54
+ const out = {};
55
+ for (const [key, value] of Object.entries(parsed.value)) {
56
+ const credential = validate(value);
57
+ if (credential)
58
+ out[normalizeKey(key)] = credential;
59
+ }
60
+ this.cache = out;
61
+ return out;
62
+ }
63
+ async get(providerId) {
64
+ return (await this.all())[normalizeKey(providerId)];
65
+ }
66
+ async set(providerId, credential) {
67
+ const all = { ...(await this.all()), [normalizeKey(providerId)]: credential };
68
+ await this.persist(all);
69
+ }
70
+ async remove(providerId) {
71
+ const all = { ...(await this.all()) };
72
+ const key = normalizeKey(providerId);
73
+ if (!(key in all))
74
+ return false;
75
+ delete all[key];
76
+ await this.persist(all);
77
+ return true;
78
+ }
79
+ /** Drop the in-memory copy so the next read comes from disk. */
80
+ invalidate() {
81
+ this.cache = undefined;
82
+ }
83
+ async persist(all) {
84
+ await mkdir(path.dirname(this.file), { recursive: true, mode: DIR_MODE });
85
+ const temp = `${this.file}.${process.pid}.tmp`;
86
+ await writeFile(temp, JSON.stringify(all, null, 2), { encoding: "utf8", mode: FILE_MODE });
87
+ await rename(temp, this.file);
88
+ // rename preserves the temp file's mode, but be explicit in case the file
89
+ // already existed with looser permissions.
90
+ await chmod(this.file, FILE_MODE).catch(() => { });
91
+ this.cache = all;
92
+ }
93
+ }
94
+ /** Trailing slashes are easy to introduce via config and break lookups. */
95
+ function normalizeKey(key) {
96
+ return key.replace(/\/+$/, "");
97
+ }
98
+ function validate(value) {
99
+ if (!value || typeof value !== "object")
100
+ return undefined;
101
+ const v = value;
102
+ switch (v["type"]) {
103
+ case "api":
104
+ return typeof v["key"] === "string"
105
+ ? {
106
+ type: "api",
107
+ key: v["key"],
108
+ ...(isStringRecord(v["metadata"]) ? { metadata: v["metadata"] } : {}),
109
+ }
110
+ : undefined;
111
+ case "oauth":
112
+ return typeof v["access"] === "string" &&
113
+ typeof v["refresh"] === "string" &&
114
+ typeof v["expires"] === "number"
115
+ ? {
116
+ type: "oauth",
117
+ access: v["access"],
118
+ refresh: v["refresh"],
119
+ expires: v["expires"],
120
+ ...(typeof v["accountId"] === "string" ? { accountId: v["accountId"] } : {}),
121
+ ...(typeof v["baseUrl"] === "string" ? { baseUrl: v["baseUrl"] } : {}),
122
+ ...(isStringRecord(v["metadata"]) ? { metadata: v["metadata"] } : {}),
123
+ }
124
+ : undefined;
125
+ case "wellknown":
126
+ return typeof v["key"] === "string" && typeof v["token"] === "string"
127
+ ? { type: "wellknown", key: v["key"], token: v["token"] }
128
+ : undefined;
129
+ default:
130
+ return undefined;
131
+ }
132
+ }
133
+ function isStringRecord(value) {
134
+ return (!!value &&
135
+ typeof value === "object" &&
136
+ Object.values(value).every((v) => typeof v === "string"));
137
+ }
138
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"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"}