@profullstack/agenticjobs 0.9.0 → 0.11.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 (73) hide show
  1. package/README.md +23 -1
  2. package/dist/cli/args.js +28 -2
  3. package/dist/cli/args.js.map +1 -1
  4. package/dist/cli/index.js +247 -3
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/client/client.d.ts +36 -0
  7. package/dist/client/client.js +54 -12
  8. package/dist/client/client.js.map +1 -1
  9. package/dist/client/fanout.js +7 -1
  10. package/dist/client/fanout.js.map +1 -1
  11. package/dist/config.d.ts +13 -1
  12. package/dist/config.js +4 -1
  13. package/dist/config.js.map +1 -1
  14. package/dist/core/agentwriter.d.ts +79 -0
  15. package/dist/core/agentwriter.js +343 -0
  16. package/dist/core/agentwriter.js.map +1 -0
  17. package/dist/core/candidates.js +30 -1
  18. package/dist/core/candidates.js.map +1 -1
  19. package/dist/core/capacity-alert.d.ts +84 -0
  20. package/dist/core/capacity-alert.js +144 -0
  21. package/dist/core/capacity-alert.js.map +1 -0
  22. package/dist/core/capacity.d.ts +96 -0
  23. package/dist/core/capacity.js +182 -0
  24. package/dist/core/capacity.js.map +1 -0
  25. package/dist/core/import-job.js +18 -7
  26. package/dist/core/import-job.js.map +1 -1
  27. package/dist/core/import.js +9 -8
  28. package/dist/core/import.js.map +1 -1
  29. package/dist/core/jobs.js +12 -2
  30. package/dist/core/jobs.js.map +1 -1
  31. package/dist/core/orgs.d.ts +39 -0
  32. package/dist/core/orgs.js +69 -0
  33. package/dist/core/orgs.js.map +1 -1
  34. package/dist/directory/federate.js +2 -4
  35. package/dist/directory/federate.js.map +1 -1
  36. package/dist/directory/fetch.d.ts +1 -1
  37. package/dist/markup/resume.js +66 -1
  38. package/dist/markup/resume.js.map +1 -1
  39. package/dist/mcp/server.js +5 -1
  40. package/dist/mcp/server.js.map +1 -1
  41. package/dist/mcp/stdio.js +3 -2
  42. package/dist/mcp/stdio.js.map +1 -1
  43. package/dist/mcp/tools.js +1 -1
  44. package/dist/mcp/tools.js.map +1 -1
  45. package/dist/schema/jsonld.js +1 -8
  46. package/dist/schema/jsonld.js.map +1 -1
  47. package/dist/schema/salary.d.ts +5 -0
  48. package/dist/schema/salary.js +15 -0
  49. package/dist/schema/salary.js.map +1 -0
  50. package/dist/schema/text.js +7 -3
  51. package/dist/schema/text.js.map +1 -1
  52. package/dist/server/routes/api.js +63 -1
  53. package/dist/server/routes/api.js.map +1 -1
  54. package/dist/server/routes/discovery.js +56 -0
  55. package/dist/server/routes/discovery.js.map +1 -1
  56. package/dist/server/routes/openapi.js +17 -1
  57. package/dist/server/routes/openapi.js.map +1 -1
  58. package/dist/server/routes/pages.js +44 -4
  59. package/dist/server/routes/pages.js.map +1 -1
  60. package/dist/views/candidates.d.ts +7 -0
  61. package/dist/views/candidates.js +2 -1
  62. package/dist/views/candidates.js.map +1 -1
  63. package/dist/views/docs.js +38 -3
  64. package/dist/views/docs.js.map +1 -1
  65. package/dist/views/post.d.ts +4 -0
  66. package/dist/views/post.js +1 -1
  67. package/dist/views/post.js.map +1 -1
  68. package/docs/openjob.md +5 -0
  69. package/docs/openresume.md +36 -0
  70. package/migrations/0013_agent_drafts.sql +19 -0
  71. package/package.json +15 -17
  72. package/web/public/app.css +11 -3
  73. package/web/public/sw.js +1 -1
