Skip to content
Back to skills

Apx Profile

ASecurity

Agent profiles: installable lines of work — "el perfil", "perfiles disponibles", "instalá un perfil" — secretary, project manager and others. Load when the user wants to install, activate, configure, diagnose or remove one, or asks why the agent behaves the way it does. Triggers: 'install a profile', 'apx profile', 'what profiles are there', 'activate the secretary', 'go back to vanilla', 'change my agent's schedule', 'why does it message me'.

  • 12 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 27, 2026
ai-agentsgoshellbashnodeapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 27, 2026

npx -y skills add agentprojectcontext/apx --skill apx-profile --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Apx Profile?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Apx Profile
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/agentprojectcontext-apx-profile/badge)](https://www.skillsdirectory.com/skills/agentprojectcontext-apx-profile)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: apx-profile
description: Agent profiles: installable lines of work — "el perfil", "perfiles disponibles", "instalá un perfil" — secretary, project manager and others. Load when the user wants to install, activate, configure, diagnose or remove one, or asks why the agent behaves the way it does. Triggers: 'install a profile', 'apx profile', 'what profiles are there', 'activate the secretary', 'go back to vanilla', 'change my agent's schedule', 'why does it message me'.
---

# apx-profile

A **profile** is an installable package that gives the super-agent a line of work: a
prompt block, its own routines, and the white-label settings the owner fills in. With no
profile active APX is *vanilla* — the system prompt is byte-identical to a clean install.

Three words that are easy to confuse. Keep them apart:

| Term | What it is | Where it lives |
|---|---|---|
| **profile** | an installable line of work (this skill) | `~/.apx/profiles/`, `config.profile` |
| **persona** | the super-agent's visible NAME | `~/.apx/identity.json` → `agent_name` |
| project config | per-project overrides | `~/.apx/projects/<apx_id>/config.json` |

Installing and activating are **different operations**. `install` validates a package and
makes it reachable; `use` is the moment behaviour changes.

## Concrete CLI calls

```bash
# Discover
apx profile list                      # everything available, and which is active
apx profile show secretary            # settings, token cost, where it came from
apx profile show secretary --preview  # ...plus the rendered prompt block

# Install and activate
apx profile install secretary         # a bundled id
apx profile install ./my-profile      # a local package directory
apx profile use secretary             # activates + installs its routines
apx profile use tutor --force         # replace whatever is active
apx profile sync                      # re-read the active package from disk (after an APX update)

# Configure — this is where white-label happens
apx profile config                                  # show current settings
apx profile config --set day_open_schedule="30 8 * * 1-5"
apx profile config --set nudge_budget_per_day=3 --set quiet_hours=22:00-07:30
apx profile config --set watch_schedule="0 */2 * * *" --set formality=vos
apx profile config --interactive                    # walk the whole schema

# Health and removal
apx profile doctor                    # what's missing for it to do its job
apx profile off                       # back to vanilla
apx profile uninstall secretary
```

## What each command actually does

- **`install`** validates the manifest, the schema and every template, then seeds the
  settings with the schema defaults. It does **not** activate. A **local path** is copied
  into `~/.apx/profiles/`; a **bundled** package is not — it is read in place so a later
  `npm update` improves it instead of being shadowed by a stale copy.
- **`use`** writes `config.profile.active`, reloads the prompt, and installs the package's
  routines (named `<profile-id>-<routine>`, marked `origin: "profile:<id>"`).
- **`off`** sets `active: null` and **disables** those routines. It deletes nothing —
  settings, tasks, commitments and memory all survive, so `use` again restores everything.
- **`config`** validates against the schema and **really reschedules**: changing an opening
  time moves the cron, it doesn't just edit JSON.
- **`uninstall`** removes the package and the routines it installed, but **keeps any routine
  the user edited** and never touches one the user wrote. A bundled package can't be
  deleted, so it gets a tombstone and can be reinstalled any time.

## Settings are per profile

`config.profile.configs[<id>]` holds each profile's own settings; `config.profile.config`
mirrors the active one. Switching A → B → A gives A its settings back rather than handing
it B's.

## When the user asks "why did it message me?"

Read the active profile's prompt block — `apx profile show <id> --preview` — and its
settings. Interruption budgets, quiet hours and staleness thresholds are all profile
settings, not core behaviour. If the answer is "it shouldn't have", the fix is usually
`apx profile config`, not a code change.

## Package layout

```
<id>/
  profile.json            # manifest: id, name, version, requires, prompt_budget_tokens
  PROFILE.md              # the always-on prompt block (template)
  PROFILE.es.md           # optional translations: PROFILE.<lang>.md
  config.schema.json      # the white-label settings, every one with a default
  channels/<ch>.md        # optional per-channel overlay, appended after the core file
  routines/*.json         # routines it installs
  agents/*.md             # specialists it adds to the vault
  skills/<slug>/SKILL.md  # its own operational procedures
```

**Template rules, enforced at install time** (installation fails, naming the variable):

- Only flat `{{single_word}}` names. `{{profile.name}}` cannot be substituted and is rejected.
- Every variable must resolve: a built-in (`owner_name`, `agent_name`, `owner_context`,
  `profile_name`) or a schema property **with a default**. A property declared without a
  default is rejected, because it would silently render as an empty string.

**In `routines/*.json`, settings render as VALUES, not as text.** The file is parsed first
and each string leaf rendered after, so a setting carrying quotes (a shell command with JSON
arguments, say) cannot break the document. Two consequences worth knowing:

- A `pre_commands` / `post_commands` entry that renders empty is dropped entirely, so an
  optional command is just a setting defaulting to `""` — no empty shell step, no pre phase.
- `{{pre_output}}` is left alone by the renderer and filled by the routine runner at run
  time. That is how a routine hands itself data without spending a tool call or a permission
  on it — the secretary's `calendar_command` is the live example.

## A package updates, its installed routines do not

The prompt block is rendered every turn, so it improves the moment APX updates. Routines are
records in the super-agent's store, written at install time — nothing carries a better anchor
across. `apx profile sync` (and any settings save) re-renders them from the package on disk,
leaving settings, activation AND each routine's on/off alone — only `apx profile use` applies the
package's `enabled_by_default`. A package may ship routines OFF (company: only the weekly review
and monthly scorecard start on; the pulse, the decision brief and the councils are installed off —
`apx routine enable <name>` turns one on); `apx profile doctor` reports the drift so it is not silent. A routine the
owner edited is skipped forever, by design, which also means a profile SETTING that lands in
a routine stops taking effect on that routine once they have touched it.

