@acnlabs/paperclip-plugin-acn 0.1.0 → 0.2.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/CHANGELOG.md +82 -0
- package/README.md +13 -13
- package/SKILL.md +155 -0
- package/dist/constants.d.ts +6 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -2
- package/dist/constants.js.map +1 -1
- package/dist/lib/org-api.d.ts +58 -0
- package/dist/lib/org-api.d.ts.map +1 -0
- package/dist/lib/org-api.js +111 -0
- package/dist/lib/org-api.js.map +1 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +16 -9
- package/dist/manifest.js.map +1 -1
- package/dist/ui/index.d.ts +9 -5
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +22 -2
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.d.ts +70 -8
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +480 -65
- package/dist/worker.js.map +1 -1
- package/package.json +6 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@acnlabs/paperclip-plugin-acn` are documented here.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
|
6
|
+
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 2026-07-22
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **P2c C0/C1 — Issue create → Org work.** Human-created Paperclip issues now
|
|
13
|
+
call `POST /api/v1/orgs/{org_id}/work` instead of Task Pool `createTask`.
|
|
14
|
+
- **P2c C2 — Inbound `org.work_*` / `org.loop_tick`.** Harness webhooks for
|
|
15
|
+
Org work create/update mirror into Issues via `issue-work-map`; loop ticks
|
|
16
|
+
leave one throttled comment on the first mapped open work. In-flight binding
|
|
17
|
+
covers ACN's synchronous harness POST during `createWork` (no twin Issue);
|
|
18
|
+
late retries use a post-persist echo set. ACN issue tab renders Org work
|
|
19
|
+
ids without crashing on null Task fields. Note: for org.* events ACN's
|
|
20
|
+
`task_id` field carries `org_id` — the plugin keys off `event` + `data.work_id`.
|
|
21
|
+
- New config `acnOrgId`. When empty, setup creates an Org bound to
|
|
22
|
+
`acnSubnetId` and stores the id in company-scoped plugin state.
|
|
23
|
+
- New state map `issue-work-map` (`work_id` → issue id). Legacy
|
|
24
|
+
`issue-task-map` remains for inbound `task.*` mirroring and review.
|
|
25
|
+
- On `subnet_already_bound` (409): reuse Org id from error message when
|
|
26
|
+
present; otherwise fail with an explicit “set `acnOrgId`” instruction.
|
|
27
|
+
- Warn when `acnSubnetId` disagrees with the Org fence (prefer Org fence).
|
|
28
|
+
- Warn when multiple Paperclip companies exist (only the first is bound).
|
|
29
|
+
- `SKILL.md` rewritten for the Org work path (no longer teaches `createTask`).
|
|
30
|
+
|
|
31
|
+
- **P2c C3 — Issue status → Org work PATCH.** Moving an Org-mapped issue to
|
|
32
|
+
`done` / `cancelled` calls `PATCH /orgs/{id}/work/{work_id}`. `done` still
|
|
33
|
+
respects `autoApproveOnDone`; `cancelled` always syncs. Legacy Task `/review`
|
|
34
|
+
remains only for issues linked via `issue-task-map`.
|
|
35
|
+
|
|
36
|
+
### Deprecated
|
|
37
|
+
|
|
38
|
+
- Outbound Issue → Task Pool create (removed).
|
|
39
|
+
- Inbound `task.*` mirror remains for transition; Issue → Task `/review` only
|
|
40
|
+
for legacy Task-mirrored issues.
|
|
41
|
+
|
|
42
|
+
## [0.1.1] - 2026-05-16
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **Default `acnBaseUrl` now points at the live ACN production endpoint
|
|
47
|
+
(`https://api.acnlabs.dev`)**. The `v0.1.0` release shipped with a
|
|
48
|
+
placeholder vanity domain (`https://acn.agentplanet.io`) that was never
|
|
49
|
+
actually registered — installing the plugin without overriding the URL would
|
|
50
|
+
fail at the first ACN call with `getaddrinfo ENOTFOUND`. With this release,
|
|
51
|
+
new users can install the plugin and connect to ACN Labs' hosted production
|
|
52
|
+
with zero additional infrastructure; self-hosters can still override
|
|
53
|
+
`acnBaseUrl` to point at their own deployment.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- `instanceConfigSchema.acnBaseUrl.description` now spells out the hosted /
|
|
58
|
+
self-host trade-off so the choice is visible in Paperclip's Instance
|
|
59
|
+
Settings UI without having to read the README.
|
|
60
|
+
- README `Prerequisites` and `Configuration` sections updated to reflect that
|
|
61
|
+
an ACN deployment is no longer something the user has to bring — the
|
|
62
|
+
default is a working public endpoint.
|
|
63
|
+
|
|
64
|
+
## [0.1.0] - 2026-05-15
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- Initial public release on npm.
|
|
69
|
+
- Bidirectional sync between Paperclip issues and ACN tasks:
|
|
70
|
+
- ACN → Paperclip: `task.created` / `accepted` / `submitted` / `completed`
|
|
71
|
+
/ `rejected` / `cancelled` / `participation.rejected` webhooks mirror
|
|
72
|
+
state into issue lifecycle + comments.
|
|
73
|
+
- Paperclip → ACN: human-created issues spawn ACN tasks in the configured
|
|
74
|
+
subnet; moving an issue to `done` (with `autoApproveOnDone`) or
|
|
75
|
+
`cancelled` posts the corresponding `/tasks/:id/review` decision.
|
|
76
|
+
- HMAC-SHA256 signed harness webhooks (`X-ACN-Signature: sha256=<hex>`),
|
|
77
|
+
with a compatibility layer for Paperclip's `secrets.read-ref` capability.
|
|
78
|
+
- Issue-detail "ACN" tab showing task ID, status, reward, participants, and
|
|
79
|
+
approve / reject actions for pending submissions.
|
|
80
|
+
- GitHub Actions: `ci.yml` (typecheck + build + tests + pack dry-run on
|
|
81
|
+
push/PR to main) and `release.yml` (npm publish + GitHub Release on
|
|
82
|
+
`v*` tags).
|
package/README.md
CHANGED
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
A [Paperclip](https://github.com/paperclipai/paperclip) plugin that connects ACN (Agent Collaboration Network) as the **identity, communication, and settlement** layer for agent organizations.
|
|
4
4
|
|
|
5
|
+
> **For AI agents helping a user set this up:** load [`SKILL.md`](./SKILL.md) — an agent-oriented, copy-pastable integration guide that complements this human-oriented README.
|
|
6
|
+
|
|
5
7
|
## What it does
|
|
6
8
|
|
|
7
9
|
| Direction | Trigger | Action |
|
|
8
10
|
|-----------|---------|--------|
|
|
9
|
-
|
|
|
10
|
-
| ACN → Paperclip | `
|
|
11
|
-
| ACN → Paperclip | `task
|
|
12
|
-
|
|
|
13
|
-
| ACN
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| Paperclip → ACN | Issue moved to `done` (and `Auto-approve` enabled) | Call `/tasks/:id/review` → approve & settle |
|
|
17
|
-
| Paperclip → ACN | Issue moved to `cancelled` | Call `/tasks/:id/review` → reject |
|
|
18
|
-
| UI | ACN tab on issue | Show task ID, status, reward, participants; approve / reject pending submission |
|
|
11
|
+
| Paperclip → ACN | Issue **created** by a human (not by this plugin) | Create **Org work** on the configured ACN Org (`POST /orgs/{id}/work`) — **not** Task Pool |
|
|
12
|
+
| ACN → Paperclip | `org.work_created` / `org.work_updated` / `org.loop_tick` | Mirror Org work into Issues (preferred inbound) |
|
|
13
|
+
| ACN → Paperclip | `task.*` webhooks (**legacy**) | Mirror Task Pool tasks into issues |
|
|
14
|
+
| Paperclip → ACN | Issue moved to `done` / `cancelled` | Org work `PATCH` when linked via `issue-work-map`; Task `/review` only for legacy Task mirrors |
|
|
15
|
+
| UI | ACN tab on issue | Shows `work_id` for Org-backed issues; Task fields for legacy mirrors |
|
|
16
|
+
|
|
17
|
+
> **P2c C0–C3 (v0.2):** Org Harness Work Port for create, inbound `org.*` webhooks, and Issue → work status PATCH. Configure **ACN Org ID** (or leave empty + set **ACN Subnet ID** so setup can `POST /orgs` once).
|
|
19
18
|
|
|
20
19
|
> **Note (v0.1):** the plugin does **not** create or sync Paperclip agents from ACN. The Paperclip Plugin SDK does not yet expose a dynamic-agent-creation capability, so each agent type is provisioned independently (see *Agent topology* below).
|
|
21
20
|
|
|
@@ -45,7 +44,7 @@ receive task lifecycle events.
|
|
|
45
44
|
### Prerequisites
|
|
46
45
|
|
|
47
46
|
- A running Paperclip instance (self-hosted, with the plugin worker enabled)
|
|
48
|
-
- An ACN deployment you can reach from the Paperclip host
|
|
47
|
+
- An ACN deployment you can reach from the Paperclip host — defaults to ACN Labs' hosted production at `https://api.acnlabs.dev`; point `acnBaseUrl` at your own ACN to self-host
|
|
49
48
|
- An ACN **agent API key** (`acn_…`) with `task.write` scope
|
|
50
49
|
- An ACN **subnet** owned by that agent (the plugin will register itself as the subnet's Org Harness)
|
|
51
50
|
- A shared **HMAC secret** for signing harness webhook deliveries (any high-entropy random string, e.g. `openssl rand -hex 32`)
|
|
@@ -72,13 +71,14 @@ Paperclip → **Instance Settings → Plugins → ACN**:
|
|
|
72
71
|
|
|
73
72
|
| Field | Required | Description |
|
|
74
73
|
|-------|----------|-------------|
|
|
75
|
-
| `acnBaseUrl` |
|
|
74
|
+
| `acnBaseUrl` | no (default `https://api.acnlabs.dev`) | Base URL of the ACN instance (no trailing slash). Leave the default to use ACN Labs' hosted production, or set it to your self-hosted ACN. |
|
|
76
75
|
| `paperclipBaseUrl` | **strongly recommended** | Publicly reachable base URL of **this** Paperclip instance (e.g. `https://app.paperclip.ai`). Used to construct the harness webhook URL ACN posts to. If omitted, the plugin still calls into ACN outbound (Paperclip → ACN direction works) but cannot register itself as a webhook target, so inbound ACN events will be lost. |
|
|
77
76
|
| `acnApiKeyRef` | yes | Secret reference to the ACN agent API key (`acn_…`). Resolved at runtime via Paperclip's secret provider. |
|
|
77
|
+
| `acnOrgId` | recommended | Existing Org id (`org_…`). If empty, setup creates an Org bound to `acnSubnetId` and persists it in plugin state. |
|
|
78
78
|
| `acnHarnessSecretRef` | **strongly recommended** | Secret reference to the HMAC-SHA256 secret shared with ACN. The plugin verifies every inbound webhook against `X-ACN-Signature: sha256=<hex>`. **Leave blank only in trusted dev environments** — without a secret anyone who can reach `/api/plugins/acnlabs.acn/webhooks/acn-events` can forge ACN events. |
|
|
79
79
|
| `acnSubnetId` | yes | The ACN subnet whose tasks this plugin syncs |
|
|
80
80
|
| `autoCreateIssues` | no (default `true`) | Auto-create Paperclip issues for new ACN tasks |
|
|
81
|
-
| `autoApproveOnDone` | no (default `false`) | When a Paperclip user moves
|
|
81
|
+
| `autoApproveOnDone` | no (default `false`) | When a Paperclip user moves a linked issue to `done`: Org-mapped issues PATCH work status; legacy Task mirrors call `/review?approved=true`. Off by default. `cancelled` always syncs. |
|
|
82
82
|
|
|
83
83
|
### 3. Verify
|
|
84
84
|
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: paperclip-plugin-acn
|
|
3
|
+
description: Connect a Paperclip instance to ACN Org Harness. Use when installing or configuring `@acnlabs/paperclip-plugin-acn`, wiring Paperclip issue → ACN Org work, registering the Paperclip side as an ACN Org Harness webhook, or debugging issue/work mirroring, webhook delivery, or HMAC signature verification. Task Pool mirroring is legacy inbound only.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: "Required: a self-hosted Paperclip instance with plugin worker enabled (Paperclip SDK >= 2026.512.0), HTTPS access to an ACN instance (defaults to https://api.acnlabs.dev). Required config: ACN agent API key (acn_*) with write access, either acnOrgId or acnSubnetId (to create/bind Org), and an HMAC-SHA256 secret for harness webhook signing. Load the ACN skill when the user does not yet have credentials."
|
|
6
|
+
metadata:
|
|
7
|
+
author: acnlabs
|
|
8
|
+
version: "0.2.0"
|
|
9
|
+
npm: "@acnlabs/paperclip-plugin-acn"
|
|
10
|
+
homepage: "https://github.com/acnlabs/paperclip-acn-plugin"
|
|
11
|
+
repository: "https://github.com/acnlabs/paperclip-acn-plugin"
|
|
12
|
+
acn_default_base_url: "https://api.acnlabs.dev"
|
|
13
|
+
prerequisite_skill: "acn (https://api.acnlabs.dev/skill.md)"
|
|
14
|
+
allowed-tools: Bash(paperclipai:*) Bash(curl:api.acnlabs.dev) Bash(curl:acn.acnlabs.cn) Bash(openssl:rand) WebFetch
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Paperclip Plugin for ACN (Org Harness)
|
|
18
|
+
|
|
19
|
+
Bridges [Paperclip](https://github.com/paperclipai/paperclip) to ACN **Org Harness**:
|
|
20
|
+
human-created issues become **Org work items** (`POST /api/v1/orgs/{id}/work`),
|
|
21
|
+
not Task Pool tasks. Inbound `task.*` webhooks remain as a **legacy** mirror.
|
|
22
|
+
|
|
23
|
+
**Package:** `@acnlabs/paperclip-plugin-acn` ≥ 0.2.0
|
|
24
|
+
**Defaults to:** `https://api.acnlabs.dev` (use `https://acn.acnlabs.cn` for CN)
|
|
25
|
+
**Prerequisite skill:** [`acn`](https://api.acnlabs.dev/skill.md)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## When to use this skill
|
|
30
|
+
|
|
31
|
+
- Install / configure `@acnlabs/paperclip-plugin-acn`
|
|
32
|
+
- Diagnose "issue not creating Org work" or harness webhook problems
|
|
33
|
+
- Switch `acnBaseUrl` (global vs CN) or bind an existing `org_…`
|
|
34
|
+
|
|
35
|
+
If the user has **no Paperclip** and wants raw ACN, load the ACN skill instead.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Quickstart (Org work path)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
paperclipai plugin install @acnlabs/paperclip-plugin-acn
|
|
43
|
+
|
|
44
|
+
# Bridge agent + subnet (ACN skill / CLI)
|
|
45
|
+
acn join --name "paperclip-bridge"
|
|
46
|
+
ACN_API_KEY=$(acn config get api_key)
|
|
47
|
+
SUBNET_ID=$(curl -s "$ACN_BASE/api/v1/subnets" \
|
|
48
|
+
-H "Authorization: Bearer $ACN_API_KEY" \
|
|
49
|
+
-H "Content-Type: application/json" \
|
|
50
|
+
-d '{"name":"paperclip-org","description":"Paperclip Org fence"}' \
|
|
51
|
+
| jq -r '.slug // .subnet_id')
|
|
52
|
+
|
|
53
|
+
HARNESS_SECRET=$(openssl rand -hex 32)
|
|
54
|
+
paperclipai secrets set acn_api_key "$ACN_API_KEY"
|
|
55
|
+
paperclipai secrets set acn_harness_secret "$HARNESS_SECRET"
|
|
56
|
+
|
|
57
|
+
# Instance Settings → Plugins → ACN:
|
|
58
|
+
# acnApiKeyRef = acn_api_key
|
|
59
|
+
# acnHarnessSecretRef = acn_harness_secret
|
|
60
|
+
# acnSubnetId = $SUBNET_ID # plugin will POST /orgs once if acnOrgId empty
|
|
61
|
+
# # OR set acnOrgId = org_… for an existing Org
|
|
62
|
+
# paperclipBaseUrl = https://<your-paperclip>
|
|
63
|
+
# acnBaseUrl = blank (global) or https://acn.acnlabs.cn
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Expect setup logs:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
acn-plugin: created ACN Org for company { org_id: "org_…", subnet_id: "…" }
|
|
70
|
+
# or: reusing / configured org
|
|
71
|
+
acn-plugin: registered harness { subnet_id: "…", org_id: "…", signed: true }
|
|
72
|
+
acn-plugin: setup complete { org_id: "…", subnet_id: "…" }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Copy the logged `org_id` into `acnOrgId` for stable restarts.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Configuration
|
|
80
|
+
|
|
81
|
+
| Field | Required | Purpose |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| `acnApiKeyRef` | yes | Secret ref → `acn_…` key |
|
|
84
|
+
| `acnOrgId` | recommended | Existing `org_…`. Empty → create Org bound to `acnSubnetId` |
|
|
85
|
+
| `acnSubnetId` | yes if no Org | Fence subnet; also used when creating Org |
|
|
86
|
+
| `acnHarnessSecretRef` | strongly recommended | HMAC for inbound harness webhooks |
|
|
87
|
+
| `paperclipBaseUrl` | strongly recommended | Public Paperclip URL for webhook registration |
|
|
88
|
+
| `acnBaseUrl` | no | Default `https://api.acnlabs.dev` |
|
|
89
|
+
| `autoCreateIssues` | no | Legacy: inbound `task.*` → Issue |
|
|
90
|
+
| `autoApproveOnDone` | no | Issue done → Org work PATCH (or legacy Task `/review`) |
|
|
91
|
+
|
|
92
|
+
**Subnet already bound:** if create Org returns 409 and the error message includes
|
|
93
|
+
`org_…`, the plugin reuses that Org. Otherwise set `acnOrgId` explicitly and restart.
|
|
94
|
+
|
|
95
|
+
**Multi-company:** only the first Paperclip company is bound to one ACN Org (v0.2).
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Behavior (v0.2)
|
|
100
|
+
|
|
101
|
+
### Paperclip → ACN (primary)
|
|
102
|
+
|
|
103
|
+
| Event | ACN effect |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `issue.created` (human, not plugin echo) | `POST /orgs/{acnOrgId}/work` with issue title |
|
|
106
|
+
| `issue.updated` → `done` / `cancelled` | `PATCH /orgs/{id}/work/{work_id}` when in `issue-work-map` (`done` respects `autoApproveOnDone`) |
|
|
107
|
+
|
|
108
|
+
State: company-scoped `issue-work-map` (`work_id` → issue id).
|
|
109
|
+
|
|
110
|
+
### ACN → Paperclip (preferred)
|
|
111
|
+
|
|
112
|
+
| Event | Effect |
|
|
113
|
+
|---|---|
|
|
114
|
+
| `org.work_created` | Create Issue + `issue-work-map` (skipped if we just created the work outbound) |
|
|
115
|
+
| `org.work_updated` | Sync Issue status (`todo`/`done`/`cancelled`); `in_progress` → comment only |
|
|
116
|
+
| `org.loop_tick` | Comment on mapped open Issues (no L1 wakeup) |
|
|
117
|
+
|
|
118
|
+
### ACN → Paperclip (legacy)
|
|
119
|
+
|
|
120
|
+
| Event | Effect |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `task.*` / `participation.*` | Mirror into Issues (same as 0.1.x) |
|
|
123
|
+
|
|
124
|
+
Issue done/cancelled → Task `/review` only when the issue was Task-mirrored (`issue-task-map`).
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Verify
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# 1. Create a Paperclip issue as a human
|
|
132
|
+
# 2. List Org work on ACN
|
|
133
|
+
curl -s -H "Authorization: Bearer $ACN_API_KEY" \
|
|
134
|
+
"$ACN_BASE/api/v1/orgs/$ORG_ID/work" | jq .
|
|
135
|
+
# Expect a work item with the issue title — NOT a row under /api/v1/tasks
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Common issues
|
|
141
|
+
|
|
142
|
+
| Symptom | Fix |
|
|
143
|
+
|---|---|
|
|
144
|
+
| Setup skipped: need org or subnet | Set `acnOrgId` or `acnSubnetId` |
|
|
145
|
+
| 409 subnet already bound, no org hint | Set `acnOrgId` to the Org that owns the subnet |
|
|
146
|
+
| Issue created, no Org work | Bridge agent must govern the Org (steward); check plugin logs |
|
|
147
|
+
| `signed: false` | Set `acnHarnessSecretRef` |
|
|
148
|
+
| Still creating Tasks | Upgrade to plugin ≥ 0.2.0 and restart |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## When to use the ACN skill
|
|
153
|
+
|
|
154
|
+
Agent join, subnet admission, A2A messaging, payments, key rotation — use the ACN skill.
|
|
155
|
+
This skill only covers Paperclip ↔ Org Harness wiring.
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const PLUGIN_ID = "acnlabs.acn";
|
|
2
|
-
export declare const PLUGIN_VERSION = "0.
|
|
2
|
+
export declare const PLUGIN_VERSION = "0.2.0";
|
|
3
3
|
export declare const WEBHOOK_KEYS: {
|
|
4
4
|
readonly acnEvents: "acn-events";
|
|
5
5
|
};
|
|
@@ -11,7 +11,11 @@ export declare const EXPORT_NAMES: {
|
|
|
11
11
|
};
|
|
12
12
|
/** Plugin state keys. State is company-scoped (see `loadMap`/`saveMap`). */
|
|
13
13
|
export declare const STATE_KEYS: {
|
|
14
|
-
/** Map of ACN taskId → Paperclip issueId. */
|
|
14
|
+
/** Map of ACN taskId → Paperclip issueId (legacy Task Pool mirror). */
|
|
15
15
|
readonly issueTaskMap: "issue-task-map";
|
|
16
|
+
/** Map of ACN workId → Paperclip issueId (Org Harness Work Port). */
|
|
17
|
+
readonly issueWorkMap: "issue-work-map";
|
|
18
|
+
/** Persisted Org id when auto-created on setup (company-scoped string). */
|
|
19
|
+
readonly acnOrgId: "acn-org-id";
|
|
16
20
|
};
|
|
17
21
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,gBAAgB,CAAC;AACvC,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,YAAY;;CAEf,CAAC;AAEX,eAAO,MAAM,QAAQ;;CAEX,CAAC;AAEX,eAAO,MAAM,YAAY;;CAEf,CAAC;AAEX,4EAA4E;AAC5E,eAAO,MAAM,UAAU;IACrB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,gBAAgB,CAAC;AACvC,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC,eAAO,MAAM,YAAY;;CAEf,CAAC;AAEX,eAAO,MAAM,QAAQ;;CAEX,CAAC;AAEX,eAAO,MAAM,YAAY;;CAEf,CAAC;AAEX,4EAA4E;AAC5E,eAAO,MAAM,UAAU;IACrB,uEAAuE;;IAEvE,qEAAqE;;IAErE,2EAA2E;;CAEnE,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const PLUGIN_ID = "acnlabs.acn";
|
|
2
|
-
export const PLUGIN_VERSION = "0.
|
|
2
|
+
export const PLUGIN_VERSION = "0.2.0";
|
|
3
3
|
export const WEBHOOK_KEYS = {
|
|
4
4
|
acnEvents: "acn-events",
|
|
5
5
|
};
|
|
@@ -11,7 +11,11 @@ export const EXPORT_NAMES = {
|
|
|
11
11
|
};
|
|
12
12
|
/** Plugin state keys. State is company-scoped (see `loadMap`/`saveMap`). */
|
|
13
13
|
export const STATE_KEYS = {
|
|
14
|
-
/** Map of ACN taskId → Paperclip issueId. */
|
|
14
|
+
/** Map of ACN taskId → Paperclip issueId (legacy Task Pool mirror). */
|
|
15
15
|
issueTaskMap: "issue-task-map",
|
|
16
|
+
/** Map of ACN workId → Paperclip issueId (Org Harness Work Port). */
|
|
17
|
+
issueWorkMap: "issue-work-map",
|
|
18
|
+
/** Persisted Org id when auto-created on setup (company-scoped string). */
|
|
19
|
+
acnOrgId: "acn-org-id",
|
|
16
20
|
};
|
|
17
21
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS,EAAE,YAAY;CACf,CAAC;AAEX,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,eAAe;CACjB,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ,EAAE,aAAa;CACf,CAAC;AAEX,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS,EAAE,YAAY;CACf,CAAC;AAEX,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,QAAQ,EAAE,eAAe;CACjB,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ,EAAE,aAAa;CACf,CAAC;AAEX,4EAA4E;AAC5E,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,uEAAuE;IACvE,YAAY,EAAE,gBAAgB;IAC9B,qEAAqE;IACrE,YAAY,EAAE,gBAAgB;IAC9B,2EAA2E;IAC3E,QAAQ,EAAE,YAAY;CACd,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Org Harness HTTP helpers (Phase 2c C0–C3).
|
|
3
|
+
*
|
|
4
|
+
* `acn-client` 0.13.x has no Org APIs yet — call REST directly until the
|
|
5
|
+
* published SDK catches up. Keep this surface tiny: resolve/create Org +
|
|
6
|
+
* create/update work items.
|
|
7
|
+
*/
|
|
8
|
+
export type OrgWorkStatus = "todo" | "in_progress" | "done" | "cancelled";
|
|
9
|
+
export interface OrgRecord {
|
|
10
|
+
org_id: string;
|
|
11
|
+
display_name: string;
|
|
12
|
+
subnet_id?: string;
|
|
13
|
+
fencing?: {
|
|
14
|
+
subnet_id?: string;
|
|
15
|
+
};
|
|
16
|
+
plugins?: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
export interface OrgWorkItem {
|
|
19
|
+
work_id: string;
|
|
20
|
+
org_id: string;
|
|
21
|
+
title: string;
|
|
22
|
+
status: string;
|
|
23
|
+
assignee_agent_id?: string | null;
|
|
24
|
+
}
|
|
25
|
+
/** Structured HTTP failure from ACN (keeps status + parsed JSON body). */
|
|
26
|
+
export declare class AcnHttpError extends Error {
|
|
27
|
+
readonly status: number;
|
|
28
|
+
readonly bodyText: string;
|
|
29
|
+
readonly body: Record<string, unknown> | null;
|
|
30
|
+
constructor(method: string, path: string, status: number, bodyText: string);
|
|
31
|
+
get reason(): string | undefined;
|
|
32
|
+
/** Best-effort extract `org_…` from body/message (ACN may only put it in prose). */
|
|
33
|
+
get boundOrgIdHint(): string | undefined;
|
|
34
|
+
}
|
|
35
|
+
export declare class AcnOrgApi {
|
|
36
|
+
private readonly baseUrl;
|
|
37
|
+
private readonly apiKey;
|
|
38
|
+
constructor(baseUrl: string, apiKey: string);
|
|
39
|
+
private url;
|
|
40
|
+
private request;
|
|
41
|
+
getOrg(orgId: string): Promise<OrgRecord>;
|
|
42
|
+
createOrg(opts: {
|
|
43
|
+
display_name: string;
|
|
44
|
+
subnet_id?: string;
|
|
45
|
+
join_policy?: "open" | "approval";
|
|
46
|
+
}): Promise<OrgRecord>;
|
|
47
|
+
createWork(orgId: string, opts: {
|
|
48
|
+
title: string;
|
|
49
|
+
assignee_agent_id?: string | null;
|
|
50
|
+
}): Promise<OrgWorkItem>;
|
|
51
|
+
updateWorkStatus(orgId: string, workId: string, opts: {
|
|
52
|
+
status: OrgWorkStatus;
|
|
53
|
+
assignee_agent_id?: string | null;
|
|
54
|
+
}): Promise<OrgWorkItem>;
|
|
55
|
+
}
|
|
56
|
+
/** Prefer fencing.subnet_id, fall back to top-level subnet_id. */
|
|
57
|
+
export declare function orgSubnetId(org: OrgRecord): string | undefined;
|
|
58
|
+
//# sourceMappingURL=org-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-api.d.ts","sourceRoot":"","sources":["../../src/lib/org-api.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC;AAE1E,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,0EAA0E;AAC1E,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;gBAElC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAiB1E,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAO/B;IAED,oFAAoF;IACpF,IAAI,cAAc,IAAI,MAAM,GAAG,SAAS,CAYvC;CACF;AAED,qBAAa,SAAS;IAElB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM;IAGjC,OAAO,CAAC,GAAG;YAKG,OAAO;IAkBf,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIzC,SAAS,CAAC,IAAI,EAAE;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;KACnC,GAAG,OAAO,CAAC,SAAS,CAAC;IAQhB,UAAU,CACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GACzD,OAAO,CAAC,WAAW,CAAC;IAYjB,gBAAgB,CACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GACjE,OAAO,CAAC,WAAW,CAAC;CAWxB;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAE9D"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Org Harness HTTP helpers (Phase 2c C0–C3).
|
|
3
|
+
*
|
|
4
|
+
* `acn-client` 0.13.x has no Org APIs yet — call REST directly until the
|
|
5
|
+
* published SDK catches up. Keep this surface tiny: resolve/create Org +
|
|
6
|
+
* create/update work items.
|
|
7
|
+
*/
|
|
8
|
+
/** Structured HTTP failure from ACN (keeps status + parsed JSON body). */
|
|
9
|
+
export class AcnHttpError extends Error {
|
|
10
|
+
status;
|
|
11
|
+
bodyText;
|
|
12
|
+
body;
|
|
13
|
+
constructor(method, path, status, bodyText) {
|
|
14
|
+
super(`ACN ${method} ${path} → ${status}: ${bodyText.slice(0, 300)}`);
|
|
15
|
+
this.name = "AcnHttpError";
|
|
16
|
+
this.status = status;
|
|
17
|
+
this.bodyText = bodyText;
|
|
18
|
+
let parsed = null;
|
|
19
|
+
try {
|
|
20
|
+
const v = JSON.parse(bodyText);
|
|
21
|
+
if (v && typeof v === "object" && !Array.isArray(v)) {
|
|
22
|
+
parsed = v;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
parsed = null;
|
|
27
|
+
}
|
|
28
|
+
this.body = parsed;
|
|
29
|
+
}
|
|
30
|
+
get reason() {
|
|
31
|
+
const details = this.body?.details;
|
|
32
|
+
if (details && typeof details === "object" && !Array.isArray(details)) {
|
|
33
|
+
const r = details.reason;
|
|
34
|
+
return typeof r === "string" ? r : undefined;
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
/** Best-effort extract `org_…` from body/message (ACN may only put it in prose). */
|
|
39
|
+
get boundOrgIdHint() {
|
|
40
|
+
const details = this.body?.details;
|
|
41
|
+
if (details && typeof details === "object" && !Array.isArray(details)) {
|
|
42
|
+
const id = details.bound_org_id;
|
|
43
|
+
if (typeof id === "string" && id.startsWith("org_"))
|
|
44
|
+
return id;
|
|
45
|
+
}
|
|
46
|
+
const msg = (typeof this.body?.message === "string" ? this.body.message : "") +
|
|
47
|
+
" " +
|
|
48
|
+
this.bodyText;
|
|
49
|
+
const m = msg.match(/\borg_[0-9a-fA-F]+\b/);
|
|
50
|
+
return m?.[0];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class AcnOrgApi {
|
|
54
|
+
baseUrl;
|
|
55
|
+
apiKey;
|
|
56
|
+
constructor(baseUrl, apiKey) {
|
|
57
|
+
this.baseUrl = baseUrl;
|
|
58
|
+
this.apiKey = apiKey;
|
|
59
|
+
}
|
|
60
|
+
url(path) {
|
|
61
|
+
const base = this.baseUrl.replace(/\/$/, "");
|
|
62
|
+
return `${base}${path.startsWith("/") ? path : `/${path}`}`;
|
|
63
|
+
}
|
|
64
|
+
async request(method, path, body) {
|
|
65
|
+
const res = await fetch(this.url(path), {
|
|
66
|
+
method,
|
|
67
|
+
headers: {
|
|
68
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
69
|
+
Accept: "application/json",
|
|
70
|
+
...(body !== undefined ? { "Content-Type": "application/json" } : {}),
|
|
71
|
+
},
|
|
72
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
73
|
+
});
|
|
74
|
+
if (!res.ok) {
|
|
75
|
+
const text = await res.text().catch(() => "");
|
|
76
|
+
throw new AcnHttpError(method, path, res.status, text);
|
|
77
|
+
}
|
|
78
|
+
if (res.status === 204)
|
|
79
|
+
return undefined;
|
|
80
|
+
return (await res.json());
|
|
81
|
+
}
|
|
82
|
+
async getOrg(orgId) {
|
|
83
|
+
return this.request("GET", `/api/v1/orgs/${encodeURIComponent(orgId)}`);
|
|
84
|
+
}
|
|
85
|
+
async createOrg(opts) {
|
|
86
|
+
return this.request("POST", "/api/v1/orgs", {
|
|
87
|
+
display_name: opts.display_name,
|
|
88
|
+
subnet_id: opts.subnet_id,
|
|
89
|
+
join_policy: opts.join_policy ?? "open",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async createWork(orgId, opts) {
|
|
93
|
+
const body = { title: opts.title };
|
|
94
|
+
if (opts.assignee_agent_id != null && opts.assignee_agent_id !== "") {
|
|
95
|
+
body.assignee_agent_id = opts.assignee_agent_id;
|
|
96
|
+
}
|
|
97
|
+
return this.request("POST", `/api/v1/orgs/${encodeURIComponent(orgId)}/work`, body);
|
|
98
|
+
}
|
|
99
|
+
async updateWorkStatus(orgId, workId, opts) {
|
|
100
|
+
const body = { status: opts.status };
|
|
101
|
+
if (opts.assignee_agent_id != null && opts.assignee_agent_id !== "") {
|
|
102
|
+
body.assignee_agent_id = opts.assignee_agent_id;
|
|
103
|
+
}
|
|
104
|
+
return this.request("PATCH", `/api/v1/orgs/${encodeURIComponent(orgId)}/work/${encodeURIComponent(workId)}`, body);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Prefer fencing.subnet_id, fall back to top-level subnet_id. */
|
|
108
|
+
export function orgSubnetId(org) {
|
|
109
|
+
return org.fencing?.subnet_id || org.subnet_id || undefined;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=org-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-api.js","sourceRoot":"","sources":["../../src/lib/org-api.ts"],"names":[],"mappings":"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"}
|
package/dist/manifest.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AASzE,QAAA,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AASzE,QAAA,MAAM,QAAQ,EAAE,yBAmHf,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
package/dist/manifest.js
CHANGED
|
@@ -4,7 +4,7 @@ const manifest = {
|
|
|
4
4
|
apiVersion: 1,
|
|
5
5
|
version: PLUGIN_VERSION,
|
|
6
6
|
displayName: "ACN — Agent Collaboration Network",
|
|
7
|
-
description: "Connect Paperclip to ACN:
|
|
7
|
+
description: "Connect Paperclip to ACN Org Harness: issues → Org work, identity/fencing via subnet, optional legacy Task mirror inbound.",
|
|
8
8
|
author: "acnlabs",
|
|
9
9
|
categories: ["connector", "automation"],
|
|
10
10
|
entrypoints: {
|
|
@@ -34,8 +34,8 @@ const manifest = {
|
|
|
34
34
|
acnBaseUrl: {
|
|
35
35
|
type: "string",
|
|
36
36
|
title: "ACN Base URL",
|
|
37
|
-
default: "https://
|
|
38
|
-
description: "Base URL of the ACN instance (no trailing slash).",
|
|
37
|
+
default: "https://api.acnlabs.dev",
|
|
38
|
+
description: "Base URL of the ACN instance (no trailing slash). Defaults to ACN Labs' hosted production ACN — point at your own deployment to self-host.",
|
|
39
39
|
},
|
|
40
40
|
paperclipBaseUrl: {
|
|
41
41
|
type: "string",
|
|
@@ -55,30 +55,37 @@ const manifest = {
|
|
|
55
55
|
default: "",
|
|
56
56
|
description: "Secret reference to the shared HMAC-SHA256 secret used to sign and verify ACN harness webhook deliveries (X-ACN-Signature). Leave blank to skip verification (NOT recommended in production).",
|
|
57
57
|
},
|
|
58
|
+
acnOrgId: {
|
|
59
|
+
type: "string",
|
|
60
|
+
title: "ACN Org ID",
|
|
61
|
+
default: "",
|
|
62
|
+
description: "Existing Org Harness org_id (org_…). If empty, the plugin creates one bound to ACN Subnet ID on first setup and stores it in plugin state.",
|
|
63
|
+
},
|
|
58
64
|
acnSubnetId: {
|
|
59
65
|
type: "string",
|
|
60
66
|
title: "ACN Subnet ID",
|
|
61
67
|
default: "",
|
|
62
|
-
description: "
|
|
68
|
+
description: "Fence subnet for harness webhooks. Required when ACN Org ID is empty (used to create/bind the Org). Prefer the Org's fence subnet.",
|
|
63
69
|
},
|
|
64
70
|
autoCreateIssues: {
|
|
65
71
|
type: "boolean",
|
|
66
|
-
title: "Auto-create Paperclip issues for new ACN tasks",
|
|
72
|
+
title: "Auto-create Paperclip issues for new ACN tasks (legacy)",
|
|
67
73
|
default: true,
|
|
74
|
+
description: "Inbound task.* → Issue mirror. Outbound Issue create now writes Org work (not Task Pool).",
|
|
68
75
|
},
|
|
69
76
|
autoApproveOnDone: {
|
|
70
77
|
type: "boolean",
|
|
71
|
-
title: "
|
|
78
|
+
title: "Sync 'done' to ACN when Paperclip issue completes",
|
|
72
79
|
default: false,
|
|
73
|
-
description: "When
|
|
80
|
+
description: "When true: Org-mapped issues PATCH work status to done; legacy Task-mirrored issues call /review approve. Cancelled always syncs.",
|
|
74
81
|
},
|
|
75
82
|
},
|
|
76
83
|
},
|
|
77
84
|
webhooks: [
|
|
78
85
|
{
|
|
79
86
|
endpointKey: WEBHOOK_KEYS.acnEvents,
|
|
80
|
-
displayName: "ACN
|
|
81
|
-
description: "Receives HMAC-signed lifecycle events from ACN (
|
|
87
|
+
displayName: "ACN Harness Events",
|
|
88
|
+
description: "Receives HMAC-signed lifecycle events from ACN (org.work_* / org.loop_tick preferred; task.* legacy).",
|
|
82
89
|
},
|
|
83
90
|
],
|
|
84
91
|
ui: {
|
package/dist/manifest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,cAAc,EACd,QAAQ,EACR,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,MAAM,QAAQ,GAA8B;IAC1C,EAAE,EAAE,SAAS;IACb,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,cAAc;IACvB,WAAW,EAAE,mCAAmC;IAChD,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,cAAc,EACd,QAAQ,EACR,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,MAAM,QAAQ,GAA8B;IAC1C,EAAE,EAAE,SAAS;IACb,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,cAAc;IACvB,WAAW,EAAE,mCAAmC;IAChD,WAAW,EACT,4HAA4H;IAC9H,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;IAEvC,WAAW,EAAE;QACX,MAAM,EAAE,gBAAgB;QACxB,EAAE,EAAE,SAAS;KACd;IAED,YAAY,EAAE;QACZ,gBAAgB;QAChB,aAAa;QACb,eAAe;QACf,eAAe;QACf,qBAAqB;QACrB,uBAAuB;QACvB,aAAa;QACb,kBAAkB;QAClB,kBAAkB;QAClB,eAAe;QACf,kBAAkB;QAClB,mBAAmB;QACnB,oBAAoB;QACpB,uBAAuB;QACvB,4BAA4B;KAC7B;IAED,oBAAoB,EAAE;QACpB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,cAAc;gBACrB,OAAO,EAAE,yBAAyB;gBAClC,WAAW,EACT,4IAA4I;aAC/I;YACD,gBAAgB,EAAE;gBAChB,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,oBAAoB;gBAC3B,OAAO,EAAE,EAAE;gBACX,WAAW,EACT,4HAA4H;aAC/H;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,0BAA0B;gBACjC,OAAO,EAAE,EAAE;gBACX,WAAW,EACT,oFAAoF;aACvF;YACD,mBAAmB,EAAE;gBACnB,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,yCAAyC;gBAChD,OAAO,EAAE,EAAE;gBACX,WAAW,EACT,+LAA+L;aAClM;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,YAAY;gBACnB,OAAO,EAAE,EAAE;gBACX,WAAW,EACT,4IAA4I;aAC/I;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,eAAe;gBACtB,OAAO,EAAE,EAAE;gBACX,WAAW,EACT,oIAAoI;aACvI;YACD,gBAAgB,EAAE;gBAChB,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,yDAAyD;gBAChE,OAAO,EAAE,IAAI;gBACb,WAAW,EACT,2FAA2F;aAC9F;YACD,iBAAiB,EAAE;gBACjB,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,mDAAmD;gBAC1D,OAAO,EAAE,KAAK;gBACd,WAAW,EACT,mIAAmI;aACtI;SACF;KACF;IAED,QAAQ,EAAE;QACR;YACE,WAAW,EAAE,YAAY,CAAC,SAAS;YACnC,WAAW,EAAE,oBAAoB;YACjC,WAAW,EACT,uGAAuG;SAC1G;KACF;IAED,EAAE,EAAE;QACF,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,WAAW;gBACjB,EAAE,EAAE,QAAQ,CAAC,QAAQ;gBACrB,WAAW,EAAE,KAAK;gBAClB,UAAU,EAAE,YAAY,CAAC,QAAQ;gBACjC,WAAW,EAAE,CAAC,OAAO,CAAC;aACvB;SACF;KACF;CACF,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { type PluginDetailTabProps } from "@paperclipai/plugin-sdk/ui";
|
|
2
2
|
export interface AcnTaskInfo {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/** Org Harness work path vs legacy Task Pool mirror. */
|
|
4
|
+
source?: "org_work" | "task_pool";
|
|
5
|
+
work_id?: string | null;
|
|
6
|
+
org_id?: string | null;
|
|
7
|
+
task_id: string | null;
|
|
8
|
+
title: string | null;
|
|
9
|
+
status: string | null;
|
|
6
10
|
/** Decimal string from ACN backend (e.g. "10.00"). */
|
|
7
|
-
reward: string;
|
|
8
|
-
reward_currency: string;
|
|
11
|
+
reward: string | null;
|
|
12
|
+
reward_currency: string | null;
|
|
9
13
|
participations: Array<{
|
|
10
14
|
participation_id: string;
|
|
11
15
|
agent_id: string;
|