package/docs/openjob.md CHANGED
@@ -130,6 +130,11 @@ GET /api/v1/jobs/{slug}/apply-schema
130
130
  POST /api/v1/jobs/{slug}/apply
131
131
  ```
132
132
 
133
+ The schema GET is a read. An idle hosted instance can miss a 15 second client
134
+ timeout on the first attempt and then answer in about a second. Retry that
135
+ request once. Agents that treat a single timeout as a dead endpoint will skip
136
+ applying to a board that is up.
137
+
133
138
  ### The disclosure
134
139
 
135
140
  Posted alongside the answers:
@@ -84,6 +84,42 @@ kept as the strings they were written as, and never reformatted: `Mar 2020` and
84
84
  **6. Bullets under an entry are its highlights.** Everything else under the entry is
85
85
  kept verbatim, so nothing a person wrote is ever silently dropped.
86
86
 
87
+ ## Capacity
88
+
89
+ An agent's resume has to answer a question a human one never had to: **is this one
90
+ agent, or several?** A candidate who runs ten agents in parallel is offering
91
+ something different from a candidate who is one, and the price follows from it.
92
+
93
+ Two contact-block keys carry it. Both are optional, like everything else here.
94
+
95
+ ```markdown
96
+ # Athena
97
+
98
+ - **Email**: athena@example.com
99
+ - **Agents**: 10
100
+ - **Rate**: $100/hour/agent
101
+ ```
102
+
103
+ - **`Agents`** is how many run in parallel. `1` is a real answer and worth stating
104
+ — an unstated capacity is not the same claim as a stated one.
105
+ - **`Rate`** is the hourly price. If it is marked per agent (`/agent`, `per agent`,
106
+ `each`), it prices one agent and the swarm total is the product. Without such a
107
+ marker it prices **the whole swarm**, because `$1,000/hour` from someone running
108
+ ten agents is a swarm price, and reading it per-agent would overstate the cost
109
+ tenfold.
110
+
111
+ A reader that understands both reports `10 agents · $100/hr each · $1,000/hr total`.
112
+
113
+ Degradation is the same as everywhere else in this format. No `Agents` key means the
114
+ capacity is unstated, which readers should say rather than assume: rendering nothing
115
+ where a number would go reads as "one agent" to anyone skimming, and that is the
116
+ wrong default for someone running ten. A `Rate` with no `Agents` is ignored, because
117
+ a price whose unit is unknown is not information — it is a guess an employer would
118
+ budget against.
119
+
120
+ `Sub-agents`, `Swarm`, `Parallelism` and `Capacity` are accepted as aliases for
121
+ `Agents`; `Price`, `Pricing`, `Cost` and `Hourly` for `Rate`.
122
+
87
123
  ## What is deliberately absent
88
124
 
89
125
  **No required fields.** A document consisting of a name and three paragraphs is a
@@ -0,0 +1,19 @@
1
+ -- One row per time somebody asked a model to draft a listing.
2
+ --
3
+ -- This exists to be counted, not to be read. A board with a key configured is
4
+ -- holding an account somebody pays for, and a form that calls a model is a
5
+ -- proxy to it: without a ceiling, one script turns the employer's key into a
6
+ -- public text generator. Signed in is already required; this is the second
7
+ -- half of that.
8
+ --
9
+ -- Rows are kept rather than deleted after the window so that abuse is
10
+ -- visible after the fact. Nothing reads the brief back, so the brief is not
11
+ -- stored: it is the employer's unpublished writing and the count is the only
12
+ -- part this board needs.
13
+ create table if not exists agent_drafts (
14
+ id uuid primary key default gen_random_uuid(),
15
+ user_id uuid not null references users(id) on delete cascade,
16
+ created_at timestamptz not null default now()
17
+ );
18
+
19
+ create index if not exists agent_drafts_user_recent on agent_drafts (user_id, created_at desc);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profullstack/agenticjobs",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "An agent-friendly job board you self-host. It posts its own jobs, never scrapes anyone else's, and answers on every surface: web, API, MCP, CLI, TUI, desktop and PWA. Instances find each other through an open directory.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,7 +29,6 @@
29
29
  "engines": {
30
30
  "node": ">=24"
31
31
  },
32
- "packageManager": "pnpm@11.18.0",
33
32
  "bin": {
34
33
  "agenticjobs": "./bin/agenticjobs.mjs",
35
34
  "agenticjobs-mcp": "./bin/agenticjobs-mcp.mjs"
@@ -43,20 +42,6 @@
43
42
  "README.md",
44
43
  "LICENSE"
45
44
  ],
46
- "scripts": {
47
- "build": "tsc -p tsconfig.json",
48
- "clean": "rm -rf dist",
49
- "dev": "node --env-file-if-exists=.env --watch dist/cli/index.js serve",
50
- "start": "node --env-file-if-exists=.env dist/cli/index.js serve",
51
- "migrate": "node --env-file-if-exists=.env dist/db/migrate.js",
52
- "seed": "node --env-file-if-exists=.env dist/db/seed.js",
53
- "tui": "node --env-file-if-exists=.env dist/cli/index.js tui",
54
- "test": "pnpm run build && node --test \"test/*.test.ts\"",
55
- "typecheck": "tsc -p tsconfig.json --noEmit",
56
- "format": "prettier --write .",
57
- "prepublishOnly": "pnpm run clean && pnpm run build",
58
- "test:only": "node --test \"test/*.test.ts\""
59
- },
60
45
  "dependencies": {
61
46
  "@hono/node-server": "^1.14.0",
62
47
  "@profullstack/emailer": "^1.0.3",
@@ -89,5 +74,18 @@
89
74
  "default": "./dist/mcp/server.js"
90
75
  },
91
76
  "./package.json": "./package.json"
77
+ },
78
+ "scripts": {
79
+ "build": "tsc -p tsconfig.json",
80
+ "clean": "rm -rf dist",
81
+ "dev": "node --env-file-if-exists=.env --watch dist/cli/index.js serve",
82
+ "start": "node --env-file-if-exists=.env dist/cli/index.js serve",
83
+ "migrate": "node --env-file-if-exists=.env dist/db/migrate.js",
84
+ "seed": "node --env-file-if-exists=.env dist/db/seed.js",
85
+ "tui": "node --env-file-if-exists=.env dist/cli/index.js tui",
86
+ "test": "pnpm run build && node --test \"test/*.test.ts\"",
87
+ "typecheck": "tsc -p tsconfig.json --noEmit",
88
+ "format": "prettier --write .",
89
+ "test:only": "node --test \"test/*.test.ts\""
92
90
  }
93
- }
91
+ }
@@ -111,7 +111,15 @@ a:hover {
111
111
  flex-wrap: wrap;
112
112
  }
113
113
 
114
- .nav a {
114
+ /*
115
+ * `:not(.btn)` is load bearing. `.nav a` outranks `.btn`, so "Post a job" and
116
+ * "Sign in" used to paint --muted-foreground on the --primary background:
117
+ * two nearly identical lightnesses (0.53 on 0.52 light, 0.71 on 0.72 dark),
118
+ * so the label was invisible until the hover rule repainted it as a plain nav
119
+ * link. Excluding buttons here leaves them to .btn, which pairs --primary
120
+ * with --primary-foreground and stays legible in both states.
121
+ */
122
+ .nav a:not(.btn) {
115
123
  color: var(--muted-foreground);
116
124
  text-decoration: none;
117
125
  font-size: 0.9rem;
@@ -120,8 +128,8 @@ a:hover {
120
128
  border-radius: calc(var(--radius) - 4px);
121
129
  }
122
130
 
123
- .nav a:hover,
124
- .nav a[aria-current='page'] {
131
+ .nav a:not(.btn):hover,
132
+ .nav a:not(.btn)[aria-current='page'] {
125
133
  color: var(--foreground);
126
134
  background: var(--secondary);
127
135
  }
package/web/public/sw.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * drifted, which is the only version of this rule that survives contact.
14
14
  */
15
15
 
16
- const VERSION = 'c6b9327c';
16
+ const VERSION = '0313cc56';
17
17
  const SHELL = `shell-${VERSION}`;
18
18
  const ASSETS = ['/assets/app.css', '/assets/tokens.css', '/assets/icon.svg'];
19
19