@venturewild/workspace 0.5.3 → 0.6.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.
- package/LICENSE +21 -21
- package/README.md +112 -112
- package/package.json +85 -85
- package/server/bin/wild-workspace.mjs +1096 -1096
- package/server/src/account.mjs +114 -114
- package/server/src/agent-login.mjs +146 -146
- package/server/src/agent-readiness.mjs +200 -200
- package/server/src/agent.mjs +468 -468
- package/server/src/bazaar/core.mjs +974 -828
- package/server/src/bazaar/index.mjs +88 -88
- package/server/src/bazaar/mcp-server.mjs +429 -417
- package/server/src/bazaar/mock-tickup.mjs +97 -97
- package/server/src/bazaar/preview-server.mjs +95 -95
- package/server/src/bazaar/seed-recipes/customer-feedback-form/know-how.md +23 -23
- package/server/src/bazaar/seed-recipes/customer-feedback-form/recipe.json +24 -24
- package/server/src/bazaar/seed-recipes/landing-page-launch/know-how.md +29 -29
- package/server/src/bazaar/seed-recipes/landing-page-launch/recipe.json +25 -25
- package/server/src/bazaar/seed-recipes/personal-portfolio/know-how.md +21 -21
- package/server/src/bazaar/seed-recipes/personal-portfolio/recipe.json +24 -24
- package/server/src/bazaar/seed-recipes/receipt-sorter/know-how.md +31 -31
- package/server/src/bazaar/seed-recipes/receipt-sorter/recipe.json +25 -25
- package/server/src/bazaar/seed-recipes/tickup-hr-matching/know-how.md +79 -79
- package/server/src/bazaar/seed-recipes/tickup-hr-matching/recipe.json +40 -40
- package/server/src/canvas/core.mjs +446 -446
- package/server/src/canvas/index.mjs +42 -42
- package/server/src/canvas/mcp-server.mjs +253 -253
- package/server/src/canvas-rails.mjs +108 -108
- package/server/src/config.mjs +404 -404
- package/server/src/daemon-bin.mjs +110 -110
- package/server/src/daemon-supervisor.mjs +285 -285
- package/server/src/doctor.mjs +375 -375
- package/server/src/inbox.mjs +86 -86
- package/server/src/index.mjs +3322 -3279
- package/server/src/listings-rails.mjs +156 -126
- package/server/src/logpaths.mjs +98 -98
- package/server/src/observability.mjs +45 -45
- package/server/src/operator.mjs +92 -92
- package/server/src/pairing.mjs +137 -137
- package/server/src/service.mjs +515 -515
- package/server/src/session-reporter.mjs +201 -201
- package/server/src/settings.mjs +145 -145
- package/server/src/share.mjs +182 -182
- package/server/src/skills.mjs +213 -213
- package/server/src/supervisor.mjs +647 -647
- package/server/src/support-consent.mjs +133 -133
- package/server/src/sync.mjs +248 -248
- package/server/src/transcript.mjs +121 -121
- package/server/src/turn-mcp.mjs +46 -46
- package/server/src/usage.mjs +405 -405
- package/server/src/workspace-presence.mjs +0 -0
- package/server/src/workspace-registry.mjs +295 -295
- package/server/src/workspaces.mjs +145 -145
- package/web/dist/assets/{index-BxTh3dyq.js → index-CSWkWdtM.js} +23 -23
- package/web/dist/index.html +1 -1
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "personal-portfolio",
|
|
3
|
-
"title": "Personal portfolio site",
|
|
4
|
-
"producer": { "name": "Nia", "handle": "nia", "kind": "maker" },
|
|
5
|
-
"pitch": "A sharp one-page portfolio — intro, projects, contact — live in one shot.",
|
|
6
|
-
"vendorDescription": "Nia's portfolio template. The layout that landed her three freelance clients: a confident intro, a project grid, and a contact line that converts.",
|
|
7
|
-
"summary": "A single-page portfolio: hero intro, a grid of project cards, and a contact section. Swap the text and images to make it yours.",
|
|
8
|
-
"outcomeScore": 0.81,
|
|
9
|
-
"outcomeStats": { "builds": 40, "working": 32 },
|
|
10
|
-
"safetyBadge": "tested",
|
|
11
|
-
"rating": { "stars": 4.3, "count": 21 },
|
|
12
|
-
"tags": [
|
|
13
|
-
"portfolio", "personal site", "personal website", "resume site", "cv site",
|
|
14
|
-
"about me", "showcase", "designer portfolio", "developer portfolio", "projects"
|
|
15
|
-
],
|
|
16
|
-
"reward": {
|
|
17
|
-
"model": "one-time",
|
|
18
|
-
"unit": "per build",
|
|
19
|
-
"perUseValue": 0,
|
|
20
|
-
"oneTimeValue": 5.0,
|
|
21
|
-
"note": "Nia earns a one-time share each time her portfolio know-how is used."
|
|
22
|
-
},
|
|
23
|
-
"buildDir": "portfolio"
|
|
24
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "personal-portfolio",
|
|
3
|
+
"title": "Personal portfolio site",
|
|
4
|
+
"producer": { "name": "Nia", "handle": "nia", "kind": "maker" },
|
|
5
|
+
"pitch": "A sharp one-page portfolio — intro, projects, contact — live in one shot.",
|
|
6
|
+
"vendorDescription": "Nia's portfolio template. The layout that landed her three freelance clients: a confident intro, a project grid, and a contact line that converts.",
|
|
7
|
+
"summary": "A single-page portfolio: hero intro, a grid of project cards, and a contact section. Swap the text and images to make it yours.",
|
|
8
|
+
"outcomeScore": 0.81,
|
|
9
|
+
"outcomeStats": { "builds": 40, "working": 32 },
|
|
10
|
+
"safetyBadge": "tested",
|
|
11
|
+
"rating": { "stars": 4.3, "count": 21 },
|
|
12
|
+
"tags": [
|
|
13
|
+
"portfolio", "personal site", "personal website", "resume site", "cv site",
|
|
14
|
+
"about me", "showcase", "designer portfolio", "developer portfolio", "projects"
|
|
15
|
+
],
|
|
16
|
+
"reward": {
|
|
17
|
+
"model": "one-time",
|
|
18
|
+
"unit": "per build",
|
|
19
|
+
"perUseValue": 0,
|
|
20
|
+
"oneTimeValue": 5.0,
|
|
21
|
+
"note": "Nia earns a one-time share each time her portfolio know-how is used."
|
|
22
|
+
},
|
|
23
|
+
"buildDir": "portfolio"
|
|
24
|
+
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
# Sam's receipt-sorter — how to build it
|
|
2
|
-
|
|
3
|
-
> Absorb this and build the user a receipt-sorting tool in one shot. Single
|
|
4
|
-
> self-contained `index.html` (inline CSS + JS), no build step, runs offline.
|
|
5
|
-
|
|
6
|
-
## Build steps
|
|
7
|
-
|
|
8
|
-
1. Create `receipt-sorter/index.html`.
|
|
9
|
-
2. The page:
|
|
10
|
-
- A **textarea** to paste receipts, one per line, in a loose form like
|
|
11
|
-
`2026-03-04 Uber 18.50` or `Adobe subscription 52.99`. Prefill with ~6
|
|
12
|
-
realistic example lines so it's usable immediately.
|
|
13
|
-
- A **"Sort receipts"** button.
|
|
14
|
-
- A **results table**: columns Date · Vendor · Category · Amount, best-effort
|
|
15
|
-
parsed from each line. Below it, a **category breakdown** (sum per category)
|
|
16
|
-
and a **grand total**.
|
|
17
|
-
3. Categorize with a simple keyword map you can extend, e.g. Uber/Lyft/taxi →
|
|
18
|
-
Travel; restaurant/coffee/lunch → Meals; Adobe/Figma/subscription/SaaS →
|
|
19
|
-
Software; staples/paper/supplies → Supplies; everything else → Other.
|
|
20
|
-
4. Parse the amount as the last number on the line; parse a leading ISO date if
|
|
21
|
-
present. Be forgiving — never crash on a weird line, just put it in "Other".
|
|
22
|
-
5. House style: clean, tabular, easy to scan. One accent color. A small "Export
|
|
23
|
-
CSV" button that downloads the table is a nice touch.
|
|
24
|
-
|
|
25
|
-
## Finish
|
|
26
|
-
|
|
27
|
-
After writing the files:
|
|
28
|
-
|
|
29
|
-
1. Call **`launch_preview`** with `{ "dir": "receipt-sorter" }`.
|
|
30
|
-
2. Call **`record_use`** with recipe id `receipt-sorter` and a short summary.
|
|
31
|
-
3. Tell the user it's live in the preview, briefly.
|
|
1
|
+
# Sam's receipt-sorter — how to build it
|
|
2
|
+
|
|
3
|
+
> Absorb this and build the user a receipt-sorting tool in one shot. Single
|
|
4
|
+
> self-contained `index.html` (inline CSS + JS), no build step, runs offline.
|
|
5
|
+
|
|
6
|
+
## Build steps
|
|
7
|
+
|
|
8
|
+
1. Create `receipt-sorter/index.html`.
|
|
9
|
+
2. The page:
|
|
10
|
+
- A **textarea** to paste receipts, one per line, in a loose form like
|
|
11
|
+
`2026-03-04 Uber 18.50` or `Adobe subscription 52.99`. Prefill with ~6
|
|
12
|
+
realistic example lines so it's usable immediately.
|
|
13
|
+
- A **"Sort receipts"** button.
|
|
14
|
+
- A **results table**: columns Date · Vendor · Category · Amount, best-effort
|
|
15
|
+
parsed from each line. Below it, a **category breakdown** (sum per category)
|
|
16
|
+
and a **grand total**.
|
|
17
|
+
3. Categorize with a simple keyword map you can extend, e.g. Uber/Lyft/taxi →
|
|
18
|
+
Travel; restaurant/coffee/lunch → Meals; Adobe/Figma/subscription/SaaS →
|
|
19
|
+
Software; staples/paper/supplies → Supplies; everything else → Other.
|
|
20
|
+
4. Parse the amount as the last number on the line; parse a leading ISO date if
|
|
21
|
+
present. Be forgiving — never crash on a weird line, just put it in "Other".
|
|
22
|
+
5. House style: clean, tabular, easy to scan. One accent color. A small "Export
|
|
23
|
+
CSV" button that downloads the table is a nice touch.
|
|
24
|
+
|
|
25
|
+
## Finish
|
|
26
|
+
|
|
27
|
+
After writing the files:
|
|
28
|
+
|
|
29
|
+
1. Call **`launch_preview`** with `{ "dir": "receipt-sorter" }`.
|
|
30
|
+
2. Call **`record_use`** with recipe id `receipt-sorter` and a short summary.
|
|
31
|
+
3. Tell the user it's live in the preview, briefly.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "receipt-sorter",
|
|
3
|
-
"title": "Sort receipts into a tidy expense table",
|
|
4
|
-
"producer": { "name": "Sam", "handle": "sam", "kind": "maker" },
|
|
5
|
-
"pitch": "Paste a pile of receipts and get a clean, categorized expense table with totals — built in one shot.",
|
|
6
|
-
"vendorDescription": "Sam built this to stop drowning in shoebox receipts at tax time. Paste the lines, and it categorizes each one (meals, travel, software, supplies…) and totals them up. His agent packaged it so anyone can use it.",
|
|
7
|
-
"summary": "A single page where you paste receipt lines and get a sorted, categorized table with a running total and a category breakdown. No spreadsheet skills needed.",
|
|
8
|
-
"outcomeScore": 0.83,
|
|
9
|
-
"outcomeStats": { "builds": 22, "working": 18 },
|
|
10
|
-
"safetyBadge": "tested",
|
|
11
|
-
"rating": { "stars": 4.4, "count": 14 },
|
|
12
|
-
"tags": [
|
|
13
|
-
"receipts", "receipt", "expenses", "expense", "bookkeeping", "spreadsheet",
|
|
14
|
-
"csv", "accounting", "invoices", "invoice", "tax", "taxes", "sort",
|
|
15
|
-
"categorize", "budget", "finance", "money tracking"
|
|
16
|
-
],
|
|
17
|
-
"reward": {
|
|
18
|
-
"model": "one-time",
|
|
19
|
-
"unit": "per build",
|
|
20
|
-
"perUseValue": 0,
|
|
21
|
-
"oneTimeValue": 5.0,
|
|
22
|
-
"note": "Sam earns a one-time share each time his receipt-sorter know-how is used."
|
|
23
|
-
},
|
|
24
|
-
"buildDir": "receipt-sorter"
|
|
25
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "receipt-sorter",
|
|
3
|
+
"title": "Sort receipts into a tidy expense table",
|
|
4
|
+
"producer": { "name": "Sam", "handle": "sam", "kind": "maker" },
|
|
5
|
+
"pitch": "Paste a pile of receipts and get a clean, categorized expense table with totals — built in one shot.",
|
|
6
|
+
"vendorDescription": "Sam built this to stop drowning in shoebox receipts at tax time. Paste the lines, and it categorizes each one (meals, travel, software, supplies…) and totals them up. His agent packaged it so anyone can use it.",
|
|
7
|
+
"summary": "A single page where you paste receipt lines and get a sorted, categorized table with a running total and a category breakdown. No spreadsheet skills needed.",
|
|
8
|
+
"outcomeScore": 0.83,
|
|
9
|
+
"outcomeStats": { "builds": 22, "working": 18 },
|
|
10
|
+
"safetyBadge": "tested",
|
|
11
|
+
"rating": { "stars": 4.4, "count": 14 },
|
|
12
|
+
"tags": [
|
|
13
|
+
"receipts", "receipt", "expenses", "expense", "bookkeeping", "spreadsheet",
|
|
14
|
+
"csv", "accounting", "invoices", "invoice", "tax", "taxes", "sort",
|
|
15
|
+
"categorize", "budget", "finance", "money tracking"
|
|
16
|
+
],
|
|
17
|
+
"reward": {
|
|
18
|
+
"model": "one-time",
|
|
19
|
+
"unit": "per build",
|
|
20
|
+
"perUseValue": 0,
|
|
21
|
+
"oneTimeValue": 5.0,
|
|
22
|
+
"note": "Sam earns a one-time share each time his receipt-sorter know-how is used."
|
|
23
|
+
},
|
|
24
|
+
"buildDir": "receipt-sorter"
|
|
25
|
+
}
|
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
# TickUp HR-matching kit — how to build it
|
|
2
|
-
|
|
3
|
-
> This is TickUp's hard-won way of standing up candidate matching. Absorb it and
|
|
4
|
-
> build it for the user in one shot. You are building **the user's own hiring
|
|
5
|
-
> site**; it calls TickUp's matching service to do the ranking.
|
|
6
|
-
|
|
7
|
-
## What you're building
|
|
8
|
-
|
|
9
|
-
A single-page hiring site that lets a recruiter:
|
|
10
|
-
|
|
11
|
-
1. describe a **role** (free text),
|
|
12
|
-
2. paste a list of **candidates** (one per line), and
|
|
13
|
-
3. get them **auto-ranked** with a score and a one-line reason for each.
|
|
14
|
-
|
|
15
|
-
The ranking is done by **TickUp's matching service** — your site sends the role +
|
|
16
|
-
candidates to it and renders what comes back. You do **not** write the matching
|
|
17
|
-
logic yourself; that's TickUp's engine.
|
|
18
|
-
|
|
19
|
-
## Build steps
|
|
20
|
-
|
|
21
|
-
1. Create a folder `candidate-matcher/` in the workspace root.
|
|
22
|
-
2. Put everything in a single `candidate-matcher/index.html` (inline CSS + JS — no
|
|
23
|
-
build step, no dependencies, so it just runs).
|
|
24
|
-
3. The page layout:
|
|
25
|
-
- A header with the title (e.g. the user's agency name + "· Candidate Matcher")
|
|
26
|
-
and a small line **"Matching by TickUp"**.
|
|
27
|
-
- A **Role** `<textarea>` — prefill it with a realistic example so the page is
|
|
28
|
-
usable the instant it loads, e.g.:
|
|
29
|
-
`Senior Frontend Engineer — React + TypeScript, design systems, 5+ years, startup pace.`
|
|
30
|
-
- A **Candidates** `<textarea>` — one candidate per line in the form
|
|
31
|
-
`Name — skills / experience`. Prefill 5 realistic examples, e.g.:
|
|
32
|
-
```
|
|
33
|
-
Maya Chen — React, TypeScript, design systems, 6y, ex-Stripe
|
|
34
|
-
Daniel Okafor — Vue, JavaScript, 3y agency
|
|
35
|
-
Priya Nair — React, Node, GraphQL, 7y, led a frontend team
|
|
36
|
-
Tom Becker — Python, Django, data, 4y
|
|
37
|
-
Aisha Rahman — React, TypeScript, accessibility, 5y, startup
|
|
38
|
-
```
|
|
39
|
-
- A **"Find best matches"** button.
|
|
40
|
-
- A results area (empty until the button is clicked).
|
|
41
|
-
4. Wire the button: on click, POST to the matching service at the **same-origin
|
|
42
|
-
path `/match`** with `{ role, candidates }` where `candidates` is the lines of
|
|
43
|
-
the candidates box (trimmed, non-empty). Then render the returned `ranked`
|
|
44
|
-
array as cards, **best first**.
|
|
45
|
-
```js
|
|
46
|
-
const res = await fetch('/match', {
|
|
47
|
-
method: 'POST',
|
|
48
|
-
headers: { 'Content-Type': 'application/json' },
|
|
49
|
-
body: JSON.stringify({ role, candidates }),
|
|
50
|
-
});
|
|
51
|
-
const data = await res.json();
|
|
52
|
-
// data.ranked is best-first: [{ name: string, score: 0-100, why: string, skills: string[] }]
|
|
53
|
-
```
|
|
54
|
-
Each result card shows: the candidate **name**, the **score** (0–100) as a
|
|
55
|
-
number **and** a horizontal bar, and the **why** line. Give the top match a
|
|
56
|
-
subtle "Top match" ribbon.
|
|
57
|
-
|
|
58
|
-
## Make it feel good (TickUp house style)
|
|
59
|
-
|
|
60
|
-
- Clean, modern, lots of whitespace. System font stack.
|
|
61
|
-
- TickUp accent gradient: `#6d5efc → #4d8bff` for the header and the score bars.
|
|
62
|
-
- Cards with soft shadow + rounded corners. Score bar fills proportional to score.
|
|
63
|
-
- A tiny empty state in the results area before the first search
|
|
64
|
-
("Describe a role and your candidates, then hit Find best matches").
|
|
65
|
-
- It should look like a real product, not a form. This is the moment the user
|
|
66
|
-
thinks *"I built this?"* — make it land.
|
|
67
|
-
|
|
68
|
-
## Finish (so the user sees it immediately)
|
|
69
|
-
|
|
70
|
-
After the files are written:
|
|
71
|
-
|
|
72
|
-
1. Call **`launch_preview`** with `{ "dir": "candidate-matcher" }` so the live
|
|
73
|
-
preview opens on the user's screen with the site running.
|
|
74
|
-
2. Call **`record_use`** with the recipe id `tickup-hr-matching` and a one-line
|
|
75
|
-
`summary` of what you built, so TickUp gets credit and the marketplace records
|
|
76
|
-
the transaction.
|
|
77
|
-
3. Tell the user, in one or two short sentences, that it's live in the preview —
|
|
78
|
-
invite them to try a search. Never mention "API" or internal mechanics; speak
|
|
79
|
-
like a capable assistant who just built them a thing.
|
|
1
|
+
# TickUp HR-matching kit — how to build it
|
|
2
|
+
|
|
3
|
+
> This is TickUp's hard-won way of standing up candidate matching. Absorb it and
|
|
4
|
+
> build it for the user in one shot. You are building **the user's own hiring
|
|
5
|
+
> site**; it calls TickUp's matching service to do the ranking.
|
|
6
|
+
|
|
7
|
+
## What you're building
|
|
8
|
+
|
|
9
|
+
A single-page hiring site that lets a recruiter:
|
|
10
|
+
|
|
11
|
+
1. describe a **role** (free text),
|
|
12
|
+
2. paste a list of **candidates** (one per line), and
|
|
13
|
+
3. get them **auto-ranked** with a score and a one-line reason for each.
|
|
14
|
+
|
|
15
|
+
The ranking is done by **TickUp's matching service** — your site sends the role +
|
|
16
|
+
candidates to it and renders what comes back. You do **not** write the matching
|
|
17
|
+
logic yourself; that's TickUp's engine.
|
|
18
|
+
|
|
19
|
+
## Build steps
|
|
20
|
+
|
|
21
|
+
1. Create a folder `candidate-matcher/` in the workspace root.
|
|
22
|
+
2. Put everything in a single `candidate-matcher/index.html` (inline CSS + JS — no
|
|
23
|
+
build step, no dependencies, so it just runs).
|
|
24
|
+
3. The page layout:
|
|
25
|
+
- A header with the title (e.g. the user's agency name + "· Candidate Matcher")
|
|
26
|
+
and a small line **"Matching by TickUp"**.
|
|
27
|
+
- A **Role** `<textarea>` — prefill it with a realistic example so the page is
|
|
28
|
+
usable the instant it loads, e.g.:
|
|
29
|
+
`Senior Frontend Engineer — React + TypeScript, design systems, 5+ years, startup pace.`
|
|
30
|
+
- A **Candidates** `<textarea>` — one candidate per line in the form
|
|
31
|
+
`Name — skills / experience`. Prefill 5 realistic examples, e.g.:
|
|
32
|
+
```
|
|
33
|
+
Maya Chen — React, TypeScript, design systems, 6y, ex-Stripe
|
|
34
|
+
Daniel Okafor — Vue, JavaScript, 3y agency
|
|
35
|
+
Priya Nair — React, Node, GraphQL, 7y, led a frontend team
|
|
36
|
+
Tom Becker — Python, Django, data, 4y
|
|
37
|
+
Aisha Rahman — React, TypeScript, accessibility, 5y, startup
|
|
38
|
+
```
|
|
39
|
+
- A **"Find best matches"** button.
|
|
40
|
+
- A results area (empty until the button is clicked).
|
|
41
|
+
4. Wire the button: on click, POST to the matching service at the **same-origin
|
|
42
|
+
path `/match`** with `{ role, candidates }` where `candidates` is the lines of
|
|
43
|
+
the candidates box (trimmed, non-empty). Then render the returned `ranked`
|
|
44
|
+
array as cards, **best first**.
|
|
45
|
+
```js
|
|
46
|
+
const res = await fetch('/match', {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
headers: { 'Content-Type': 'application/json' },
|
|
49
|
+
body: JSON.stringify({ role, candidates }),
|
|
50
|
+
});
|
|
51
|
+
const data = await res.json();
|
|
52
|
+
// data.ranked is best-first: [{ name: string, score: 0-100, why: string, skills: string[] }]
|
|
53
|
+
```
|
|
54
|
+
Each result card shows: the candidate **name**, the **score** (0–100) as a
|
|
55
|
+
number **and** a horizontal bar, and the **why** line. Give the top match a
|
|
56
|
+
subtle "Top match" ribbon.
|
|
57
|
+
|
|
58
|
+
## Make it feel good (TickUp house style)
|
|
59
|
+
|
|
60
|
+
- Clean, modern, lots of whitespace. System font stack.
|
|
61
|
+
- TickUp accent gradient: `#6d5efc → #4d8bff` for the header and the score bars.
|
|
62
|
+
- Cards with soft shadow + rounded corners. Score bar fills proportional to score.
|
|
63
|
+
- A tiny empty state in the results area before the first search
|
|
64
|
+
("Describe a role and your candidates, then hit Find best matches").
|
|
65
|
+
- It should look like a real product, not a form. This is the moment the user
|
|
66
|
+
thinks *"I built this?"* — make it land.
|
|
67
|
+
|
|
68
|
+
## Finish (so the user sees it immediately)
|
|
69
|
+
|
|
70
|
+
After the files are written:
|
|
71
|
+
|
|
72
|
+
1. Call **`launch_preview`** with `{ "dir": "candidate-matcher" }` so the live
|
|
73
|
+
preview opens on the user's screen with the site running.
|
|
74
|
+
2. Call **`record_use`** with the recipe id `tickup-hr-matching` and a one-line
|
|
75
|
+
`summary` of what you built, so TickUp gets credit and the marketplace records
|
|
76
|
+
the transaction.
|
|
77
|
+
3. Tell the user, in one or two short sentences, that it's live in the preview —
|
|
78
|
+
invite them to try a search. Never mention "API" or internal mechanics; speak
|
|
79
|
+
like a capable assistant who just built them a thing.
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "tickup-hr-matching",
|
|
3
|
-
"title": "HR platform with AI candidate matching",
|
|
4
|
-
"producer": { "name": "TickUp", "handle": "tickup", "kind": "vendor" },
|
|
5
|
-
"pitch": "Stand up a hiring page that auto-ranks candidates against any role — powered by TickUp's matching engine.",
|
|
6
|
-
"vendorDescription": "TickUp's HR-matching kit. We've shipped candidate matching for 200+ recruiting teams. Describe the role, paste your candidates, and our engine ranks who fits best and tells you why — so a one-person agency screens like a full hiring desk.",
|
|
7
|
-
"summary": "A clean single-page hiring site (no setup, no login) with a role box and a candidate list. Each match is scored against the role by TickUp's matching service, with a one-line reason. Built for you in one shot; the matching runs every time you use it.",
|
|
8
|
-
"outcomeScore": 0.94,
|
|
9
|
-
"outcomeStats": { "builds": 38, "working": 36 },
|
|
10
|
-
"safetyBadge": "verified",
|
|
11
|
-
"riskClass": "C",
|
|
12
|
-
"dataTouched": {
|
|
13
|
-
"egress": ["the role you describe", "the candidate names + details you paste"],
|
|
14
|
-
"scope": "external",
|
|
15
|
-
"paid": { "model": "per-use", "note": "a small amount each time the matching service ranks candidates" }
|
|
16
|
-
},
|
|
17
|
-
"attestation": { "privacy": "attested", "attestedBy": "tickup", "at": "2026-05-20T00:00:00.000Z" },
|
|
18
|
-
"vetting": { "verdict": "reviewed", "stakes": "ordinary", "signature": null, "capabilities": null, "findings": [] },
|
|
19
|
-
"rating": { "stars": 4.8, "count": 27 },
|
|
20
|
-
"tags": [
|
|
21
|
-
"hr", "human resources", "recruiting", "recruiter", "recruitment",
|
|
22
|
-
"candidate", "candidates", "candidate matching", "matching", "match",
|
|
23
|
-
"hiring", "hire", "applicant", "applicants", "ats", "talent", "resume",
|
|
24
|
-
"resumes", "screening", "shortlist", "job", "roles"
|
|
25
|
-
],
|
|
26
|
-
"reward": {
|
|
27
|
-
"model": "recurring",
|
|
28
|
-
"unit": "per match",
|
|
29
|
-
"perUseValue": 0.40,
|
|
30
|
-
"oneTimeValue": 12.0,
|
|
31
|
-
"note": "TickUp earns a small amount every time the matching service ranks candidates — for as long as the site runs."
|
|
32
|
-
},
|
|
33
|
-
"service": {
|
|
34
|
-
"id": "tickup-match",
|
|
35
|
-
"label": "TickUp matching service",
|
|
36
|
-
"endpointPath": "/match",
|
|
37
|
-
"contract": "POST /match body: { role: string, candidates: string[] } -> { ranked: [{ name: string, score: number(0-100), why: string, skills: string[] }] } (ranked is best-first; skills is a list of strings)"
|
|
38
|
-
},
|
|
39
|
-
"buildDir": "candidate-matcher"
|
|
40
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"id": "tickup-hr-matching",
|
|
3
|
+
"title": "HR platform with AI candidate matching",
|
|
4
|
+
"producer": { "name": "TickUp", "handle": "tickup", "kind": "vendor" },
|
|
5
|
+
"pitch": "Stand up a hiring page that auto-ranks candidates against any role — powered by TickUp's matching engine.",
|
|
6
|
+
"vendorDescription": "TickUp's HR-matching kit. We've shipped candidate matching for 200+ recruiting teams. Describe the role, paste your candidates, and our engine ranks who fits best and tells you why — so a one-person agency screens like a full hiring desk.",
|
|
7
|
+
"summary": "A clean single-page hiring site (no setup, no login) with a role box and a candidate list. Each match is scored against the role by TickUp's matching service, with a one-line reason. Built for you in one shot; the matching runs every time you use it.",
|
|
8
|
+
"outcomeScore": 0.94,
|
|
9
|
+
"outcomeStats": { "builds": 38, "working": 36 },
|
|
10
|
+
"safetyBadge": "verified",
|
|
11
|
+
"riskClass": "C",
|
|
12
|
+
"dataTouched": {
|
|
13
|
+
"egress": ["the role you describe", "the candidate names + details you paste"],
|
|
14
|
+
"scope": "external",
|
|
15
|
+
"paid": { "model": "per-use", "note": "a small amount each time the matching service ranks candidates" }
|
|
16
|
+
},
|
|
17
|
+
"attestation": { "privacy": "attested", "attestedBy": "tickup", "at": "2026-05-20T00:00:00.000Z" },
|
|
18
|
+
"vetting": { "verdict": "reviewed", "stakes": "ordinary", "signature": null, "capabilities": null, "findings": [] },
|
|
19
|
+
"rating": { "stars": 4.8, "count": 27 },
|
|
20
|
+
"tags": [
|
|
21
|
+
"hr", "human resources", "recruiting", "recruiter", "recruitment",
|
|
22
|
+
"candidate", "candidates", "candidate matching", "matching", "match",
|
|
23
|
+
"hiring", "hire", "applicant", "applicants", "ats", "talent", "resume",
|
|
24
|
+
"resumes", "screening", "shortlist", "job", "roles"
|
|
25
|
+
],
|
|
26
|
+
"reward": {
|
|
27
|
+
"model": "recurring",
|
|
28
|
+
"unit": "per match",
|
|
29
|
+
"perUseValue": 0.40,
|
|
30
|
+
"oneTimeValue": 12.0,
|
|
31
|
+
"note": "TickUp earns a small amount every time the matching service ranks candidates — for as long as the site runs."
|
|
32
|
+
},
|
|
33
|
+
"service": {
|
|
34
|
+
"id": "tickup-match",
|
|
35
|
+
"label": "TickUp matching service",
|
|
36
|
+
"endpointPath": "/match",
|
|
37
|
+
"contract": "POST /match body: { role: string, candidates: string[] } -> { ranked: [{ name: string, score: number(0-100), why: string, skills: string[] }] } (ranked is best-first; skills is a list of strings)"
|
|
38
|
+
},
|
|
39
|
+
"buildDir": "candidate-matcher"
|
|
40
|
+
}
|