@profullstack/agenticjobs 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 (206) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +219 -0
  3. package/bin/agenticjobs-mcp.mjs +2 -0
  4. package/bin/agenticjobs.mjs +2 -0
  5. package/dist/cli/args.d.ts +17 -0
  6. package/dist/cli/args.js +103 -0
  7. package/dist/cli/args.js.map +1 -0
  8. package/dist/cli/format.d.ts +15 -0
  9. package/dist/cli/format.js +24 -0
  10. package/dist/cli/format.js.map +1 -0
  11. package/dist/cli/index.d.ts +13 -0
  12. package/dist/cli/index.js +620 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/cli/jobfile.d.ts +15 -0
  15. package/dist/cli/jobfile.js +94 -0
  16. package/dist/cli/jobfile.js.map +1 -0
  17. package/dist/client/client.d.ts +105 -0
  18. package/dist/client/client.js +182 -0
  19. package/dist/client/client.js.map +1 -0
  20. package/dist/client/config.d.ts +33 -0
  21. package/dist/client/config.js +92 -0
  22. package/dist/client/config.js.map +1 -0
  23. package/dist/client/fanout.d.ts +35 -0
  24. package/dist/client/fanout.js +77 -0
  25. package/dist/client/fanout.js.map +1 -0
  26. package/dist/client/index.d.ts +4 -0
  27. package/dist/client/index.js +5 -0
  28. package/dist/client/index.js.map +1 -0
  29. package/dist/client/login.d.ts +23 -0
  30. package/dist/client/login.js +45 -0
  31. package/dist/client/login.js.map +1 -0
  32. package/dist/config.d.ts +40 -0
  33. package/dist/config.js +64 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/core/applications.d.ts +67 -0
  36. package/dist/core/applications.js +187 -0
  37. package/dist/core/applications.js.map +1 -0
  38. package/dist/core/auth.d.ts +120 -0
  39. package/dist/core/auth.js +246 -0
  40. package/dist/core/auth.js.map +1 -0
  41. package/dist/core/import.d.ts +52 -0
  42. package/dist/core/import.js +311 -0
  43. package/dist/core/import.js.map +1 -0
  44. package/dist/core/jobs.d.ts +91 -0
  45. package/dist/core/jobs.js +381 -0
  46. package/dist/core/jobs.js.map +1 -0
  47. package/dist/core/orgs.d.ts +21 -0
  48. package/dist/core/orgs.js +111 -0
  49. package/dist/core/orgs.js.map +1 -0
  50. package/dist/core/resumes.d.ts +51 -0
  51. package/dist/core/resumes.js +144 -0
  52. package/dist/core/resumes.js.map +1 -0
  53. package/dist/core/zip.d.ts +17 -0
  54. package/dist/core/zip.js +77 -0
  55. package/dist/core/zip.js.map +1 -0
  56. package/dist/db/index.d.ts +3 -0
  57. package/dist/db/index.js +3 -0
  58. package/dist/db/index.js.map +1 -0
  59. package/dist/db/migrate.d.ts +15 -0
  60. package/dist/db/migrate.js +67 -0
  61. package/dist/db/migrate.js.map +1 -0
  62. package/dist/db/pool.d.ts +13 -0
  63. package/dist/db/pool.js +68 -0
  64. package/dist/db/pool.js.map +1 -0
  65. package/dist/db/seed.d.ts +9 -0
  66. package/dist/db/seed.js +120 -0
  67. package/dist/db/seed.js.map +1 -0
  68. package/dist/directory/announce.d.ts +32 -0
  69. package/dist/directory/announce.js +59 -0
  70. package/dist/directory/announce.js.map +1 -0
  71. package/dist/directory/federate.d.ts +59 -0
  72. package/dist/directory/federate.js +126 -0
  73. package/dist/directory/federate.js.map +1 -0
  74. package/dist/directory/fetch.d.ts +35 -0
  75. package/dist/directory/fetch.js +138 -0
  76. package/dist/directory/fetch.js.map +1 -0
  77. package/dist/directory/index.d.ts +4 -0
  78. package/dist/directory/index.js +5 -0
  79. package/dist/directory/index.js.map +1 -0
  80. package/dist/directory/registry.d.ts +55 -0
  81. package/dist/directory/registry.js +155 -0
  82. package/dist/directory/registry.js.map +1 -0
  83. package/dist/index.d.ts +14 -0
  84. package/dist/index.js +14 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/markup/escape.d.ts +20 -0
  87. package/dist/markup/escape.js +56 -0
  88. package/dist/markup/escape.js.map +1 -0
  89. package/dist/markup/markdown.d.ts +35 -0
  90. package/dist/markup/markdown.js +279 -0
  91. package/dist/markup/markdown.js.map +1 -0
  92. package/dist/markup/resume.d.ts +72 -0
  93. package/dist/markup/resume.js +260 -0
  94. package/dist/markup/resume.js.map +1 -0
  95. package/dist/mcp/protocol.d.ts +56 -0
  96. package/dist/mcp/protocol.js +48 -0
  97. package/dist/mcp/protocol.js.map +1 -0
  98. package/dist/mcp/server.d.ts +21 -0
  99. package/dist/mcp/server.js +73 -0
  100. package/dist/mcp/server.js.map +1 -0
  101. package/dist/mcp/stdio.d.ts +13 -0
  102. package/dist/mcp/stdio.js +85 -0
  103. package/dist/mcp/stdio.js.map +1 -0
  104. package/dist/mcp/tools.d.ts +26 -0
  105. package/dist/mcp/tools.js +351 -0
  106. package/dist/mcp/tools.js.map +1 -0
  107. package/dist/schema/index.d.ts +5 -0
  108. package/dist/schema/index.js +6 -0
  109. package/dist/schema/index.js.map +1 -0
  110. package/dist/schema/instance.d.ts +85 -0
  111. package/dist/schema/instance.js +147 -0
  112. package/dist/schema/instance.js.map +1 -0
  113. package/dist/schema/job.d.ts +151 -0
  114. package/dist/schema/job.js +73 -0
  115. package/dist/schema/job.js.map +1 -0
  116. package/dist/schema/jsonld.d.ts +18 -0
  117. package/dist/schema/jsonld.js +120 -0
  118. package/dist/schema/jsonld.js.map +1 -0
  119. package/dist/schema/query.d.ts +47 -0
  120. package/dist/schema/query.js +103 -0
  121. package/dist/schema/query.js.map +1 -0
  122. package/dist/schema/text.d.ts +27 -0
  123. package/dist/schema/text.js +117 -0
  124. package/dist/schema/text.js.map +1 -0
  125. package/dist/server/app.d.ts +13 -0
  126. package/dist/server/app.js +57 -0
  127. package/dist/server/app.js.map +1 -0
  128. package/dist/server/deps.d.ts +20 -0
  129. package/dist/server/deps.js +2 -0
  130. package/dist/server/deps.js.map +1 -0
  131. package/dist/server/middleware.d.ts +39 -0
  132. package/dist/server/middleware.js +100 -0
  133. package/dist/server/middleware.js.map +1 -0
  134. package/dist/server/routes/api.d.ts +20 -0
  135. package/dist/server/routes/api.js +584 -0
  136. package/dist/server/routes/api.js.map +1 -0
  137. package/dist/server/routes/descriptor.d.ts +11 -0
  138. package/dist/server/routes/descriptor.js +31 -0
  139. package/dist/server/routes/descriptor.js.map +1 -0
  140. package/dist/server/routes/discovery.d.ts +12 -0
  141. package/dist/server/routes/discovery.js +305 -0
  142. package/dist/server/routes/discovery.js.map +1 -0
  143. package/dist/server/routes/mcp.d.ts +19 -0
  144. package/dist/server/routes/mcp.js +85 -0
  145. package/dist/server/routes/mcp.js.map +1 -0
  146. package/dist/server/routes/openapi.d.ts +11 -0
  147. package/dist/server/routes/openapi.js +297 -0
  148. package/dist/server/routes/openapi.js.map +1 -0
  149. package/dist/server/routes/pages.d.ts +11 -0
  150. package/dist/server/routes/pages.js +445 -0
  151. package/dist/server/routes/pages.js.map +1 -0
  152. package/dist/server/routes/passkey.d.ts +20 -0
  153. package/dist/server/routes/passkey.js +198 -0
  154. package/dist/server/routes/passkey.js.map +1 -0
  155. package/dist/server/routes/specs.d.ts +10 -0
  156. package/dist/server/routes/specs.js +42 -0
  157. package/dist/server/routes/specs.js.map +1 -0
  158. package/dist/server/serve.d.ts +11 -0
  159. package/dist/server/serve.js +79 -0
  160. package/dist/server/serve.js.map +1 -0
  161. package/dist/tui/index.d.ts +13 -0
  162. package/dist/tui/index.js +266 -0
  163. package/dist/tui/index.js.map +1 -0
  164. package/dist/tui/state.d.ts +63 -0
  165. package/dist/tui/state.js +136 -0
  166. package/dist/tui/state.js.map +1 -0
  167. package/dist/tui/types.d.ts +2 -0
  168. package/dist/tui/types.js +2 -0
  169. package/dist/tui/types.js.map +1 -0
  170. package/dist/tui/views.d.ts +11 -0
  171. package/dist/tui/views.js +197 -0
  172. package/dist/tui/views.js.map +1 -0
  173. package/dist/views/auth.d.ts +21 -0
  174. package/dist/views/auth.js +5 -0
  175. package/dist/views/auth.js.map +1 -0
  176. package/dist/views/docs.d.ts +17 -0
  177. package/dist/views/docs.js +40 -0
  178. package/dist/views/docs.js.map +1 -0
  179. package/dist/views/jobs.d.ts +49 -0
  180. package/dist/views/jobs.js +44 -0
  181. package/dist/views/jobs.js.map +1 -0
  182. package/dist/views/layout.d.ts +58 -0
  183. package/dist/views/layout.js +36 -0
  184. package/dist/views/layout.js.map +1 -0
  185. package/dist/views/me.d.ts +27 -0
  186. package/dist/views/me.js +6 -0
  187. package/dist/views/me.js.map +1 -0
  188. package/dist/views/network.d.ts +21 -0
  189. package/dist/views/network.js +17 -0
  190. package/dist/views/network.js.map +1 -0
  191. package/dist/views/post.d.ts +22 -0
  192. package/dist/views/post.js +20 -0
  193. package/dist/views/post.js.map +1 -0
  194. package/docs/openjob.md +200 -0
  195. package/docs/openresume.md +143 -0
  196. package/migrations/0001_init.sql +109 -0
  197. package/migrations/0002_auth.sql +82 -0
  198. package/migrations/0003_directory.sql +27 -0
  199. package/migrations/0004_resumes.sql +63 -0
  200. package/migrations/0005_application_drafts.sql +20 -0
  201. package/package.json +92 -0
  202. package/web/public/app.css +731 -0
  203. package/web/public/app.js +173 -0
  204. package/web/public/icon.svg +5 -0
  205. package/web/public/sw.js +64 -0
  206. package/web/public/tokens.css +153 -0