## Channel overlays

`channels/<ch>.md` is rendered and appended after the core `channels/<ch>.md`, only on that
surface. Use it for judgement that must load deterministically where a decision is taken —
the rules for speaking unprompted belong in `channels/routine.md`, not in an on-demand
skill, because "should I interrupt?" is a decision the model may not know it is about to
take. Costs nothing on the channels that don't need it.

## The prompt budget is real

The block ships on **every turn of every channel**, on top of a ~2.5k-token base. A
package declares `prompt_budget_tokens`; exceeding it warns, exceeding 1.5× fails to
install. Check the real number with `apx profile show <id>` or
`node scripts/inspect-channel-prompts.js`.

## HTTP

`GET /api/profiles` · `GET /api/profiles/:id` (includes `preview`) · `GET /api/profiles/doctor` ·
`POST /api/profiles/install` · `POST /api/profiles/use` · `POST /api/profiles/off` ·
`POST /api/profiles/sync` (re-applies a package's routines after an update — `apx profile sync`) ·
`PATCH /api/profiles/config` · `DELETE /api/profiles/:id` ·
`POST /api/profiles/readopt` (force the active profile's routines back to the package, past the
user_modified/user_owned skips sync respects — `{ routine }` targets one, omit for all; the
web "Re-sync routines" button. It discards local edits to the affected routines.)

## Gotchas

- **`install` does not activate.** The most common confusion. Follow it with `use`.
- **One profile at a time.** Activating a second needs `--force`.
- **`off` is not `uninstall`.** `off` is reversible and keeps everything.
- **The vanilla invariant is load-bearing.** With no profile active the prompt must stay
  byte-identical. If a change would alter that, it's a bug, not a feature.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…