cue-ai 0.9.1 → 0.9.2
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/CHANGELOG.md +40 -0
- package/README.md +38 -0
- package/bin/cue-review-progress +107 -0
- package/bin/cue-review-watch +98 -0
- package/package.json +2 -1
- package/profiles/career/profile.yaml +13 -2
- package/profiles/core/profile.yaml +8 -0
- package/profiles/eu-tender-research/README.md +48 -0
- package/profiles/eu-tender-research/logo.png +0 -0
- package/profiles/eu-tender-research/profile.yaml +108 -0
- package/profiles/gstack/profile.yaml +2 -0
- package/profiles/skill-writer/profile.yaml +4 -0
- package/profiles/x-growth-bot/profile.yaml +0 -2
- package/resources/icons/generate-icons.py +128 -2
- package/resources/mcps/configs/claude.sanitized.json +17 -0
- package/resources/skills/skills/career/resume-version-manager/SKILL.md +351 -0
- package/resources/skills/skills/career/salary-negotiation-prep/SKILL.md +378 -0
- package/resources/skills/skills/eu-funding/grant-outreach/SKILL.md +70 -0
- package/resources/skills/skills/eu-funding/hu-grant-finder/SKILL.md +114 -0
- package/resources/skills/skills/eu-funding/hu-grant-finder/evals.md +26 -0
- package/resources/skills/skills/eu-funding/ted-tender-search/SKILL.md +80 -0
- package/resources/skills/skills/eu-funding/ted-tender-search/evals.md +26 -0
- package/resources/skills/skills/eu-funding/ted-tender-search/scripts/ted-search.sh +46 -0
- package/resources/skills/skills/github/gx-agents/SKILL.md +96 -0
- package/resources/skills/skills/meta/focus/SKILL.md +62 -0
- package/resources/skills/skills/tools/portless/SKILL.md +186 -0
- package/src/lib/analytics.ts +13 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Activation evals — ted-tender-search
|
|
2
|
+
|
|
3
|
+
Run by judging each query against the `description:` only: does it fire?
|
|
4
|
+
Pass bar: >=90% of TRIGGER fire, <=10% of NO-TRIGGER false-fire.
|
|
5
|
+
|
|
6
|
+
## TRIGGER (must fire)
|
|
7
|
+
|
|
8
|
+
- find EU tenders for IT companies
|
|
9
|
+
- search TED for Hungarian procurement
|
|
10
|
+
- közbeszerzés keresés szoftverre
|
|
11
|
+
- what public procurement notices are open in Slovakia?
|
|
12
|
+
- find tenders by CPV code 72000000
|
|
13
|
+
- are there open EU contracts my company can bid on?
|
|
14
|
+
- TED search for AI tenders
|
|
15
|
+
- list active procurement notices from Hungarian buyers
|
|
16
|
+
|
|
17
|
+
## NO-TRIGGER (must NOT fire — route elsewhere)
|
|
18
|
+
|
|
19
|
+
- find grants for my startup → hu-grant-finder
|
|
20
|
+
- what GINOP can I apply for? → hu-grant-finder
|
|
21
|
+
- find me a venture capital investor → hu-grant-finder
|
|
22
|
+
- write me a bid proposal → content/article-writer
|
|
23
|
+
- scrape this website → gstack/scrape
|
|
24
|
+
- how do I register a Kft? → none
|
|
25
|
+
|
|
26
|
+
Last run: 8/8 trigger, 0/6 false-fire = 100%.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ted-search.sh — one-command EU tender search via the official free TED API.
|
|
3
|
+
#
|
|
4
|
+
# Usage: ted-search.sh <BUYER_COUNTRY> [CPV_CODES] [SCOPE] [LIMIT]
|
|
5
|
+
# BUYER_COUNTRY ISO 3-letter buyer country, e.g. HUN, SVK (required)
|
|
6
|
+
# CPV_CODES space-separated, default "72000000 48000000 73000000" (IT/sw/R&D)
|
|
7
|
+
# SCOPE ACTIVE (default, open to bid) or ALL (historical)
|
|
8
|
+
# LIMIT page size, default 50
|
|
9
|
+
#
|
|
10
|
+
# Examples:
|
|
11
|
+
# ted-search.sh HUN
|
|
12
|
+
# ted-search.sh SVK "72000000 48000000" ACTIVE 60
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
COUNTRY="${1:?usage: ted-search.sh <BUYER_COUNTRY> [CPV] [SCOPE] [LIMIT]}"
|
|
16
|
+
CPV="${2:-72000000 48000000 73000000}"
|
|
17
|
+
SCOPE="${3:-ACTIVE}"
|
|
18
|
+
LIMIT="${4:-50}"
|
|
19
|
+
|
|
20
|
+
QUERY="classification-cpv IN (${CPV}) AND organisation-country-buyer IN (${COUNTRY})"
|
|
21
|
+
|
|
22
|
+
BODY=$(python3 -c 'import json,sys
|
|
23
|
+
print(json.dumps({"query":sys.argv[1],
|
|
24
|
+
"fields":["publication-number","notice-title","buyer-name","classification-cpv","notice-type"],
|
|
25
|
+
"limit":int(sys.argv[2]),"scope":sys.argv[3]}))' "$QUERY" "$LIMIT" "$SCOPE")
|
|
26
|
+
|
|
27
|
+
curl -sS -m 60 -X POST "https://api.ted.europa.eu/v3/notices/search" \
|
|
28
|
+
-H "Content-Type: application/json" -d "$BODY" \
|
|
29
|
+
| python3 -c '
|
|
30
|
+
import json,sys
|
|
31
|
+
d=json.load(sys.stdin)
|
|
32
|
+
def pick(f):
|
|
33
|
+
if not isinstance(f,dict): return f or ""
|
|
34
|
+
for l in ("eng","hun"):
|
|
35
|
+
if f.get(l): v=f[l]; return v[0] if isinstance(v,list) else v
|
|
36
|
+
return next((v[0] if isinstance(v,list) else v for v in f.values()), "")
|
|
37
|
+
ns=sorted(d.get("notices",[]), key=lambda n:-int(n["publication-number"].split("-")[1]))
|
|
38
|
+
total=d.get("totalNoticeCount",0); shown=min(15,len(ns))
|
|
39
|
+
print("TOTAL match: %d (showing newest %d)\n" % (total, shown))
|
|
40
|
+
for n in ns[:15]:
|
|
41
|
+
p=n["publication-number"]
|
|
42
|
+
title=pick(n.get("notice-title",""))[:70]
|
|
43
|
+
buyer=pick(n.get("buyer-name",""))[:55]
|
|
44
|
+
print("%s %s" % (p, title))
|
|
45
|
+
print(" %s https://ted.europa.eu/en/notice/%s" % (buyer, p))
|
|
46
|
+
'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gx-agents
|
|
3
|
+
category: github
|
|
4
|
+
triggers:
|
|
5
|
+
- who's working on what
|
|
6
|
+
- show all agents
|
|
7
|
+
- is anyone else editing
|
|
8
|
+
- agent collision
|
|
9
|
+
- which PR is each agent shipping
|
|
10
|
+
- who owns this file
|
|
11
|
+
- agent radar
|
|
12
|
+
description: >-
|
|
13
|
+
Use when several agents work in parallel and you need to see who is on which branch, worktree, or PR, or to avoid editing a file another agent already owns. Triggers: "who's working on what", "show all agents", "is anyone else editing X", "agent collision", "which PR is each agent shipping", "who owns this file", "agent radar". Drives the gx mcp tools (list_agents, who_owns, my_context) or the `gx mcp list-agents` / `gx mcp who-owns` CLI to read every agent's branch, worktree, dirty files, locks, and PR. Read-only. NOT for repo-safety repair (use gitguardex).
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# gx agents: see every agent, avoid collisions
|
|
17
|
+
|
|
18
|
+
Multiple agents (Claude, Codex) editing nearby repos step on each other: two
|
|
19
|
+
edit the same file, or one edits the protected primary checkout and a later
|
|
20
|
+
branch switch auto-stashes the work. `gx mcp` exposes the live picture
|
|
21
|
+
gitguardex already tracks. Read it BEFORE you edit, not after the conflict.
|
|
22
|
+
|
|
23
|
+
## Prereq
|
|
24
|
+
|
|
25
|
+
The server ships with gitguardex (`gx mcp serve`). Register it once so any
|
|
26
|
+
session can call the tools:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
claude mcp add gx -s user -- gx mcp serve
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If it is not registered, use the CLI fallback below: same data, no MCP client.
|
|
33
|
+
|
|
34
|
+
## Before you edit a shared file: check ownership
|
|
35
|
+
|
|
36
|
+
Ask who holds the lock before touching a path. If another branch owns it,
|
|
37
|
+
coordinate or pick a different file instead of overwriting.
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
gx mcp who-owns path/to/file.ts
|
|
41
|
+
# -> "locked by <agent> (branch agent/<name>/...)" or "unclaimed"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
MCP tool form: call `who_owns` with `{ "file": "path/to/file.ts" }`.
|
|
45
|
+
|
|
46
|
+
## See the whole field
|
|
47
|
+
|
|
48
|
+
List every active agent lane across all your repos: branch, worktree, the
|
|
49
|
+
files each is editing right now (`dirty`), held locks, last commit, and PR.
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
gx mcp list-agents # human view
|
|
53
|
+
gx mcp list-agents --json # machine view (pass --no-prs to skip gh/network)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
MCP tool form: call `list_agents` (pass `{ "include_prs": true }` when you need
|
|
57
|
+
PR state, which is off by default to keep the cross-repo scan fast).
|
|
58
|
+
|
|
59
|
+
Watch for `⚠ ON PRIMARY CHECKOUT`: that lane is editing the protected base, not
|
|
60
|
+
an isolated worktree, so its work can be auto-stashed. Tell it to move with
|
|
61
|
+
`gx branch start`.
|
|
62
|
+
|
|
63
|
+
## Know your own lane
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
# MCP tool: my_context -> repo, branch, worktree, onPrimaryCheckout, dirty, locks, PR
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Example
|
|
70
|
+
|
|
71
|
+
User: "before I touch the checkout component, is anyone else on it?"
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
gx mcp who-owns apps/storefront/src/checkout-delivery-step.tsx
|
|
75
|
+
# -> locked by codex (branch agent/codex/checkout-copy-fix)
|
|
76
|
+
gx mcp list-agents --no-prs | grep -A3 checkout
|
|
77
|
+
# -> codex agent/codex/checkout-copy-fix editing 4 file(s)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Conclusion: codex owns it and is editing it right now. Pick different work or
|
|
81
|
+
post a handoff instead of overwriting.
|
|
82
|
+
|
|
83
|
+
## Rules
|
|
84
|
+
|
|
85
|
+
- **Read-only.** These tools never change a repo. To actually reserve a file,
|
|
86
|
+
use `gx locks claim --branch "<branch>" <file>`; to coordinate live tasks,
|
|
87
|
+
use Colony. `gx mcp` only shows the state.
|
|
88
|
+
- **Locks lag edits.** File locks are written at commit time, so `who_owns` can
|
|
89
|
+
return `unclaimed` while another lane is mid-edit. Cross-check the lane's
|
|
90
|
+
`dirty` files in `list_agents` for in-progress work.
|
|
91
|
+
- **One agent per file.** If `who_owns` (or another lane's `dirty`) shows the
|
|
92
|
+
file is taken, do not overwrite. Post a handoff or pick different work.
|
|
93
|
+
- **Act on the primary-checkout warning.** A lane on the primary checkout is the
|
|
94
|
+
collision waiting to happen; route it to `gx branch start` first.
|
|
95
|
+
- **This is not gitguardex repair.** For broken repo safety (dirty worktree,
|
|
96
|
+
stuck finish, `gx doctor`) use the `gitguardex` skill instead.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: focus
|
|
3
|
+
description: 'Use when user says "focus", "which skill", "what skill should I use", "route this", or faces a task in a profile with many loaded skills. Picks the best-fit loaded skill to invoke, fast.'
|
|
4
|
+
tags: [meta, routing, skills, focus]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Focus
|
|
8
|
+
|
|
9
|
+
Pick the right *loaded* skill for the task at hand. When a profile carries dozens of
|
|
10
|
+
skills, the cost is decision latency, not capability. Focus narrows the loaded set to the
|
|
11
|
+
one skill that fires, so you invoke it instead of freestyling.
|
|
12
|
+
|
|
13
|
+
Scope: skills already in the active profile. For a skill that is **not** loaded, use
|
|
14
|
+
[[smart-loader]] (it reads from disk). For catalog lookup or dedup before writing a new
|
|
15
|
+
skill, use [[skill-suggestion]].
|
|
16
|
+
|
|
17
|
+
## Steps
|
|
18
|
+
|
|
19
|
+
1. List what is loaded in the active profile:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cue skills list
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
2. Narrow by intent (fuzzy match across the set):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cue skills search "<task keywords>"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
3. Confirm a candidate by the prompts that historically fired it:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cue skills triggers <skill-id>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
4. Invoke the top match via the Skill tool. If 2+ fit, name them and pick the most
|
|
38
|
+
specific. If none fits the loaded set, hand off to [[smart-loader]] or say so plainly.
|
|
39
|
+
|
|
40
|
+
## How to match
|
|
41
|
+
|
|
42
|
+
- Read each candidate's `description:` trigger phrases against the task intent; the most
|
|
43
|
+
specific wins. A skill that names the exact tool or platform beats a generic one.
|
|
44
|
+
- One skill, one job: route to the single best fit, do not chain three skills for one task.
|
|
45
|
+
- Prefer a loaded skill over freestyling. Even a 70% fit usually beats raw improvisation,
|
|
46
|
+
because the skill carries the verified recipe.
|
|
47
|
+
|
|
48
|
+
## Rules
|
|
49
|
+
|
|
50
|
+
- Only route to skills in the active profile (`cue skills list`). For unloaded skills use
|
|
51
|
+
[[smart-loader]]; this skill never loads from disk.
|
|
52
|
+
- Name the match and the reason in one line before invoking, so the choice is auditable.
|
|
53
|
+
- If nothing fits, say so and offer [[smart-loader]] or a new skill. Do not force a bad match.
|
|
54
|
+
- Recommend only what the task needs: one skill if one fits.
|
|
55
|
+
|
|
56
|
+
## Example
|
|
57
|
+
|
|
58
|
+
User: "focus, I need to find EU tenders."
|
|
59
|
+
|
|
60
|
+
Run `cue skills list` and `cue skills search "tender"`, see `eu-funding/ted-tender-search`
|
|
61
|
+
match the intent and tool exactly, and invoke it. If the profile had no tender skill, hand
|
|
62
|
+
off to [[smart-loader]] to find one on disk.
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: portless
|
|
3
|
+
description: Named .localhost HTTPS URLs for local dev instead of port numbers. Use when the user says "portless", "https on localhost", "named dev URL", "stop using port 3000", or runs multiple dev servers (Next.js, Vite, Medusa) that collide on ports. Prefer it for Medusa shop local dev.
|
|
4
|
+
allowed-tools: Bash(portless:*), Bash(npm:*)
|
|
5
|
+
category: tools
|
|
6
|
+
tags: [tools, local-dev, https, proxy, dev-server, medusa, monorepo]
|
|
7
|
+
requires_mcps: []
|
|
8
|
+
metadata:
|
|
9
|
+
version: 1.0.0
|
|
10
|
+
homepage: https://github.com/vercel-labs/portless
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# portless: named .localhost URLs for local dev
|
|
14
|
+
|
|
15
|
+
Run dev servers behind stable `https://<name>.localhost` URLs instead of memorizing port numbers. portless starts a local HTTPS proxy, assigns each app an ephemeral port via `PORT`, and routes a clean URL to it. HTTP/2 + a trusted local CA come on by default, so no browser warnings and no port collisions when several servers run at once.
|
|
16
|
+
|
|
17
|
+
Pre-1.0 (current 0.13.x): the state-dir format can change between releases, so re-run `portless trust` after upgrades if certs stop working.
|
|
18
|
+
|
|
19
|
+
## When to activate
|
|
20
|
+
|
|
21
|
+
- User wants `https://myapp.localhost` instead of `http://localhost:3000`.
|
|
22
|
+
- Two or more dev servers fight over ports (admin + storefront, web + api).
|
|
23
|
+
- A Medusa shop needs local URLs for both the backend and the storefront.
|
|
24
|
+
- User asks for HTTPS/HTTP-2 on localhost without manual mkcert setup.
|
|
25
|
+
- A monorepo (pnpm/turbo) needs one URL per workspace package.
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
Install once, globally (recommended so every project shares one proxy + CA):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install -g portless
|
|
33
|
+
portless --version # -> portless 0.13.x
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
First run generates a local CA, trusts it, and binds port 443 (auto-elevates with `sudo` on macOS/Linux). To skip HTTPS use `--no-tls`.
|
|
37
|
+
|
|
38
|
+
## Step 1: run a single app
|
|
39
|
+
|
|
40
|
+
Infer the name from `package.json`/git root and run the `dev` script through the proxy:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
portless run next dev
|
|
44
|
+
# -> https://myapp.localhost
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or name it explicitly:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
portless myapp next dev
|
|
51
|
+
# -> https://myapp.localhost
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Bare `portless` (no args) runs the `dev` script and infers the name:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
portless # -> runs "dev", https://<project>.localhost
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Step 2: wire it into package.json
|
|
61
|
+
|
|
62
|
+
Put the proxy in the script once so it works for everyone:
|
|
63
|
+
|
|
64
|
+
```jsonc
|
|
65
|
+
{ "scripts": { "dev": "portless run next dev" } }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
With a `portless.json` you can keep the script clean and run `portless` to route it:
|
|
69
|
+
|
|
70
|
+
```jsonc
|
|
71
|
+
// portless.json
|
|
72
|
+
{ "name": "myapp" }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
portless # runs "dev", https://myapp.localhost
|
|
77
|
+
PORTLESS=0 pnpm dev # bypass the proxy, use the default port
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Step 3: subdomains and monorepos
|
|
81
|
+
|
|
82
|
+
Organize services under subdomains:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
portless api.myapp pnpm start # -> https://api.myapp.localhost
|
|
86
|
+
portless docs.myapp next dev # -> https://docs.myapp.localhost
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
One `portless.json` at the repo root covers every workspace package (pnpm/npm/yarn/bun). The `apps` map is only for name overrides:
|
|
90
|
+
|
|
91
|
+
```jsonc
|
|
92
|
+
{
|
|
93
|
+
"apps": {
|
|
94
|
+
"apps/web": { "name": "myapp" },
|
|
95
|
+
"apps/api": { "name": "api.myapp" }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
portless # from repo root: start every package with a "dev" script
|
|
102
|
+
cd apps/web && portless # start just one
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Step 4: Medusa shop local dev (preferred)
|
|
106
|
+
|
|
107
|
+
For `medusa-shops/<shop>`, route both halves through portless so admin and storefront stop colliding on ports:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# backend (Medusa serves admin on the injected PORT)
|
|
111
|
+
portless admin.myshop medusa develop # -> https://admin.myshop.localhost
|
|
112
|
+
|
|
113
|
+
# storefront
|
|
114
|
+
portless myshop pnpm dev # -> https://myshop.localhost
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Next.js storefronts must allow the dev origin:
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
// next.config.js
|
|
121
|
+
module.exports = { allowedDevOrigins: ["myshop.localhost", "*.myshop.localhost"] }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
If the storefront proxies `/api` to the backend, set `changeOrigin: true` or portless returns `508 Loop Detected` (it rewrites the `Host` header back to the proxy). See Rules.
|
|
125
|
+
|
|
126
|
+
Related: the `medusa-local-dev` skill runs many shops on a fixed-port registry (`.dev-ports.yaml`) with the `medusa-dev` helper for lifecycle (start/stop/tail). portless is the preferred URL layer on top: keep `medusa-dev` for process management, or pass `portless --app-port <registry-port>` to give each shop a clean `https://<shop>.localhost` instead of a bare port.
|
|
127
|
+
|
|
128
|
+
## Step 5: git worktrees
|
|
129
|
+
|
|
130
|
+
`portless run` auto-detects linked worktrees and prepends the branch as a subdomain, so each worktree gets its own URL with zero config:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# main checkout
|
|
134
|
+
portless run next dev # -> https://myapp.localhost
|
|
135
|
+
# worktree on branch "fix-ui"
|
|
136
|
+
portless run next dev # -> https://fix-ui.myapp.localhost
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Commands reference
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
portless list # show active routes (local + tailnet)
|
|
143
|
+
portless alias <name> <port> # static route, e.g. point a name at a Docker port
|
|
144
|
+
portless trust # (re)add the local CA to the system trust store
|
|
145
|
+
portless prune # kill orphaned dev servers from crashed sessions
|
|
146
|
+
portless hosts sync # add routes to /etc/hosts (fixes Safari)
|
|
147
|
+
portless clean # remove state, CA trust entry, and hosts block
|
|
148
|
+
|
|
149
|
+
portless proxy start # start the HTTPS proxy (port 443, daemon)
|
|
150
|
+
portless proxy start --no-tls # plain HTTP on port 80
|
|
151
|
+
portless proxy start -p 1355 # custom port, no sudo
|
|
152
|
+
portless proxy stop
|
|
153
|
+
|
|
154
|
+
portless service install # start the proxy at OS startup (survives reboot)
|
|
155
|
+
portless service status
|
|
156
|
+
portless service uninstall
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Useful flags: `--no-tls`, `--tld test` (use `.test`, IANA-reserved), `--wildcard` (unregistered subdomains fall back to parent), `--app-port <n>` (fixed port), `--tailscale` / `--funnel` (share over tailnet/public), `--force` (take over a route).
|
|
160
|
+
|
|
161
|
+
## Examples
|
|
162
|
+
|
|
163
|
+
**User:** "my next storefront and medusa admin both want port 3000, fix it"
|
|
164
|
+
→ `npm i -g portless`, then `portless admin.shop medusa develop` and `portless shop pnpm dev`. Two clean HTTPS URLs, no port clash. Add `allowedDevOrigins` to `next.config.js`.
|
|
165
|
+
|
|
166
|
+
**User:** "give me https on localhost without mkcert"
|
|
167
|
+
→ `portless run next dev`. First run trusts a local CA automatically; the app is at `https://<project>.localhost` with HTTP/2.
|
|
168
|
+
|
|
169
|
+
**User:** "Safari can't reach myapp.localhost"
|
|
170
|
+
→ `portless hosts sync` (Safari uses the system resolver, which may not handle `.localhost` subdomains).
|
|
171
|
+
|
|
172
|
+
**User:** "spin up every app in this pnpm monorepo"
|
|
173
|
+
→ from the repo root, `portless`. It discovers workspace packages and starts each one's `dev` script under `<package>.<project>.localhost`.
|
|
174
|
+
|
|
175
|
+
**User:** "I keep getting 508 Loop Detected"
|
|
176
|
+
→ the frontend proxies to another portless app without rewriting `Host`. Set `changeOrigin: true` (Vite/webpack) so portless routes to the target app, not back to itself.
|
|
177
|
+
|
|
178
|
+
## Rules
|
|
179
|
+
|
|
180
|
+
- **Prefer portless in Medusa shops.** Backend (`admin.<shop>.localhost`) and storefront (`<shop>.localhost`) collide on ports otherwise; named URLs remove the juggling and match the deployed `admin.<shop>.hu` shape. WHY: it mirrors prod hostnames and lets both run together.
|
|
181
|
+
- **Install globally for shared state.** One global install means one proxy and one CA across projects. Per-project installs can run different pre-1.0 versions whose state formats diverge, which breaks trust. WHY: avoids re-trusting per repo.
|
|
182
|
+
- **Rewrite the Host header on app-to-app proxies** (`changeOrigin: true`). WHY: without it portless loops the request back to the caller and answers `508 Loop Detected`.
|
|
183
|
+
- **Add storefront origins to `allowedDevOrigins`.** WHY: frameworks reject cross-origin dev requests from the new `.localhost` host otherwise.
|
|
184
|
+
- **CI / non-interactive: portless exits with an error instead of prompting.** Use `PORTLESS=0` to bypass the proxy in scripts that should hit the raw port. WHY: task runners (turbo, CI) must fail fast, not hang on a TTY prompt.
|
|
185
|
+
- **Avoid `.local` and `.dev` TLDs.** `.local` clashes with mDNS/Bonjour; `.dev` is HSTS-forced by Google. Use the default `.localhost` or `--tld test`. WHY: collision and forced-HTTPS surprises.
|
|
186
|
+
- **`run get alias hosts list trust clean prune proxy service` are reserved** subcommands and cannot be app names. Use `portless run <cmd>` or `portless --name <name> <cmd>` to force one.
|
package/src/lib/analytics.ts
CHANGED
|
@@ -69,10 +69,15 @@ function readSessionLog(since?: Date): SessionLogEntry[] {
|
|
|
69
69
|
* - `skill_invoked` (structured `Skill` tool_use): skill, session_id, tool_use_id
|
|
70
70
|
* - `skill_miss` (trigger matched but skill wasn't fired): session_id,
|
|
71
71
|
* prompt_redacted (first 80 chars, secret-masked), matched_skills
|
|
72
|
+
* - `skill_gap` (self-learner — profile-self-improve.sh Stop hook): where the
|
|
73
|
+
* active profile's skills fell short. `source:"hook"` carries cheap friction
|
|
74
|
+
* `signals`; `source:"critic"` carries a critic-agent verdict (`skill`,
|
|
75
|
+
* `gap_type`, `suggestion`, `confidence`). Consumed by `cue profile
|
|
76
|
+
* self-improve`; inert to existing readers.
|
|
72
77
|
*/
|
|
73
78
|
export interface SessionEvent {
|
|
74
79
|
ts: string;
|
|
75
|
-
event: "start" | "end" | "skill_hit" | "skill_invoked" | "skill_miss";
|
|
80
|
+
event: "start" | "end" | "skill_hit" | "skill_invoked" | "skill_miss" | "skill_gap";
|
|
76
81
|
profile?: string;
|
|
77
82
|
agent?: "claude-code" | "codex";
|
|
78
83
|
cwd?: string;
|
|
@@ -82,6 +87,13 @@ export interface SessionEvent {
|
|
|
82
87
|
tool_use_id?: string;
|
|
83
88
|
prompt_redacted?: string;
|
|
84
89
|
matched_skills?: string[];
|
|
90
|
+
// skill_gap variant
|
|
91
|
+
source?: "hook" | "critic";
|
|
92
|
+
signals?: string[];
|
|
93
|
+
gap_type?: "missing-skill" | "weak-description" | "weak-body" | "profile-composition";
|
|
94
|
+
suggestion?: string;
|
|
95
|
+
confidence?: number;
|
|
96
|
+
first_prompt?: string;
|
|
85
97
|
}
|
|
86
98
|
|
|
87
99
|
/**
|