@@ -0,0 +1,584 @@
1
+ /**
2
+ * The REST API.
3
+ *
4
+ * Every other surface is a client of this: the CLI, the TUI, the desktop app,
5
+ * the MCP tools and one instance searching another. The HTML pages are the one
6
+ * exception, and only because they render server-side from the same core
7
+ * functions rather than from a second set of queries.
8
+ *
9
+ * Two rules hold throughout:
10
+ *
11
+ * 1. An error is an object with a message a person could act on, not a status
12
+ * code and an empty body. Half the callers here are models.
13
+ * 2. Reads are public unless the data belongs to someone. A job board whose
14
+ * listings need a key is a job board nobody's agent will ever read.
15
+ */
16
+ import { Hono } from 'hono';
17
+ import { approveDeviceCode, createSession, ensureUser, normaliseEmail, pollDeviceAuth, requireAdmin, startDeviceAuth, startMagicLink, } from "../../core/auth.js";
18
+ import { createApplication, listApplications, listDraftApplications, recentApplicationCount, submitApplication, validateApplication, } from "../../core/applications.js";
19
+ import { countJobs, createJob, getJobBySlug, normaliseInput, searchJobs, setStatus, } from "../../core/jobs.js";
20
+ import { createOrg, getOrgBySlug, isMember, listOrgs, listOrgsForUser } from "../../core/orgs.js";
21
+ import { createResume, deleteResume, getResume, getResumeById, getSharedResume, isVisibility, listResumes, updateResume, } from "../../core/resumes.js";
22
+ import { importDocument, ImportProblem, MAX_UPLOAD_BYTES } from "../../core/import.js";
23
+ import { announce, Blocked, listInstances, listTopics } from "../../directory/registry.js";
24
+ import { federatedSearch, targetsFromDescriptors } from "../../directory/federate.js";
25
+ import { FetchProblem } from "../../directory/fetch.js";
26
+ import { parseQuery } from "../../schema/query.js";
27
+ import { jobPostingJsonLd } from "../../schema/jsonld.js";
28
+ import { parseResume } from "../../markup/resume.js";
29
+ import { renderMarkdown } from "../../markup/markdown.js";
30
+ import { descriptorFor } from "./descriptor.js";
31
+ import { openApiDocument } from "./openapi.js";
32
+ function fail(c, status, code, message, fields) {
33
+ const body = { error: { message, code, ...(fields === undefined ? {} : { fields }) } };
34
+ return c.json(body, status);
35
+ }
36
+ function viewerOf(c) {
37
+ return c.get('viewer');
38
+ }
39
+ /** Body from JSON or a form, so curl, a browser and a model all work. */
40
+ async function readBody(c) {
41
+ const type = c.req.header('content-type') ?? '';
42
+ try {
43
+ if (type.includes('application/json')) {
44
+ const parsed = (await c.req.json());
45
+ return typeof parsed === 'object' && parsed !== null
46
+ ? parsed
47
+ : {};
48
+ }
49
+ const form = await c.req.parseBody({ all: true });
50
+ return form;
51
+ }
52
+ catch {
53
+ return {};
54
+ }
55
+ }
56
+ export function apiRoutes() {
57
+ const api = new Hono();
58
+ // --- jobs -------------------------------------------------------------
59
+ api.get('/jobs', async (c) => {
60
+ const { pool } = c.get('deps');
61
+ const query = parseQuery(new URL(c.req.url).searchParams);
62
+ const page = await searchJobs(pool, query);
63
+ return c.json({ ...page, query });
64
+ });
65
+ api.get('/jobs/:slug', async (c) => {
66
+ const { pool, config } = c.get('deps');
67
+ const job = await getJobBySlug(pool, c.req.param('slug'));
68
+ if (job === null)
69
+ return fail(c, 404, 'not_found', 'No such job, or it is not published.');
70
+ return c.json({
71
+ job,
72
+ html: renderMarkdown(job.description, { headingOffset: 2 }),
73
+ jsonld: jobPostingJsonLd(job, config.publicUrl),
74
+ });
75
+ });
76
+ /**
77
+ * The application form, as data.
78
+ *
79
+ * This is the endpoint that makes the board agentic: an agent reads the
80
+ * fields it has to fill in and the address to post them to, and never has to
81
+ * render a page or guess a form encoding.
82
+ */
83
+ api.get('/jobs/:slug/apply-schema', async (c) => {
84
+ const { pool, config } = c.get('deps');
85
+ const job = await getJobBySlug(pool, c.req.param('slug'));
86
+ if (job === null)
87
+ return fail(c, 404, 'not_found', 'No such job, or it is not published.');
88
+ if (job.apply.via !== 'board') {
89
+ return c.json({
90
+ via: job.apply.via,
91
+ target: job.apply.via === 'url' ? job.apply.url : job.apply.email,
92
+ agentPolicy: job.agentPolicy,
93
+ message: job.apply.via === 'url'
94
+ ? 'This employer takes applications on their own site.'
95
+ : 'This employer takes applications by email.',
96
+ });
97
+ }
98
+ return c.json({
99
+ via: 'board',
100
+ endpoint: `${config.publicUrl}/api/v1/jobs/${job.slug}/apply`,
101
+ method: 'POST',
102
+ agentPolicy: job.agentPolicy,
103
+ schema: job.apply.schema,
104
+ resume: {
105
+ format: 'openresume.md',
106
+ accepts: 'markdown',
107
+ field: 'resume',
108
+ spec: `${config.publicUrl}/docs/openresume`,
109
+ },
110
+ disclosure: {
111
+ field: 'agent',
112
+ shape: { name: 'string', supervised: 'boolean' },
113
+ required: job.agentPolicy === 'disclose',
114
+ note: job.agentPolicy === 'human-only'
115
+ ? 'This employer asks for applications written by a person.'
116
+ : 'Say which agent wrote this, if one did.',
117
+ },
118
+ });
119
+ });
120
+ api.post('/jobs/:slug/apply', async (c) => {
121
+ const { pool } = c.get('deps');
122
+ const job = await getJobBySlug(pool, c.req.param('slug'));
123
+ if (job === null)
124
+ return fail(c, 404, 'not_found', 'No such job, or it is not published.');
125
+ if (job.apply.via !== 'board') {
126
+ return fail(c, 400, 'wrong_channel', job.apply.via === 'url'
127
+ ? `This employer takes applications at ${job.apply.url}`
128
+ : `This employer takes applications at ${job.apply.email}`);
129
+ }
130
+ const body = await readBody(c);
131
+ const validated = validateApplication(job.apply.schema, body, job.agentPolicy);
132
+ if (!validated.ok) {
133
+ return fail(c, 400, 'invalid', 'Some answers need fixing.', validated.problems);
134
+ }
135
+ const email = validated.value.answers['email'] ?? '';
136
+ if (email !== '') {
137
+ const recent = await recentApplicationCount(pool, email);
138
+ if (recent >= 20) {
139
+ return fail(c, 429, 'rate_limited', 'That address has sent a lot of applications in the last hour. Try again later.');
140
+ }
141
+ }
142
+ const viewer = viewerOf(c);
143
+ const resolved = await resolveResume(c, body, viewer);
144
+ // `typeof null` is 'object', so the error case is checked by shape and not
145
+ // by typeof alone.
146
+ if (resolved !== null && typeof resolved === 'object') {
147
+ return fail(c, 400, 'invalid_resume', resolved.error);
148
+ }
149
+ const resumeMarkdown = resolved;
150
+ // `submit: false` holds it as a draft for a person to release. This is the
151
+ // candidate's half of the same seam an employer has with job drafts: an
152
+ // agent can do the work, a person decides it goes out.
153
+ const submit = body['submit'] !== false && body['submit'] !== 'false';
154
+ if (!submit && viewer === null) {
155
+ return fail(c, 401, 'unauthenticated', 'Holding an application as a draft needs an account, otherwise nobody could come back to release it.');
156
+ }
157
+ const application = await createApplication(pool, job.id, validated.value, { submit });
158
+ if (resumeMarkdown !== null || viewer !== null) {
159
+ await pool.query(`update applications set resume_markdown = $2, resume_title = $3, user_id = $4
160
+ where id = $1`, [
161
+ application.id,
162
+ resumeMarkdown,
163
+ resumeMarkdown === null ? null : (parseResume(resumeMarkdown).name ?? 'Resume'),
164
+ viewer?.id ?? null,
165
+ ]);
166
+ }
167
+ return c.json({
168
+ ok: true,
169
+ applicationId: application.id,
170
+ job: job.slug,
171
+ status: application.status,
172
+ submitted: submit,
173
+ ...(submit
174
+ ? {}
175
+ : {
176
+ message: 'Held as a draft. Nobody at the employer can see it until it is submitted.',
177
+ submitWith: `POST /api/v1/applications/${application.id}/submit`,
178
+ }),
179
+ }, 201);
180
+ });
181
+ api.post('/jobs', async (c) => {
182
+ const { pool } = c.get('deps');
183
+ const viewer = viewerOf(c);
184
+ if (viewer === null)
185
+ return fail(c, 401, 'unauthenticated', 'Sign in to post a job.');
186
+ const body = await readBody(c);
187
+ const orgSlug = typeof body['org'] === 'string' ? body['org'] : '';
188
+ const org = orgSlug === '' ? null : await getOrgBySlug(pool, orgSlug);
189
+ if (org === null) {
190
+ return fail(c, 400, 'no_org', 'Name the employer to post under, as "org": "<slug>".');
191
+ }
192
+ if (!(await isMember(pool, viewer.id, org.id))) {
193
+ return fail(c, 403, 'not_a_member', `You are not a member of ${org.name}.`);
194
+ }
195
+ const input = normaliseInput(body, org.id);
196
+ if (typeof input === 'string')
197
+ return fail(c, 400, 'invalid', input);
198
+ const job = await createJob(pool, input);
199
+ // A job posted through the API arrives as a draft like any other, unless
200
+ // the caller asked for it to go live. An agent that posts a job the author
201
+ // has not read is the failure mode worth designing against.
202
+ if (body['publish'] === true || body['publish'] === 'true') {
203
+ const published = await setStatus(pool, job.id, 'published');
204
+ return c.json({ job: published ?? job }, 201);
205
+ }
206
+ return c.json({ job }, 201);
207
+ });
208
+ api.post('/jobs/:slug/:action{publish|close|reopen}', async (c) => {
209
+ const { pool } = c.get('deps');
210
+ const viewer = viewerOf(c);
211
+ if (viewer === null)
212
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
213
+ const job = await getJobBySlug(pool, c.req.param('slug'), { includeUnpublished: true });
214
+ if (job === null)
215
+ return fail(c, 404, 'not_found', 'No such job.');
216
+ if (!(await isMember(pool, viewer.id, job.org.id))) {
217
+ return fail(c, 403, 'not_a_member', `You are not a member of ${job.org.name}.`);
218
+ }
219
+ const action = c.req.param('action');
220
+ const status = action === 'close' ? 'closed' : 'published';
221
+ const updated = await setStatus(pool, job.id, status);
222
+ return c.json({ job: updated });
223
+ });
224
+ api.get('/jobs/:slug/applications', async (c) => {
225
+ const { pool } = c.get('deps');
226
+ const viewer = viewerOf(c);
227
+ if (viewer === null)
228
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
229
+ const job = await getJobBySlug(pool, c.req.param('slug'), { includeUnpublished: true });
230
+ if (job === null)
231
+ return fail(c, 404, 'not_found', 'No such job.');
232
+ if (!(await isMember(pool, viewer.id, job.org.id))) {
233
+ return fail(c, 403, 'not_a_member', `You are not a member of ${job.org.name}.`);
234
+ }
235
+ const applications = await listApplications(pool, job.id);
236
+ const withResumes = await Promise.all(applications.map(async (application) => {
237
+ const row = await pool.query(`select resume_markdown, resume_title from applications where id = $1`, [application.id]);
238
+ return {
239
+ ...application,
240
+ resume: row.rows[0]?.resume_markdown ?? null,
241
+ resumeTitle: row.rows[0]?.resume_title ?? null,
242
+ };
243
+ }));
244
+ return c.json({ job: job.slug, items: withResumes, total: withResumes.length });
245
+ });
246
+ /**
247
+ * Applications you have prepared but not sent.
248
+ *
249
+ * The review step for a candidate, reachable from a browser, the CLI, the
250
+ * TUI or a tool call - it is the same endpoint for all of them.
251
+ */
252
+ api.get('/applications/drafts', async (c) => {
253
+ const { pool } = c.get('deps');
254
+ const viewer = viewerOf(c);
255
+ if (viewer === null)
256
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
257
+ const items = await listDraftApplications(pool, viewer.id);
258
+ return c.json({ items, total: items.length });
259
+ });
260
+ api.post('/applications/:id/submit', async (c) => {
261
+ const { pool } = c.get('deps');
262
+ const viewer = viewerOf(c);
263
+ if (viewer === null)
264
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
265
+ const sent = await submitApplication(pool, c.req.param('id'), viewer.id);
266
+ if (!sent) {
267
+ return fail(c, 404, 'not_found', 'No draft of yours with that id. It may already have been sent.');
268
+ }
269
+ return c.json({ ok: true, submitted: true });
270
+ });
271
+ // --- employers --------------------------------------------------------
272
+ api.get('/orgs', async (c) => {
273
+ const { pool } = c.get('deps');
274
+ return c.json({ items: await listOrgs(pool) });
275
+ });
276
+ api.get('/orgs/:slug', async (c) => {
277
+ const { pool } = c.get('deps');
278
+ const org = await getOrgBySlug(pool, c.req.param('slug'));
279
+ if (org === null)
280
+ return fail(c, 404, 'not_found', 'No such employer.');
281
+ const query = parseQuery(new URLSearchParams({ org: org.slug }));
282
+ const jobs = await searchJobs(pool, query);
283
+ return c.json({ org, jobs });
284
+ });
285
+ api.post('/orgs', async (c) => {
286
+ const { pool } = c.get('deps');
287
+ const viewer = viewerOf(c);
288
+ if (viewer === null)
289
+ return fail(c, 401, 'unauthenticated', 'Sign in to add an employer.');
290
+ const body = await readBody(c);
291
+ const created = await createOrg(pool, viewer.id, {
292
+ name: typeof body['name'] === 'string' ? body['name'] : '',
293
+ website: typeof body['website'] === 'string' ? body['website'] : null,
294
+ description: typeof body['description'] === 'string' ? body['description'] : null,
295
+ logoUrl: typeof body['logoUrl'] === 'string' ? body['logoUrl'] : null,
296
+ });
297
+ if (typeof created === 'string')
298
+ return fail(c, 400, 'invalid', created);
299
+ return c.json({ org: created }, 201);
300
+ });
301
+ // --- me and resumes ---------------------------------------------------
302
+ api.get('/me', async (c) => {
303
+ const { pool } = c.get('deps');
304
+ const viewer = viewerOf(c);
305
+ if (viewer === null)
306
+ return fail(c, 401, 'unauthenticated', 'No token, or it has expired.');
307
+ return c.json({
308
+ user: {
309
+ id: viewer.id,
310
+ email: viewer.email,
311
+ name: viewer.name,
312
+ isAdmin: viewer.isAdmin,
313
+ viaToken: viewer.viaToken,
314
+ },
315
+ orgs: await listOrgsForUser(pool, viewer.id),
316
+ resumes: (await listResumes(pool, viewer.id)).map((resume) => ({
317
+ slug: resume.slug,
318
+ title: resume.title,
319
+ visibility: resume.visibility,
320
+ updatedAt: resume.updatedAt,
321
+ })),
322
+ });
323
+ });
324
+ api.get('/resumes', async (c) => {
325
+ const { pool } = c.get('deps');
326
+ const viewer = viewerOf(c);
327
+ if (viewer === null)
328
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
329
+ return c.json({ items: await listResumes(pool, viewer.id) });
330
+ });
331
+ api.get('/resumes/:slug', async (c) => {
332
+ const { pool } = c.get('deps');
333
+ const viewer = viewerOf(c);
334
+ if (viewer === null)
335
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
336
+ const resume = await getResume(pool, viewer.id, c.req.param('slug'));
337
+ if (resume === null)
338
+ return fail(c, 404, 'not_found', 'No such resume.');
339
+ return c.json({ resume, html: renderMarkdown(resume.markdown, { headingOffset: 1, noImages: true }) });
340
+ });
341
+ api.post('/resumes', async (c) => {
342
+ const { pool } = c.get('deps');
343
+ const viewer = viewerOf(c);
344
+ if (viewer === null)
345
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
346
+ const body = await readBody(c);
347
+ const markdown = typeof body['markdown'] === 'string' ? body['markdown'] : '';
348
+ if (markdown.trim() === '') {
349
+ return fail(c, 400, 'invalid', 'Send the resume as Markdown in a "markdown" field.');
350
+ }
351
+ const visibility = body['visibility'];
352
+ const resume = await createResume(pool, viewer.id, {
353
+ markdown,
354
+ ...(typeof body['title'] === 'string' ? { title: body['title'] } : {}),
355
+ ...(isVisibility(visibility) ? { visibility } : {}),
356
+ });
357
+ return c.json({ resume }, 201);
358
+ });
359
+ api.patch('/resumes/:slug', async (c) => {
360
+ const { pool } = c.get('deps');
361
+ const viewer = viewerOf(c);
362
+ if (viewer === null)
363
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
364
+ const body = await readBody(c);
365
+ const existing = await getResume(pool, viewer.id, c.req.param('slug'));
366
+ if (existing === null)
367
+ return fail(c, 404, 'not_found', 'No such resume.');
368
+ const visibility = body['visibility'];
369
+ const resume = await updateResume(pool, viewer.id, c.req.param('slug'), {
370
+ markdown: typeof body['markdown'] === 'string' ? body['markdown'] : existing.markdown,
371
+ ...(typeof body['title'] === 'string' ? { title: body['title'] } : {}),
372
+ ...(isVisibility(visibility) ? { visibility } : {}),
373
+ });
374
+ return c.json({ resume });
375
+ });
376
+ api.delete('/resumes/:slug', async (c) => {
377
+ const { pool } = c.get('deps');
378
+ const viewer = viewerOf(c);
379
+ if (viewer === null)
380
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
381
+ const removed = await deleteResume(pool, viewer.id, c.req.param('slug'));
382
+ if (!removed)
383
+ return fail(c, 404, 'not_found', 'No such resume.');
384
+ return c.json({ ok: true });
385
+ });
386
+ /**
387
+ * Upload a document and get Markdown back.
388
+ *
389
+ * The result is stored as a resume the candidate can then edit, because a
390
+ * conversion nobody checks is a conversion nobody trusts.
391
+ */
392
+ api.post('/resumes/import', async (c) => {
393
+ const { pool } = c.get('deps');
394
+ const viewer = viewerOf(c);
395
+ if (viewer === null)
396
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
397
+ let file = null;
398
+ try {
399
+ const form = await c.req.parseBody();
400
+ const candidate = form['file'];
401
+ if (candidate instanceof File)
402
+ file = candidate;
403
+ }
404
+ catch {
405
+ file = null;
406
+ }
407
+ if (file === null)
408
+ return fail(c, 400, 'no_file', 'Attach the document as a "file" field.');
409
+ if (file.size > MAX_UPLOAD_BYTES) {
410
+ return fail(c, 413, 'too_large', `The limit is ${MAX_UPLOAD_BYTES / 1024 / 1024}MB.`);
411
+ }
412
+ const bytes = Buffer.from(await file.arrayBuffer());
413
+ try {
414
+ const imported = await importDocument(file.name, bytes, file.type);
415
+ const resume = await createResume(pool, viewer.id, {
416
+ markdown: imported.markdown,
417
+ source: { name: file.name, mime: file.type || 'application/octet-stream', bytes },
418
+ });
419
+ return c.json({ resume, via: imported.via, warnings: imported.warnings }, 201);
420
+ }
421
+ catch (error) {
422
+ if (error instanceof ImportProblem)
423
+ return fail(c, 400, 'import_failed', error.message);
424
+ throw error;
425
+ }
426
+ });
427
+ // --- sign in ----------------------------------------------------------
428
+ api.post('/auth/magic-link', async (c) => {
429
+ const { pool, config } = c.get('deps');
430
+ const body = await readBody(c);
431
+ const email = normaliseEmail(body['email']);
432
+ if (email === null)
433
+ return fail(c, 400, 'invalid', 'That is not an email address.');
434
+ const link = await startMagicLink(pool, email, null);
435
+ const url = `${config.publicUrl}/auth/callback?token=${link.token}`;
436
+ // Without SMTP the link is logged rather than silently dropped, which is
437
+ // what makes a laptop run work at all.
438
+ if (config.smtpUrl === null)
439
+ console.log(`magic link for ${email}: ${url}`);
440
+ return c.json({ ok: true, expiresAt: link.expiresAt, delivered: config.smtpUrl !== null });
441
+ });
442
+ api.post('/auth/device', async (c) => {
443
+ const { pool, config } = c.get('deps');
444
+ const body = await readBody(c);
445
+ const label = typeof body['label'] === 'string' ? body['label'] : 'terminal';
446
+ const grant = await startDeviceAuth(pool, label, config.publicUrl);
447
+ return c.json(grant);
448
+ });
449
+ api.post('/auth/device/poll', async (c) => {
450
+ const { pool } = c.get('deps');
451
+ const body = await readBody(c);
452
+ const deviceCode = typeof body['deviceCode'] === 'string' ? body['deviceCode'] : '';
453
+ if (deviceCode === '')
454
+ return fail(c, 400, 'invalid', 'Send the deviceCode you were given.');
455
+ return c.json(await pollDeviceAuth(pool, deviceCode));
456
+ });
457
+ api.post('/auth/device/approve', async (c) => {
458
+ const { pool } = c.get('deps');
459
+ const viewer = viewerOf(c);
460
+ if (viewer === null)
461
+ return fail(c, 401, 'unauthenticated', 'Sign in first.');
462
+ const body = await readBody(c);
463
+ const code = typeof body['userCode'] === 'string' ? body['userCode'] : '';
464
+ const approved = await approveDeviceCode(pool, code, viewer.id);
465
+ if (!approved)
466
+ return fail(c, 404, 'no_such_code', 'That code is unknown or has expired.');
467
+ return c.json({ ok: true });
468
+ });
469
+ // --- federation -------------------------------------------------------
470
+ api.get('/directory/instances', async (c) => {
471
+ const { pool, config } = c.get('deps');
472
+ if (!config.isDirectory)
473
+ return fail(c, 404, 'not_a_directory', 'This instance is not a directory.');
474
+ const params = new URL(c.req.url).searchParams;
475
+ const items = await listInstances(pool, {
476
+ topic: params.get('topic'),
477
+ q: params.get('q'),
478
+ onlineOnly: params.get('online') === 'true',
479
+ limit: Number(params.get('limit') ?? '100'),
480
+ });
481
+ return c.json({ items, total: items.length });
482
+ });
483
+ api.get('/directory/topics', async (c) => {
484
+ const { pool, config } = c.get('deps');
485
+ if (!config.isDirectory)
486
+ return fail(c, 404, 'not_a_directory', 'This instance is not a directory.');
487
+ return c.json({ items: await listTopics(pool) });
488
+ });
489
+ api.post('/directory/announce', async (c) => {
490
+ const { pool, config } = c.get('deps');
491
+ if (!config.isDirectory) {
492
+ return fail(c, 404, 'not_a_directory', 'This instance is not a directory.');
493
+ }
494
+ const body = await readBody(c);
495
+ const url = typeof body['url'] === 'string' ? body['url'] : '';
496
+ try {
497
+ const listing = await announce(pool, url);
498
+ return c.json({ ok: true, instance: listing });
499
+ }
500
+ catch (error) {
501
+ if (error instanceof Blocked)
502
+ return fail(c, 403, 'blocked', error.message);
503
+ if (error instanceof FetchProblem) {
504
+ // The instance is the one that has to fix this, so say what we saw.
505
+ return fail(c, 400, 'unreachable', error.message);
506
+ }
507
+ throw error;
508
+ }
509
+ });
510
+ /** One question, every instance the directory knows about. */
511
+ api.get('/directory/search', async (c) => {
512
+ const { pool, config } = c.get('deps');
513
+ if (!config.isDirectory)
514
+ return fail(c, 404, 'not_a_directory', 'This instance is not a directory.');
515
+ const params = new URL(c.req.url).searchParams;
516
+ const query = parseQuery(params);
517
+ const instances = await listInstances(pool, { onlineOnly: true, limit: 40 });
518
+ const result = await federatedSearch(targetsFromDescriptors(instances.map((instance) => instance.descriptor)), query);
519
+ return c.json(result);
520
+ });
521
+ // --- this instance ----------------------------------------------------
522
+ api.get('/openapi.json', (c) => {
523
+ const { config } = c.get('deps');
524
+ return c.json(openApiDocument(config));
525
+ });
526
+ api.get('/stats', async (c) => {
527
+ const { pool, config } = c.get('deps');
528
+ return c.json({
529
+ board: config.boardName,
530
+ url: config.publicUrl,
531
+ jobs: await countJobs(pool),
532
+ directory: config.isDirectory,
533
+ });
534
+ });
535
+ api.get('/descriptor', async (c) => {
536
+ const { pool, config } = c.get('deps');
537
+ return c.json(await descriptorFor(pool, config));
538
+ });
539
+ api.all('*', (c) => fail(c, 404, 'not_found', `No API route for ${c.req.path}.`));
540
+ return api;
541
+ }
542
+ /**
543
+ * Which resume an application carries.
544
+ *
545
+ * Three ways in, because three kinds of caller apply: a person picks one they
546
+ * have saved, an agent posts Markdown inline, and a stranger with no account
547
+ * pastes it into the form. All three end up as Markdown copied onto the
548
+ * application.
549
+ */
550
+ async function resolveResume(c, body, viewer) {
551
+ const { pool } = c.get('deps');
552
+ const inline = body['resume'];
553
+ if (typeof inline === 'string' && inline.trim() !== '') {
554
+ if (inline.length > 200_000)
555
+ return { error: 'That resume is too long.' };
556
+ return inline;
557
+ }
558
+ const slug = body['resumeSlug'];
559
+ if (typeof slug === 'string' && slug !== '') {
560
+ if (viewer === null)
561
+ return { error: 'Sign in to send a resume you have saved.' };
562
+ const resume = await getResume(pool, viewer.id, slug);
563
+ if (resume === null)
564
+ return { error: `You have no resume called "${slug}".` };
565
+ return resume.markdown;
566
+ }
567
+ const id = body['resumeId'];
568
+ if (typeof id === 'string' && id !== '') {
569
+ // A shared id is accepted from anyone, which is what a share link is for;
570
+ // a private one only from its owner.
571
+ const shared = await getSharedResume(pool, id);
572
+ if (shared !== null)
573
+ return shared.markdown;
574
+ if (viewer !== null) {
575
+ const owned = await getResumeById(pool, id);
576
+ if (owned !== null && owned.userId === viewer.id)
577
+ return owned.markdown;
578
+ }
579
+ return { error: 'That resume is not shared, or does not exist.' };
580
+ }
581
+ return null;
582
+ }
583
+ export { requireAdmin };
584
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/server/routes/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * What this instance says about itself at /.well-known/agenticjobs.
3
+ *
4
+ * Built from live counts rather than from configuration, so an instance cannot
5
+ * advertise a hundred openings it does not have. The directory re-reads this
6
+ * on its own schedule; nothing here is cached longer than a request.
7
+ */
8
+ import type pg from 'pg';
9
+ import type { Config } from '../../config.ts';
10
+ import { type InstanceDescriptor } from '../../schema/instance.ts';
11
+ export declare function descriptorFor(pool: pg.Pool, config: Config): Promise<InstanceDescriptor>;