# Connect an agent

1. The owner creates or chooses an unencrypted goal, then creates a connection at
   https://www.achieveaims.com/agents. Only selected goals are accessible. Read-only
   is the default; enable writing to save work, criteria, evidence, and handoffs.
   Separately enable “Allow this agent to read my ideas” to share unlinked ideas
   and ideas attached to selected unencrypted goals. This includes future ideas
   in that scope and never allows editing ideas. Scratchpads are not included.
   Enable “Allow this agent to propose goal changes for my approval” separately
   for goal batches. This does not give the agent permission to commit them.
2. Download the private connection JSON when the key is shown. Move it into a
   private directory outside source control. On macOS/Linux run `chmod 600` on
   the file. On Windows restrict its ACL to the owner. Never attach it to a chat.
3. Set `AIM_CONNECTION_FILE` in the executing host to that file's absolute path.
   Alternatively use its secret store to inject `AIM_AGENT_TOKEN`; the API origin
   defaults to `https://www.achieveaims.com`. A sandbox needs the file or secret
   explicitly provided inside its execution environment.

The file has `apiUrl` and `token` fields. The client uses the file as a pair,
ignoring environment origin/token overrides when a file is selected. Neither a
token nor a connection file is distributed in the public skill.

## Terminal and HTTP

Requires Node 22+; no npm install. From the extracted skill directory:

```sh
export AIM_CONNECTION_FILE="/absolute/private/path/achieve-aims-connection.json"
node scripts/aims.mjs connection
node scripts/aims.mjs list
node scripts/aims.mjs ideas
node scripts/aims.mjs today
node scripts/aims.mjs read GOAL_ID
```

`list` reports `capabilities.readIdeas`. `ideas` requires that permission;
`list` and `ideas` each accept their own optional nextCursor. Read before writing, then save a command
file with the returned workspace version, a UUID operationId, and one operation.
The client never invents or changes operation IDs and never retries automatically.
For example, after reading version 0, a handoff command file could contain:

```json
{
  "version": 0,
  "operationId": "91586d91-150a-4160-8c08-60492b2479ed",
  "operation": {
    "type": "handoff",
    "summary": "The user chose to outline one short story this week.",
    "nextAction": "Ask which 20-minute window they want to use tomorrow."
  }
}
```

Generate your own UUID (for example `node -e 'console.log(crypto.randomUUID())'`)
and use the version actually read. Then:

```sh
node scripts/aims.mjs write GOAL_ID /private/command.json
```

HTTP tools can use `Authorization: Bearer` from private configuration:

- GET `/api/v1/goals` (follow `?after=nextCursor`).
- GET `/api/v1/ideas` (separate idea permission; follow its `?after=nextCursor`).
- GET `/api/v1/today` (up to 50 active accessible goals).
- GET `/api/v1/goals/{goalId}/workspace`.
- PATCH the same workspace URL with `Content-Type: application/json` and the command.

Full schemas: https://www.achieveaims.com/openapi.json. Operations: create_item,
update_item, add_note, set_criteria, handoff. Workspace criteria are separate
from the parent goal specification. Work items are separate from its legacy checklist.

## Owner-approved goal batches

`connection` / GET `/api/v1/connection` returns the current connection's name,
assigned goalIds, canWrite, canReadIdeas, canProposeGoals and expiry. Metadata never
contains the key. Existing keys keep their permissions; create a replacement key
with proposal access enabled at /agents and replace it through the secure field.
Reload the latest skill ZIP or Grok tools/template to discover these operations.

When canProposeGoals is true, draft up to 20 create/update operations in one file.
Read each existing target's workspace first and copy its `goal.revision` (different
from workspace.version). A null revision means the specification is unavailable
for proposals. Each goal can appear in one update; combine its changes there.
Allowed fields: title, specification (description and details, or null to clear),
status (`active`, `completed`, `deferred`), integer order (0–1,000,000). To reorder,
include updates with the desired order for all affected, assigned goals. No delete.

```json
{
  "operationId": "656c5a82-22dc-4a95-9017-20d4c3f34ff9",
  "summary": "My next aims, drafted with my coach",
  "operations": [
    { "type": "create", "goal": { "title": "Build a regular meditation practice", "order": 1, "status": "active", "specification": { "description": "Make time for reflection every day", "details": ["Start with five minutes"] } } }
  ]
}
```

