Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
af6b32d
feat(observability): add provider OTel spans - cache-hit flag, plugin…
nickyleach Aug 3, 2026
18f391e
feat(ui): add shared workspace concurrency select to workspace policy…
cryppadotta Aug 3, 2026
6a69a3d
refactor(observability): stop writing detailed per-step timing to the…
nickyleach Aug 3, 2026
9b9631b
feat(ui): chat-style tasks polish — rich-text composer, attachment ch…
scotttong Aug 3, 2026
8e7f1c0
feat(decisions): improve desk triage and queue parity (#10785)
cryppadotta Aug 4, 2026
2a90933
fix(ui): remove duplicate create-task loading status (#10756)
cryppadotta Aug 4, 2026
76f4420
fix(ui): follow managed sign-out redirects
cryppadotta Aug 4, 2026
aa6b6bc
chore(lockfile): refresh pnpm-lock.yaml (#10787)
github-actions[bot] Aug 4, 2026
bd7a13e
fix(daytona): replace bwrap user-namespace with su privilege drop (#1…
nickyleach Aug 4, 2026
2ab797d
fix(sandbox): reset step store for long-lived bridge work (#10813)
nickyleach Aug 4, 2026
cb52f0b
db: env-configurable client options; parallelize attention feed queri…
devinfoley Aug 4, 2026
dfcda67
feat(auth): default-open visible issue writes (#10804)
cryppadotta Aug 4, 2026
ca6416d
fix(server): preserve hot-restart shutdown snapshots (#10815)
cryppadotta Aug 4, 2026
f0b06d2
feat(claude): environment-aware test-environment probe and claude-loc…
devinfoley Aug 4, 2026
ded813a
feat(interactions): add governed agent addressees (#10252)
cryppadotta Aug 4, 2026
f91a6e2
feat(issues): contain cross-issue agent side effects (#10837)
cryppadotta Aug 4, 2026
678728f
feat: maintained in_review review-path contract + stalled-review acti…
cryppadotta Aug 4, 2026
74416e9
fix(server): render company-export YAML iteratively to stop stack ove…
nickyleach Aug 4, 2026
c647b8c
feat(acpx-engine): give sandbox.exec spans real parents (#10852)
nickyleach Aug 4, 2026
7e592c3
feat(codex): add identity-keyed host credential cache (#10853)
nickyleach Aug 4, 2026
7cff943
chore(ui): remove deprecated baseUrl from ui/tsconfig.json (#4067)
sparkeros Aug 4, 2026
2495e29
Preserve company display names in cloud tenants (#10845)
cryppadotta Aug 5, 2026
2ebc236
fix(server): accept parentIssueId alias in GET /issues (#4032)
scokeepa Aug 5, 2026
d114c49
feat(observability): give sandbox sync spans true wall-clock width (#…
nickyleach Aug 5, 2026
3f86508
docs: replace broken README Discord badge (#1727)
noahrasheta Aug 5, 2026
1f7b710
docs: expand AGENTS.md repo map (cli, skills-catalog, teams-catalog, …
santhiprakash Aug 5, 2026
1e44e50
docs: remove leaked fork-specific section from AGENTS.md (#9935)
santhiprakash Aug 5, 2026
5858ccb
feat: make in-app features cloud-aware (#10850)
cryppadotta Aug 5, 2026
e8ae528
feat(issues): explain cross-task agent writes with attribution, audit…
cryppadotta Aug 5, 2026
f0ed524
fix(ui): prefix audit board route (#10830)
cryppadotta Aug 5, 2026
68ddd6a
feat(activity): add two-tier all-actors audit feed (#10831)
cryppadotta Aug 5, 2026
8142e54
feat(activity): merge the audit page into one rich Activity page (#10…
cryppadotta Aug 5, 2026
c54936e
fix(openclaw-gateway): use per-agent claimedApiKeyPath in wake text (…
jooneyp Aug 5, 2026
ef33c1d
fix(decisions): retire completed-target decisions and link targets fr…
cryppadotta Aug 5, 2026
6ffe9df
fix(auth): clarify protected-agent assignment blocks (#10893)
cryppadotta Aug 5, 2026
14d7558
Remove decision and review summaries from issue headers (#10891)
cryppadotta Aug 5, 2026
1fa36be
fix(ui): use HTTP-safe clipboard copy everywhere (#10875)
cryppadotta Aug 5, 2026
ffd62a4
fix(adapter-utils): carry the workspace origin remote into transporte…
devinfoley Aug 5, 2026
8ac2526
chore(plugin-daytona): pin @daytonaio/sdk to 0.203.0 (#10907)
nickyleach Aug 5, 2026
5888cbf
fix(issues): restore checkout after accepted confirmations (#10909)
cryppadotta Aug 5, 2026
427509e
fix(ui): show the synced company logo on the Cloud org switcher trigg…
cryppadotta Aug 5, 2026
c2b41bb
fix(issues): quiet missing-disposition warnings while a live continua…
cryppadotta Aug 5, 2026
72b509c
Recognize delivered workspaces and reap terminal worktrees (#10908)
cryppadotta Aug 5, 2026
b6e5801
ci: split serialized tests into five shards (#10923)
devinfoley Aug 5, 2026
00a24d7
ci: split general-server tests into five shards with refreshed durati…
devinfoley Aug 5, 2026
b1b7a9d
feat(settings): alphabetize experimental cards and drop the Experimen…
scotttong Aug 6, 2026
f5e9ca3
fix(adapters): keep user-scoped env bindings on the agent Test action…
nickyleach Aug 6, 2026
ac3b2e1
fix(ui): use cloud logout for managed sign-out (#10937)
cryppadotta Aug 6, 2026
dc71fef
feat(ui): show task identifier in task-detail breadcrumb header (#10933)
scotttong Aug 6, 2026
f950952
fix: reliably show plans in the Plan pane and restore sticky plan con…
scotttong Aug 6, 2026
e43f187
feat(secrets): add human-approved secret proposals (#9934)
cryppadotta Aug 6, 2026
5b62a38
feat(settings): add experimental Simplified English Interactions flag…
cryppadotta Aug 6, 2026
f554d67
fix(server): add explicit review verdict policies (#10931)
cryppadotta Aug 6, 2026
814cb33
feat(server): allow agents to resolve review confirmations (#10939)
cryppadotta Aug 6, 2026
2ea22d6
fix(ui): white text on light-mode user chat bubbles (#10952)
scotttong Aug 6, 2026
e591e75
perf(db): index context_snapshot/payload issueId lookups used by reco…
cryppadotta Aug 6, 2026
656ecfa
fix(server): keep Date fields intact through secret redaction; harden…
cryppadotta Aug 6, 2026
52b8741
perf(server): cut steady-state DB hot paths in dashboard, attention, …
cryppadotta Aug 6, 2026
f258b34
fix(ui): unify cloud-managed sign-out (#10994)
cryppadotta Aug 6, 2026
75acc46
feat(sandbox-providers): pre-fill environment form with default sizin…
devinfoley Aug 6, 2026
d84c5ea
feat(ui): hide task priority from the UI (keep data model) (#11024)
scotttong Aug 6, 2026
cfed36e
feat(plugin-daytona): persistent session model with plain command dis…
nickyleach Aug 7, 2026
ea83c5c
feat(task-chat): bring back copy/👍/👎 actions on the agent bubble foot…
scotttong Aug 7, 2026
03cfad7
feat(apps): connect Notion through MCP OAuth (#11009)
cryppadotta Aug 7, 2026
9ace548
feat(observability): rename sandbox provider spans and add run-time w…
nickyleach Aug 7, 2026
35132af
fix(config): preserve extensions and guard invalid repairs (#11005)
cryppadotta Aug 7, 2026
f6c6452
fix(server): preserve managed environment drift on boot (#10979)
cryppadotta Aug 7, 2026
5da382f
feat(skills): require explicit merge modes (#10978)
cryppadotta Aug 7, 2026
9485ffe
fix(config): preserve env files during managed updates (#10980)
cryppadotta Aug 7, 2026
4e76227
feat(plugin-daytona): stream session command logs behind useLogStream…
nickyleach Aug 7, 2026
b67c512
feat(ui): live run label → run detail, running row → task detail (#11…
scotttong Aug 7, 2026
11e5665
feat(ui): port onboarding flow from prototype; add cloud + local vari…
tonio-alucema Aug 7, 2026
4683f26
chore(lockfile): refresh pnpm-lock.yaml (#11036)
github-actions[bot] Aug 7, 2026
01b51dc
fix(runtime): stop Live badge and Working shimmer after task teardown…
nickyleach Aug 7, 2026
9abb600
docs(connections): MCP-direct/DCR playbook section + Notion dry-run a…
cryppadotta Aug 7, 2026
42c7356
fix(heartbeat): backfill projectWorkspaceId when restoring a reused e…
nguyenm7 Aug 7, 2026
b18b0fc
feat: refine app connections and legacy worktree startup (#11040)
cryppadotta Aug 7, 2026
3435920
docs: minimize plan task graphs (#11057)
cryppadotta Aug 7, 2026
a71b9cf
feat(skills): add MCP integration preparation skill (#11063)
cryppadotta Aug 7, 2026
0a511ed
feat(apps): support multiple provider connections (#11060)
cryppadotta Aug 7, 2026
6b7e081
feat(acp): stream Daytona sandbox agent output and remove the host ou…
nickyleach Aug 7, 2026
384e5f6
revert(ui): back out onboarding port (#10786) (#11067)
tonio-alucema Aug 7, 2026
6772423
chore(lockfile): refresh pnpm-lock.yaml (#11068)
github-actions[bot] Aug 7, 2026
d5208d3
feat(adapter-utils): add host-side pack span to managed-runtime tarba…
nickyleach Aug 8, 2026
1791979
refactor(a11y): add ARIA progressbar attributes to BudgetPolicyCard (…
bluzername Aug 8, 2026
34fe57a
fix(server): ignore sibling worktrees in dev watch (#11074)
scotttong Aug 8, 2026
4e9a78d
feat(ui): persist task chat composer drafts (#11076)
scotttong Aug 8, 2026
cc35c3c
feat: structure and humanize recovery notices (#11075)
scotttong Aug 8, 2026
19be4cf
refactor(a11y): add scope=col to the agent costs table headers (#1789)
bluzername Aug 8, 2026
ebf2b8f
fix(server): persist worktree runtime port when ambient PORT does not…
manavshrivastavagit Aug 9, 2026
6a4e2e1
fix(routes): return 409 for routine checkout conflicts (#3790)
LeonSGP43 Aug 10, 2026
13ce2f9
Merge remote-tracking branch 'upstream/master' into sync/upstream-202…
Aug 10, 2026
0370ee6
chore: sync fork with upstream/master, and let a sync PR through the …
Aug 10, 2026
36234b0
ci: upstream's review bot cannot run on a fork
Aug 10, 2026
ef030ee
fix(docker): cover the fork's plugins in the deps stage
Aug 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .github/workflows/commitperclip-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ permissions:

jobs:
review:
# Upstream's review bot, and only upstream can run it. Dependency Review needs
# Advanced Security, which a private fork does not have, and the token step needs
# `COMMITPERCLIP_KEY` — upstream's GitHub App, not a secret a fork can hold. On the
# fork this job could only ever fail, so it is scoped to the repository that owns it.
if: github.repository == 'paperclipai/paperclip'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
Expand Down
59 changes: 39 additions & 20 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,17 @@ jobs:
- name: Block manual lockfile edits
if: >-
github.head_ref != 'chore/refresh-lockfile' &&
!startsWith(github.head_ref, 'sync/upstream-') &&
github.event.pull_request.user.login != 'dependabot[bot]'
run: |
# Diff the PR branch against its merge base so recent base-branch commits
# do not masquerade as changes made by the PR itself.
#
# `sync/upstream-*` is exempt: those PRs merge upstream/master into the
# fork's integration branch, so upstream's own lockfile arrives with the
# merge. Blocking it would make an upstream sync unmergeable. The property
# that matters — the committed lockfile agrees with the manifests — is
# still enforced downstream by `pnpm install --frozen-lockfile`.
changed="$(git diff --name-only "${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}")"
if printf '%s\n' "$changed" | grep -qx 'pnpm-lock.yaml'; then
echo "Do not commit pnpm-lock.yaml in pull requests. CI owns lockfile updates."
Expand Down Expand Up @@ -151,26 +158,31 @@ jobs:
include:
# The server suite is pinned to maxWorkers=1 (server/vitest.config.ts),
# so it can only be parallelized across runners. Shard it to keep this
# lane off the PR critical path. Four shards because the suite has
# grown to ~880s of serial vitest wall time (run 30723165356,
# 2026-08-01): at three shards the worst shard ran 313s and was the
# slowest check in the whole PR run; four brings each shard to ~220s.
# lane off the PR critical path. Five shards because the suite has
# grown to ~946s of serial vitest wall time (run 30930345729,
# 2026-08-04): at four shards the worst shard ran 311s and was the
# slowest check in the whole PR run; five brings each shard to ~196s
# of suite time (~240s job), level with the other ~250-300s lanes.
- group: general-server
group_label: server (1/4)
group_label: server (1/5)
shard_index: 0
shard_count: 4
shard_count: 5
- group: general-server
group_label: server (2/4)
group_label: server (2/5)
shard_index: 1
shard_count: 4
shard_count: 5
- group: general-server
group_label: server (3/4)
group_label: server (3/5)
shard_index: 2
shard_count: 4
shard_count: 5
- group: general-server
group_label: server (4/4)
group_label: server (4/5)
shard_index: 3
shard_count: 4
shard_count: 5
- group: general-server
group_label: server (5/5)
shard_index: 4
shard_count: 5
- group: general-workspaces-a
group_label: workspaces-a
- group: general-workspaces-b
Expand Down Expand Up @@ -272,18 +284,25 @@ jobs:
fail-fast: false
matrix:
include:
# A successful PR run on 2026-08-04 (30876682788) spent 256s in
# serialized shard 2/4, making its 305s job the run's slowest check.
# Five shards reduce the measured 739s suite total to about 148s per
# runner before setup overhead.
- shard_index: 0
shard_count: 4
shard_label: 1/4
shard_count: 5
shard_label: 1/5
- shard_index: 1
shard_count: 4
shard_label: 2/4
shard_count: 5
shard_label: 2/5
- shard_index: 2
shard_count: 4
shard_label: 3/4
shard_count: 5
shard_label: 3/5
- shard_index: 3
shard_count: 4
shard_label: 4/4
shard_count: 5
shard_label: 4/5
- shard_index: 4
shard_count: 5
shard_label: 5/5

steps:
- name: Checkout repository
Expand Down
19 changes: 11 additions & 8 deletions .github/workflows/release-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,20 @@ jobs:
matrix:
include:
- shard_index: 0
shard_count: 4
shard_label: 1/4
shard_count: 5
shard_label: 1/5
- shard_index: 1
shard_count: 4
shard_label: 2/4
shard_count: 5
shard_label: 2/5
- shard_index: 2
shard_count: 4
shard_label: 3/4
shard_count: 5
shard_label: 3/5
- shard_index: 3
shard_count: 4
shard_label: 4/4
shard_count: 5
shard_label: 4/5
- shard_index: 4
shard_count: 5
shard_label: 5/5

steps:
- name: Checkout repository
Expand Down
46 changes: 4 additions & 42 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ Before making changes, read in this order:
- `packages/adapters/`: agent adapter implementations (Claude, Codex, Cursor, etc.)
- `packages/adapter-utils/`: shared adapter utilities
- `packages/plugins/`: plugin system packages
- `packages/skills-catalog/`: app-shipped skills catalog (`@paperclipai/skills-catalog`)
- `packages/teams-catalog/`: app-shipped teams catalog (`@paperclipai/teams-catalog`)
- `cli/`: `paperclipai` CLI package (published bin, agent-facing commands)
- `skills/`: Paperclip runtime/operational skills (not part of the app catalog)
- `doc/`: operational and product docs

## 4. Dev Setup (Auto DB)
Expand Down Expand Up @@ -179,48 +183,6 @@ A change is done when all are true:
4. Docs updated when behavior or commands change
5. PR description follows the [PR template](.github/PULL_REQUEST_TEMPLATE.md) with all sections filled in (including Model Used)

## 11. Fork-Specific: HenkDz/paperclip

This is a fork of `paperclipai/paperclip` with QoL patches and a **built-in** Hermes adapter story on branch `feat/externalize-hermes-adapter` ([tree](https://github.com/HenkDz/paperclip/tree/feat/externalize-hermes-adapter)).

### Branch Strategy

- `feat/externalize-hermes-adapter` now ships `hermes_local` and `hermes_gateway` as built-in core adapters.
- Older fork branches may still document plugin-only Hermes; treat this file as authoritative for the current branch.

### Hermes (built-in)

- `hermes_local` is available without Adapter manager installation and runs the local Hermes CLI.
- `hermes_gateway` is available without Adapter manager installation and calls an already-running Hermes API server.
- Operators may still install external Hermes packages through Adapter manager to override/shadow the built-ins.
- Optional: `file:` entry in `~/.paperclip/adapter-plugins.json` remains useful for local development of override packages.

### Local Dev

- Fork runs on port 3101+ (auto-detects if 3100 is taken by upstream instance)
- `npx vite build` hangs on NTFS — use `node node_modules/vite/bin/vite.js build` instead
- Server startup from NTFS takes 30-60s — don't assume failure immediately
- Kill ALL paperclip processes before starting: `pkill -f "paperclip"; pkill -f "tsx.*index.ts"`
- Vite cache survives `rm -rf dist` — delete both: `rm -rf ui/dist ui/node_modules/.vite`

### Fork QoL Patches (not in upstream)

These are local modifications in the fork's UI. If re-copying source, these must be re-applied:

1. **stderr_group** — amber accordion for MCP init noise in `RunTranscriptView.tsx`
2. **tool_group** — accordion for consecutive non-terminal tools (write, read, search, browser)
3. **Dashboard excerpt** — `LatestRunCard` strips markdown, shows first 3 lines/280 chars

### Plugin System

PR #2218 (`feat/external-adapter-phase1`) adds external adapter support. See root `AGENTS.md` for full details.

- Adapters can be loaded as external plugins via `~/.paperclip/adapter-plugins.json`
- The plugin-loader should have ZERO hardcoded adapter imports — pure dynamic loading
- `createServerAdapter()` must include ALL optional fields (especially `detectModel`)
- Built-in UI adapters can shadow external plugin parsers; external override pause/resume should restore the built-in parser.
- Reference external adapters: Droid (npm); Hermes can also be tested as an override package.

## Design system

`DESIGN.md` at the repo root is the source of truth for UI design decisions. The token-only rule applies to all `ui/` changes: every color, spacing, radius, type, shadow, and motion value in `ui/src/components/**` and `ui/src/pages/**` comes from the token layer in `ui/src/index.css` — no hex, raw px, arbitrary Tailwind bracket values, or raw `font-size`/`fontSize` declarations in components, outside the documented allowlist in `ui/src/index.css`. Run `pnpm check:token-gates` (`scripts/check-token-gates.mjs`) before committing UI changes — it fails on any violation not covered by that allowlist.
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ COPY --parents packages/plugins/sandbox-providers/./*/package.json packages/plug
COPY packages/plugins/paperclip-plugin-fake-sandbox/package.json packages/plugins/paperclip-plugin-fake-sandbox/
COPY packages/plugins/plugin-llm-wiki/package.json packages/plugins/plugin-llm-wiki/
COPY packages/plugins/plugin-workspace-diff/package.json packages/plugins/plugin-workspace-diff/
# Fork plugins.
COPY packages/plugins/paperclip-plugin-escalation/package.json packages/plugins/paperclip-plugin-escalation/
COPY packages/plugins/paperclip-plugin-github-mirror/package.json packages/plugins/paperclip-plugin-github-mirror/
COPY packages/plugins/paperclip-plugin-run-completion/package.json packages/plugins/paperclip-plugin-run-completion/
COPY packages/plugins/paperclip-plugin-telegram-notify/package.json packages/plugins/paperclip-plugin-telegram-notify/
COPY patches/ patches/
COPY scripts/link-plugin-dev-sdk.mjs scripts/

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<a href="https://github.com/paperclipai/paperclip/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License" /></a>
<a href="https://github.com/paperclipai/paperclip/stargazers"><img src="https://img.shields.io/github/stars/paperclipai/paperclip?style=flat" alt="Stars" /></a>
<a href="https://www.star-history.com/paperclipai/paperclip"><img src="https://api.star-history.com/badge?repo=paperclipai/paperclip" alt="Star History Rank" /></a>
<a href="https://discord.gg/m4HZY7xNG3"><img src="https://img.shields.io/discord/000000000?label=discord" alt="Discord" /></a>
<a href="https://discord.gg/m4HZY7xNG3"><img src="https://img.shields.io/badge/discord-join-7289da" alt="Discord" /></a>
</p>

<br/>
Expand Down
58 changes: 58 additions & 0 deletions cli/src/__tests__/agent-jwt-env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,62 @@ describe("agent jwt env helpers", () => {
expect(contents).toContain('PAPERCLIP_WORKTREE_COLOR="#439edb"');
expect(readPaperclipEnvEntries(envPath).PAPERCLIP_WORKTREE_COLOR).toBe("#439edb");
});

it("preserves operator content and CRLF while updating only managed entries", () => {
const configPath = tempConfigPath();
const envPath = resolveAgentJwtEnvFile(configPath);
const original = [
"# operator comment",
"DATABASE_URL='postgres://operator:encoded@localhost/paperclip'",
"",
"export PAPERCLIP_HOME = '/old path' # managed path",
"PAPERCLIP_DUPLICATE=stale",
'PAPERCLIP_DUPLICATE="current"',
"UNKNOWN_VALUE=operator-owned",
"",
].join("\r\n");
fs.writeFileSync(envPath, original, { mode: 0o600 });

mergePaperclipEnvEntries(
{
PAPERCLIP_HOME: "/new path",
PAPERCLIP_DUPLICATE: "current",
PAPERCLIP_WORKTREE_COLOR: "#439edb",
DATABASE_URL: "postgres://paperclip-must-not-overwrite",
},
envPath,
);

const updated = fs.readFileSync(envPath, "utf8");
expect(updated).toBe([
"# operator comment",
"DATABASE_URL='postgres://operator:encoded@localhost/paperclip'",
"",
'export PAPERCLIP_HOME = "/new path" # managed path',
"PAPERCLIP_DUPLICATE=current",
'PAPERCLIP_DUPLICATE="current"',
"UNKNOWN_VALUE=operator-owned",
'PAPERCLIP_WORKTREE_COLOR="#439edb"',
"",
].join("\r\n"));
expect(updated.replaceAll("\r\n", "")).not.toContain("\n");
});

it("does not replace the env file when managed values are already current", () => {
const configPath = tempConfigPath();
const envPath = resolveAgentJwtEnvFile(configPath);
const original = [
"# preserve this file byte-for-byte",
"export PAPERCLIP_HOME = '/same path'",
"UNKNOWN=\"operator encoding\"",
"",
].join("\n");
fs.writeFileSync(envPath, original, { mode: 0o600 });
const previousInode = fs.statSync(envPath).ino;

mergePaperclipEnvEntries({ PAPERCLIP_HOME: "/same path" }, envPath);

expect(fs.readFileSync(envPath, "utf8")).toBe(original);
expect(fs.statSync(envPath).ino).toBe(previousInode);
});
});
10 changes: 9 additions & 1 deletion cli/src/__tests__/agent-lifecycle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,15 @@ describe("agent lifecycle commands", () => {
await run(["agent", "runtime-state:reset-session", AGENT_ID, "--task-key", "task-1"]);
await run(["agent", "task-sessions", AGENT_ID]);
await run(["agent", "skills", AGENT_ID]);
await run(["agent", "skills:sync", AGENT_ID, "--desired-skills", "paperclip,github"]);
await run([
"agent",
"skills:sync",
AGENT_ID,
"--desired-skills",
"paperclip,github",
"--mode",
"replace",
]);
await run(["agent", "instructions-path:update", AGENT_ID, "--payload-json", JSON.stringify({ path: "/tmp/AGENTS.md" })]);
await run(["agent", "instructions-bundle", AGENT_ID]);
await run(["agent", "instructions-bundle:update", AGENT_ID, "--payload-json", JSON.stringify({ mode: "managed" })]);
Expand Down
1 change: 1 addition & 0 deletions cli/src/__tests__/company-delete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function makeCompany(overrides: Partial<Company>): Company {
createdAt: new Date(),
updatedAt: new Date(),
...overrides,
interactionResolverGovernance: overrides.interactionResolverGovernance ?? {},
};
}

Expand Down
13 changes: 13 additions & 0 deletions cli/src/__tests__/company.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,17 @@ describe("renderCompanyImportResult", () => {
{ slug: "cto", id: "agent-2", action: "updated", name: "CTO", reason: "replace strategy" },
{ slug: "ops", id: null, action: "skipped", name: "Ops", reason: "skip strategy" },
],
skills: [
{
originalKey: "company/source/review",
originalSlug: "review",
key: "company/target/review-2",
slug: "review-2",
id: "skill-1",
action: "renamed",
reason: "rename strategy",
},
],
projects: [
{ slug: "app", id: "project-1", action: "created", name: "App", reason: null },
{ slug: "ops", id: "project-2", action: "updated", name: "Operations", reason: "replace strategy" },
Expand All @@ -525,8 +536,10 @@ describe("renderCompanyImportResult", () => {
expect(rendered).toContain("Company");
expect(rendered).toContain("https://paperclip.example/PAP/dashboard");
expect(rendered).toContain("3 agents total (1 created, 1 updated, 1 skipped)");
expect(rendered).toContain("1 skill total (1 renamed)");
expect(rendered).toContain("3 projects total (1 created, 1 updated, 1 skipped)");
expect(rendered).toContain("Agent results");
expect(rendered).toContain("Skill results");
expect(rendered).toContain("Project results");
expect(rendered).toContain("Using claude-local adapter");
expect(rendered).toContain("Review API keys");
Expand Down
Loading
Loading