For an existing aim use an operation shaped as
`{ "type": "update", "goalId": "ID_FROM_LIST", "revision": "HASH_FROM_READ", "changes": { "status": "deferred", "order": 8 } }`.
Generate a fresh UUID for your own draft; preserve it and the complete payload on retry.

```sh
node scripts/aims.mjs propose /private/proposal.json
node scripts/aims.mjs proposal PROPOSAL_ID
```

These map to POST `/api/v1/goal-proposals` and GET `/api/v1/goal-proposals/{id}`.
The response provides `reviewUrl` for the owner and a pending proposal. Present
that link. Only the signed-in owner may approve in the app; never use their
browser session to approve on their behalf. A verbal yes in chat is not an API approval.
The owner sees before/after and approves all changes or rejects the batch. No
partial application. To revise, submit a new draft and reject the old one.

Proposals expire in 24 hours. Approval rechecks current ownership, scope,
encryption, credential expiry/revocation, goal revisions and plan limits. A
`stale_goal` requires reading and reconciling before submitting a new UUID/draft.
New goals are unencrypted, belong to the owner and count toward their plan limit.
They are not added to the agent's scope unless the owner explicitly checks sharing
at review. Existing read/write/idea/proposal permissions stay the same. The
20-goal connection limit applies. Poll the proposal after review: only `applied`
means the changes were saved. List/read again for current accessible context.
This does not edit affirmations or ideas, or log practice.

## Retry and access failures

- Lost response: retry the identical saved command file. A replay does not duplicate work.
- 409 version_conflict: read again, reconcile concurrent changes, then create a
  new command and UUID. For other 409 errors inspect the code; capacity requires
  an owner-created follow-up goal, not a retry loop.
- 401: invalid, expired, or revoked key; ask the owner to create a new connection.
- 403 proposals_not_enabled: ask the owner for an explicitly opted-in replacement connection.
- 403 ideas_not_shared: stop idea reads. A new connection with idea sharing is needed.
- 403 read_only: stop writes. A new owner-issued write connection is needed.
- 404: unavailable goal or item; stay within the connection's scope.
- 429: retry after the next minute begins.

Credentials default to 30 days (owner can choose 1–90 through the API).
Limits: 100 items/goal, 50 notes/item, 1,000 commands/workspace, 4 MB workspace,
32 KB requests, and 120 requests/key/minute. No scheduled agent execution is installed.

## Add idea access to an existing agent

Existing credentials keep their original permissions. At /agents the owner
creates a new connection, selects goals, and enables “Allow this agent to read
my ideas.” Replace the old key through the host's secure credential field or
private configuration. Confirm `list` reports `capabilities.readIdeas: true`,
then run `ideas`. Revoke the old connection after confirming the replacement.

If the installed client does not recognize `ideas`, download and extract the
current skill ZIP, replacing the public skill files while keeping the private
connection outside that folder. Reload the skill in the host. HTTP hosts can
use GET /api/v1/ideas directly; Grok function hosts should reload grok-tools.json
and map list_ideas to that endpoint. Templates already copied into a host do
not update automatically.

Each page contains up to 50 ideas and `scope: unlinked_and_selected_goals`.
Ideas tied to unassigned, encrypted, deleted, or foreign-owned goals are excluded,
even if visible when the connection was created. Linked goal titles reflect the
currently accessible goal. Idea reads expose no account or scratchpad fields.

## Host setup

The same folder works with hosts that load SKILL.md and can run the script.
Place the extracted `achieve-aims` folder in the host's skill directory and make
Node, network access, and the private credential available to its execution tool.

- OpenClaw: `<workspace>/skills/achieve-aims/` is a documented workspace skill
  location. Start a fresh session after installation. See
  https://docs.openclaw.ai/tools/skills for sandbox and secret configuration.
- Hermes: install the complete folder in its configured skills root (normally
  `~/.hermes/skills/achieve-aims/`), then load the skill in a new session. See
  https://hermes-agent.nousresearch.com/docs/guides/work-with-skills.
- Other terminal agents: give the agent this skill and the absolute script path.
- HTTP-only hosts: register tools from the OpenAPI contract. Tool execution must
  inject the credential; the model should never construct or receive the key.

These are host configuration instructions, not certification of every host/version.
The standalone terminal flow is tested against real API handlers. A skill alone
does not enable missing tools. There is no hosted `/mcp` endpoint; HTTP/terminal
is the public connection path. The repository MCP bridge is for repository users.
