diff --git a/README.md b/README.md index 5541a858b8..cea39e55c8 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ It looks like a task manager. Under the hood: org charts, budgets, governance, g ## Paperclip is right for you if -- ✅ You want to build **autonomous AI companies** +- ✅ You want to build **autonomous AI organizations** - ✅ You **coordinate many different agents** (OpenClaw, Codex, Claude, Cursor) toward a common goal - ✅ You have **20 simultaneous Claude Code terminals** open and lose track of what everyone is doing - ✅ You want agents running **autonomously 24/7**, but still want to audit work and chime in when needed @@ -106,7 +106,7 @@ Any agent, any runtime, one org chart. If it can receive a heartbeat, it's hired

🎯 Goal Alignment

-Every task traces back to the company mission. Agents know what to do and why. +Every task traces back to the organization mission. Agents know what to do and why.

💓 Heartbeats

@@ -119,8 +119,8 @@ Agents wake on a schedule, check work, and act. Delegation flows up and down the Monthly budgets per agent. When they hit the limit, they stop. No runaway costs. -

🏢 Multi-Company

-One deployment, many companies. Complete data isolation. One control plane for your portfolio. +

🏢 Multi-Organization

+One deployment, many organizations. Complete data isolation. One control plane for your portfolio.

🎫 Ticket System

@@ -170,7 +170,7 @@ Paperclip handles the hard orchestration details correctly. | **Governance with rollback.** | Approval gates are enforced, config changes are revisioned, and bad changes can be rolled back safely. | | **Goal-aware execution.** | Tasks carry full goal ancestry so agents consistently see the "why," not just a title. | | **Portable company templates.** | Export/import orgs, agents, and skills with secret scrubbing and collision handling. | -| **True multi-company isolation.** | Every entity is company-scoped, so one deployment can run many companies with separate data and audit trails. | +| **True multi-organization isolation.** | Every entity is company-scoped, so one deployment can run many companies with separate data and audit trails. |
diff --git a/doc/CLI.md b/doc/CLI.md index f01291b299..aa6a0ad616 100644 --- a/doc/CLI.md +++ b/doc/CLI.md @@ -297,7 +297,7 @@ npx paperclipai context set --api-key-env-var-name PAPERCLIP_API_KEY export PAPERCLIP_API_KEY=... ``` -## Company Commands +## Organization Commands ```sh npx paperclipai company list @@ -633,7 +633,7 @@ npx paperclipai skills install paperclipai:optional:browser:agent-browser --comp External GitHub, skills.sh, local-path, and URL sources still go through `skills import`; catalog commands are for the app-shipped catalog only. -### Company library +### Organization library ```sh npx paperclipai skills list --company-id @@ -762,7 +762,7 @@ bootstrap credentials in Paperclip secrets. Per-company provider vaults (multiple vault instances per provider, default vault selection, coming-soon GCP/Vault) can be configured from the board UI under -`Company Settings → Secrets → Provider vaults` or through the provider-config CLI +`Organization Settings → Secrets → Provider vaults` or through the provider-config CLI commands above. See the [secrets deploy guide](../docs/deploy/secrets.md#provider-vaults) and [API reference](../docs/api/secrets.md#provider-vaults) for the contract. diff --git a/docs/deploy/secrets.md b/docs/deploy/secrets.md index c589eacf2c..3823079578 100644 --- a/docs/deploy/secrets.md +++ b/docs/deploy/secrets.md @@ -254,7 +254,7 @@ default provider — no migration is required. ### Where to configure -Open `Company Settings → Secrets` in the board UI and switch to the +Open `Organization Settings → Secrets` in the board UI and switch to the `Provider vaults` tab. From there you can: - Create a vault for any supported provider family. diff --git a/docs/start/core-concepts.md b/docs/start/core-concepts.md index 6709e8a8c2..ad65b6881f 100644 --- a/docs/start/core-concepts.md +++ b/docs/start/core-concepts.md @@ -5,9 +5,9 @@ summary: Companies, agents, issues, delegation, heartbeats, and governance Paperclip organizes autonomous AI work around six key concepts. -## Company +## Organization -A company is the top-level unit of organization. Each company has: +An organization is the top-level unit in Paperclip. Each organization has: - A **goal** — the reason it exists (e.g. "Build the #1 AI note-taking app at $1M MRR") - **Employees** — every employee is an AI agent diff --git a/tests/e2e/conference-room-typing-intro.spec.ts b/tests/e2e/conference-room-typing-intro.spec.ts index b69f9a6a16..0935ebc0a2 100644 --- a/tests/e2e/conference-room-typing-intro.spec.ts +++ b/tests/e2e/conference-room-typing-intro.spec.ts @@ -69,7 +69,7 @@ async function runOnboardingWizard(page: Page, companyName: string) { if (await startBtn.count()) await startBtn.first().click(); // Step 0: front door (skipped when the wizard opens on the create path). - const frontDoor = page.getByText("Build a new company"); + const frontDoor = page.getByText("Build a new organization"); if (await frontDoor.count()) await frontDoor.first().click(); // Step 1: company name. diff --git a/tests/e2e/nux-phase4-screenshots.spec.ts b/tests/e2e/nux-phase4-screenshots.spec.ts index cf3da3e3a6..e18b5a5b8f 100644 --- a/tests/e2e/nux-phase4-screenshots.spec.ts +++ b/tests/e2e/nux-phase4-screenshots.spec.ts @@ -33,7 +33,7 @@ function shot(name: string) { async function openWizard(page: import("@playwright/test").Page) { await page.goto("/onboarding"); - const startBtn = page.getByRole("button", { name: /Start Onboarding|New Company|Add Agent/ }); + const startBtn = page.getByRole("button", { name: /Start Onboarding|New Organization|Add Agent/ }); if (await startBtn.count()) { await startBtn.first().click(); } @@ -61,7 +61,7 @@ test.describe("NUX Phase 4 visual QA", () => { await openWizard(page); // Front door shows when the wizard doesn't open directly on the create // path (e.g. another spec already created a company on this instance). - const createCard = page.getByRole("button", { name: /Build a new company/ }); + const createCard = page.getByRole("button", { name: /Build a new organization/ }); if (await createCard.count()) { await createCard.first().click(); } @@ -101,7 +101,7 @@ test.describe("NUX Phase 4 visual QA", () => { page.getByRole("heading", { name: "Welcome to Paperclip" }), ).toBeVisible({ timeout: 10_000 }); await expect( - page.getByRole("heading", { name: "Build a new company" }), + page.getByRole("heading", { name: "Build a new organization" }), ).toBeVisible(); await expect( page.getByRole("heading", { name: "Add agents to your org" }), @@ -131,7 +131,7 @@ test.describe("NUX Phase 4 visual QA", () => { // Composer renders once a company is selected. (Regression guard for the // Rules-of-Hooks crash that previously blanked this page — see PAP-50.) await expect( - page.getByPlaceholder("Ask anything about your company..."), + page.getByPlaceholder("Ask anything about your organization..."), ).toBeVisible({ timeout: 20_000 }); await page.waitForTimeout(2_000); // let welcome bubble + suggestion chips stage in await page.screenshot({ path: shot("06-board-chat.png") }); diff --git a/tests/e2e/onboarding.spec.ts b/tests/e2e/onboarding.spec.ts index d7819493fd..0755e6aade 100644 --- a/tests/e2e/onboarding.spec.ts +++ b/tests/e2e/onboarding.spec.ts @@ -41,12 +41,12 @@ test.describe("Onboarding wizard", () => { // The wizard may open on a launcher card or directly on the capsule // wizard; the front door (step 0) requires a click into the create path. const startBtn = page.getByRole("button", { - name: /Start Onboarding|New Company|Add Agent/, + name: /Start Onboarding|New Organization|Add Agent/, }); if (await startBtn.count()) { await startBtn.first().click(); } - const createCard = page.getByRole("button", { name: /Build a new company/ }); + const createCard = page.getByRole("button", { name: /Build a new organization/ }); if (await createCard.count()) { await createCard.first().click(); } diff --git a/tests/e2e/planning-mode-visual-verification.spec.ts b/tests/e2e/planning-mode-visual-verification.spec.ts index 1c8978c2e8..d3a69bf1f8 100644 --- a/tests/e2e/planning-mode-visual-verification.spec.ts +++ b/tests/e2e/planning-mode-visual-verification.spec.ts @@ -48,10 +48,10 @@ test("captures planning mode UI for desktop and mobile", async ({ page }) => { }); await page.goto("/onboarding"); - const startBtn = page.getByRole("button", { name: /Start Onboarding|New Company|Add Agent/ }); + const startBtn = page.getByRole("button", { name: /Start Onboarding|New Organization|Add Agent/ }); if (await startBtn.count()) await startBtn.first().click(); - const createCard = page.getByRole("button", { name: /Build a new company/ }); + const createCard = page.getByRole("button", { name: /Build a new organization/ }); if (await createCard.count()) await createCard.first().click(); await expect(page.getByRole("heading", { name: "What is the name of your organization?" })).toBeVisible({ timeout: 15_000 }); diff --git a/ui/src/App.activity-routing.test.tsx b/ui/src/App.activity-routing.test.tsx index 5a7e5ce7de..55eb7abb30 100644 --- a/ui/src/App.activity-routing.test.tsx +++ b/ui/src/App.activity-routing.test.tsx @@ -141,7 +141,7 @@ describe("App Activity routing (PAP-16302)", () => { it("serves the merged Activity page at /:company/activity", async () => { const root = renderAppAt(container, "/PAP/activity"); await waitForRoute(container, "ACTIVITY_PAGE@/PAP/activity"); - expect(container.textContent).not.toContain("No company matches prefix"); + expect(container.textContent).not.toContain("No organization matches prefix"); flushSync(() => root.unmount()); }); @@ -169,7 +169,7 @@ describe("App Activity routing (PAP-16302)", () => { it("redirects the bare /audit deep link through to the prefixed Activity page", async () => { const root = renderAppAt(container, "/audit"); await waitForRoute(container, "ACTIVITY_PAGE@/PAP/activity?mode=agents"); - expect(container.textContent).not.toContain("No company matches prefix"); + expect(container.textContent).not.toContain("No organization matches prefix"); flushSync(() => root.unmount()); }); }); diff --git a/ui/src/App.cases-routing.test.tsx b/ui/src/App.cases-routing.test.tsx index 7a85e81981..dc110a1307 100644 --- a/ui/src/App.cases-routing.test.tsx +++ b/ui/src/App.cases-routing.test.tsx @@ -132,14 +132,14 @@ describe("App Cases routing (PAP-13002)", () => { it("redirects unprefixed /cases to the company-prefixed list page", async () => { const root = await renderAppAt(container, "/cases"); await waitForRoute(container, "CASES_LIST_PAGE"); - expect(container.textContent).not.toContain("No company matches prefix"); + expect(container.textContent).not.toContain("No organization matches prefix"); flushSync(() => root.unmount()); }); it("redirects unprefixed /cases/:id to the company-prefixed detail page", async () => { const root = await renderAppAt(container, "/cases/PAP-C5"); await waitForRoute(container, "CASE_DETAIL_PAGE"); - expect(container.textContent).not.toContain("No company matches prefix"); + expect(container.textContent).not.toContain("No organization matches prefix"); flushSync(() => root.unmount()); }); }); diff --git a/ui/src/App.test.tsx b/ui/src/App.test.tsx index 920f192baf..020c2c0eb2 100644 --- a/ui/src/App.test.tsx +++ b/ui/src/App.test.tsx @@ -115,9 +115,9 @@ describe("CloudAccessGate", () => { }); const root = renderGate(container); - await waitForText(container, "No company access"); + await waitForText(container, "No organization access"); - expect(container.textContent).toContain("No company access"); + expect(container.textContent).toContain("No organization access"); expect(container.textContent).not.toContain("Outlet content"); unmountRoot(root); @@ -141,7 +141,7 @@ describe("CloudAccessGate", () => { await waitForText(container, "Outlet content"); expect(container.textContent).toContain("Outlet content"); - expect(container.textContent).not.toContain("No company access"); + expect(container.textContent).not.toContain("No organization access"); unmountRoot(root); }); diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 4e9d9fcee9..5e6b326c48 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -463,13 +463,13 @@ export function OnboardingRoutePage() { const title = matchedCompany ? `Add another agent to ${matchedCompany.name}` : companies.length > 0 - ? "Create another company" - : "Create your first company"; + ? "Create another organization" + : "Create your first organization"; const description = matchedCompany - ? "Run onboarding again to add an agent and a starter task for this company." + ? "Run onboarding again to add an agent and a starter task for this organization." : companies.length > 0 - ? "Run onboarding again to create another company and seed its first agent." - : "Get started by creating a company and your first agent."; + ? "Run onboarding again to create another organization and seed its first agent." + : "Get started by creating an organization and your first agent."; return (
@@ -588,10 +588,10 @@ function NoCompaniesStartPage() {

- {t("app.noCompanies.title", { defaultValue: "Create your first company" })} + {t("app.noCompanies.title", { defaultValue: "Create your first organization" })}

- {t("app.noCompanies.description", { defaultValue: "Get started by creating a company." })} + {t("app.noCompanies.description", { defaultValue: "Get started by creating an organization." })}

{/* Same as the onboarding route: no Cloud origin means nowhere to @@ -611,7 +611,7 @@ function NoCompaniesStartPage() { : openOnboarding() } > - {t("app.noCompanies.newCompany", { defaultValue: "New Company" })} + {t("app.noCompanies.newCompany", { defaultValue: "New Organization" })} )}
diff --git a/ui/src/adapters/claude-local/config-fields.tsx b/ui/src/adapters/claude-local/config-fields.tsx index ab546ebbb5..d0604b79ab 100644 --- a/ui/src/adapters/claude-local/config-fields.tsx +++ b/ui/src/adapters/claude-local/config-fields.tsx @@ -167,7 +167,7 @@ export function ClaudeLocalAdvancedFields({
{ - if (!selectedCompanyId) throw new Error("Select a company to create secrets"); + if (!selectedCompanyId) throw new Error("Select an organization to create secrets"); return secretsApi.create(selectedCompanyId, input); }, onSuccess: () => { @@ -334,7 +334,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) { const uploadMarkdownImage = useMutation({ mutationFn: async ({ file, namespace }: { file: File; namespace: string }) => { - if (!selectedCompanyId) throw new Error("Select a company to upload images"); + if (!selectedCompanyId) throw new Error("Select an organization to upload images"); return assetsApi.uploadImage(selectedCompanyId, file, namespace); }, }); @@ -711,7 +711,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) { : ["agents", "none", "detect-model", adapterType], queryFn: () => { if (!selectedCompanyId) { - throw new Error("Select a company to detect the model"); + throw new Error("Select an organization to detect the model"); } return agentsApi.detectModel(selectedCompanyId, adapterType); }, @@ -867,7 +867,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) { const testEnvironment = useMutation({ mutationFn: async () => { if (!selectedCompanyId) { - throw new Error("Select a company to test adapter environment"); + throw new Error("Select an organization to test adapter environment"); } const flushedEnv = flushEnvironmentDraft(); const adapterConfigPatch = flushedEnv ? { env: flushedEnv } : undefined; @@ -1052,7 +1052,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) { (!loginNeedsPty || providerSupportsLoginPty); const runEnvironmentTest = useCallback(async () => { if (!selectedCompanyId) { - throw new Error("Select a company to test adapter environment"); + throw new Error("Select an organization to test adapter environment"); } setTestActionPending(true); setTestActionError(null); @@ -1454,7 +1454,7 @@ export function AgentConfigForm(props: AgentConfigFormProps) { ) : (
This instance requires the Kubernetes sandbox, but no managed Kubernetes - environment is available for this company yet. Configure one before creating + environment is available for this organization yet. Configure one before creating agents; execution will not fall back to local.
)} diff --git a/ui/src/components/AppsSidebar.tsx b/ui/src/components/AppsSidebar.tsx index f339f8e9bc..882e969b7a 100644 --- a/ui/src/components/AppsSidebar.tsx +++ b/ui/src/components/AppsSidebar.tsx @@ -57,7 +57,7 @@ export function AppsSidebar() { className="flex items-center gap-1.5 rounded-md px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground" > - {selectedCompany?.name ?? "Company"} + {selectedCompany?.name ?? "Organization"}
diff --git a/ui/src/components/BootstrapPendingPage.tsx b/ui/src/components/BootstrapPendingPage.tsx index 6724a5dff0..b2d4885267 100644 --- a/ui/src/components/BootstrapPendingPage.tsx +++ b/ui/src/components/BootstrapPendingPage.tsx @@ -100,7 +100,7 @@ export function BootstrapPendingPage({

You're the instance admin

- Setup is complete. Taking you to onboarding to create your first company... + Setup is complete. Taking you to onboarding to create your first organization...

diff --git a/ui/src/components/CloudAccessGate.tsx b/ui/src/components/CloudAccessGate.tsx index 960533875a..7b47cb854c 100644 --- a/ui/src/components/CloudAccessGate.tsx +++ b/ui/src/components/CloudAccessGate.tsx @@ -13,13 +13,13 @@ function NoBoardAccessPage() { return (
-

No company access

+

No organization access

- This account is signed in, but it does not have an active company membership or instance-admin access on + This account is signed in, but it does not have an active organization membership or instance-admin access on this Paperclip instance.

- Use a company invite or sign in with an account that already belongs to this org. + Use an organization invite or sign in with an account that already belongs to this org.

diff --git a/ui/src/components/CompanySettingsSidebar.tsx b/ui/src/components/CompanySettingsSidebar.tsx index 2f9e7abaaa..368715fcb4 100644 --- a/ui/src/components/CompanySettingsSidebar.tsx +++ b/ui/src/components/CompanySettingsSidebar.tsx @@ -94,7 +94,7 @@ export function CompanySettingsSidebar() { className="flex items-center gap-1.5 rounded-md px-2 py-1 text-xs text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground" > - {selectedCompany?.name ?? "Company"} + {selectedCompany?.name ?? "Organization"}
diff --git a/ui/src/components/CompanySwitcher.tsx b/ui/src/components/CompanySwitcher.tsx index 9882d53be2..64fbe7d245 100644 --- a/ui/src/components/CompanySwitcher.tsx +++ b/ui/src/components/CompanySwitcher.tsx @@ -50,14 +50,14 @@ export function CompanySwitcher({ open: controlledOpen, onOpenChange }: CompanyS )} - {selectedCompany?.name ?? "Select company"} + {selectedCompany?.name ?? "Select organization"}
- Companies + Organizations {sidebarCompanies.map((company) => ( - Couldn't load companies + Couldn't load organizations { // Keep the menu open so the result of the retry is visible. @@ -88,7 +88,7 @@ export function CompanySwitcher({ open: controlledOpen, onOpenChange }: CompanyS ) : ( - No companies + No organizations ) )} @@ -101,7 +101,7 @@ export function CompanySwitcher({ open: controlledOpen, onOpenChange }: CompanyS - Manage Companies + Manage Organizations diff --git a/ui/src/components/ConfigureBuiltInAgentModal.tsx b/ui/src/components/ConfigureBuiltInAgentModal.tsx index 3931474e47..79e29131f8 100644 --- a/ui/src/components/ConfigureBuiltInAgentModal.tsx +++ b/ui/src/components/ConfigureBuiltInAgentModal.tsx @@ -158,7 +158,7 @@ export function ConfigureBuiltInAgentModal({
Creates {definition.displayName} in your roster, badged{" "} - Built-in. Companies that require hire approval will queue this for the + Built-in. Organizations that require hire approval will queue this for the board. diff --git a/ui/src/components/FeedCard.tsx b/ui/src/components/FeedCard.tsx index 099071969a..614f299b34 100644 --- a/ui/src/components/FeedCard.tsx +++ b/ui/src/components/FeedCard.tsx @@ -115,13 +115,13 @@ function formatVerb( case "goal.deleted": return "deleted goal"; case "company.created": - return "created company"; + return "created organization"; case "company.updated": - return "updated company"; + return "updated organization"; case "company.archived": - return "archived company"; + return "archived organization"; case "company.budget_updated": - return "updated company budget"; + return "updated organization budget"; default: return action.replace(/[._]/g, " "); diff --git a/ui/src/components/FrontDoor.tsx b/ui/src/components/FrontDoor.tsx index 24345fa7f9..9986ed2bdf 100644 --- a/ui/src/components/FrontDoor.tsx +++ b/ui/src/components/FrontDoor.tsx @@ -30,7 +30,7 @@ export function FrontDoor({ onChoose }: FrontDoorProps) {
-

Build a new company

+

Build a new organization

Begin with a mission, bring on a lead agent, and grow a team of agents to do the work.

diff --git a/ui/src/components/InteractionGovernancePanel.tsx b/ui/src/components/InteractionGovernancePanel.tsx index 358a57a8a7..d697b1f094 100644 --- a/ui/src/components/InteractionGovernancePanel.tsx +++ b/ui/src/components/InteractionGovernancePanel.tsx @@ -243,7 +243,7 @@ export function InteractionGovernancePanel({

Thread interactions are open by default:{" "} - Anyone in the company — the + Anyone in the organization — the board or any agent, including the one that asked — can respond. Narrow a kind only when you need to.{" "} Default policy is the diff --git a/ui/src/components/IssueChatThread.test.tsx b/ui/src/components/IssueChatThread.test.tsx index 0fbc3a1a14..757dd7ad94 100644 --- a/ui/src/components/IssueChatThread.test.tsx +++ b/ui/src/components/IssueChatThread.test.tsx @@ -3948,7 +3948,7 @@ describe("IssueAssigneePausedNotice", () => { ); }); - expect(container.textContent).toContain("arrived paused from a company import"); + expect(container.textContent).toContain("arrived paused from an organization import"); const resumeButton = container.querySelector( '[data-testid="issue-assignee-paused-resume"]', ) as HTMLButtonElement | null; diff --git a/ui/src/components/IssueChatThread.tsx b/ui/src/components/IssueChatThread.tsx index 71862484c1..cf4b0baf8e 100644 --- a/ui/src/components/IssueChatThread.tsx +++ b/ui/src/components/IssueChatThread.tsx @@ -644,7 +644,7 @@ export function IssueAssigneePausedNotice({ agent.pauseReason === "budget" ? "It was paused by a budget hard stop." : agent.pauseReason === "import" - ? "It arrived paused from a company import — imported agents stay parked until you resume them." + ? "It arrived paused from an organization import — imported agents stay parked until you resume them." : agent.pauseReason === "system" ? "It was paused by the system." : "It was paused manually."; diff --git a/ui/src/components/IssueThreadInteractionCard.test.tsx b/ui/src/components/IssueThreadInteractionCard.test.tsx index 3995a58cdf..2b27093e8f 100644 --- a/ui/src/components/IssueThreadInteractionCard.test.tsx +++ b/ui/src/components/IssueThreadInteractionCard.test.tsx @@ -1276,7 +1276,7 @@ describe("IssueThreadInteractionCard resolver audience", () => { expect(audience?.getAttribute("data-audience-policy")).toBe("human_only"); expect( host.querySelector('[data-testid="interaction-audience-note"]')?.textContent, - ).toBe("Company interaction governance narrowed this from Anyone to Human only."); + ).toBe("Organization interaction governance narrowed this from Anyone to Human only."); }); it("explains a legacy card that predates the open default", () => { diff --git a/ui/src/components/IssueThreadInteractionCard.tsx b/ui/src/components/IssueThreadInteractionCard.tsx index 747ccb378a..a7b7f2ac2a 100644 --- a/ui/src/components/IssueThreadInteractionCard.tsx +++ b/ui/src/components/IssueThreadInteractionCard.tsx @@ -3682,7 +3682,7 @@ export function IssueThreadInteractionCard({ - Directed to {addresseeLabel}. Agent-addressed interactions are owned by that agent and are kept out of the open company attention feed. + Directed to {addresseeLabel}. Agent-addressed interactions are owned by that agent and are kept out of the open organization attention feed. ) : null} @@ -3853,7 +3853,7 @@ function ResolvedByAgentChip() { - Resolved by an agent under the company's interaction governance policy — audit-distinct from a human board resolution. + Resolved by an agent under the organization's interaction governance policy — audit-distinct from a human board resolution. ); diff --git a/ui/src/components/JsonSchemaForm.tsx b/ui/src/components/JsonSchemaForm.tsx index 5668665854..d1466eb8fc 100644 --- a/ui/src/components/JsonSchemaForm.tsx +++ b/ui/src/components/JsonSchemaForm.tsx @@ -699,7 +699,7 @@ const SecretField = React.memo(({ label={label} description={ description || - "Pick an existing company secret, or paste a raw value (Paperclip will store it as a secret on save)." + "Pick an existing organization secret, or paste a raw value (Paperclip will store it as a secret on save)." } required={isRequired} error={error} diff --git a/ui/src/components/NewAgentDialog.test.tsx b/ui/src/components/NewAgentDialog.test.tsx index b1c63b9e1c..5fc729d9cb 100644 --- a/ui/src/components/NewAgentDialog.test.tsx +++ b/ui/src/components/NewAgentDialog.test.tsx @@ -160,7 +160,7 @@ describe("NewAgentDialog", () => { }); expect(container.textContent).toContain("Generate a one-time onboarding prompt"); - expect(container.textContent).not.toContain("Company Invites"); + expect(container.textContent).not.toContain("Organization Invites"); const generateButton = Array.from(container.querySelectorAll("button")).find( (button) => button.textContent === "Generate onboarding prompt", diff --git a/ui/src/components/NewAgentDialog.tsx b/ui/src/components/NewAgentDialog.tsx index 1324b84c2a..73bd9e3b6a 100644 --- a/ui/src/components/NewAgentDialog.tsx +++ b/ui/src/components/NewAgentDialog.tsx @@ -352,7 +352,7 @@ export function NewAgentDialog() {

- Agent invites create a join request first. A company admin still approves the request before the agent can claim its API key. + Agent invites create a join request first. An organization admin still approves the request before the agent can claim its API key.
@@ -385,7 +385,7 @@ export function NewAgentDialog() { ) : null}

- Send this prompt to the external agent that should join this company. + Send this prompt to the external agent that should join this organization.

diff --git a/ui/src/components/NewGoalDialog.tsx b/ui/src/components/NewGoalDialog.tsx index a41ea3e4e5..f842015452 100644 --- a/ui/src/components/NewGoalDialog.tsx +++ b/ui/src/components/NewGoalDialog.tsx @@ -27,7 +27,7 @@ import { MarkdownEditor, type MarkdownEditorRef } from "./MarkdownEditor"; import { StatusBadge } from "./StatusBadge"; const levelLabels: Record = { - company: "Company", + company: "Organization", team: "Team", agent: "Agent", task: "Task", @@ -70,7 +70,7 @@ export function NewGoalDialog() { const uploadDescriptionImage = useMutation({ mutationFn: async (file: File) => { - if (!selectedCompanyId) throw new Error("No company selected"); + if (!selectedCompanyId) throw new Error("No organization selected"); return assetsApi.uploadImage(selectedCompanyId, file, "goals/drafts"); }, }); diff --git a/ui/src/components/NewIssueDialog.test.tsx b/ui/src/components/NewIssueDialog.test.tsx index 2a6c778a7a..8e9275f83c 100644 --- a/ui/src/components/NewIssueDialog.test.tsx +++ b/ui/src/components/NewIssueDialog.test.tsx @@ -570,7 +570,7 @@ describe("NewIssueDialog", () => { await waitForAssertion(() => { expect(container.querySelector('[data-testid="new-issue-paused-assignee-note"]')).not.toBeNull(); }); - expect(container.textContent).toContain("arrived paused from a company import"); + expect(container.textContent).toContain("arrived paused from an organization import"); act(() => root.unmount()); }); diff --git a/ui/src/components/NewIssueDialog.tsx b/ui/src/components/NewIssueDialog.tsx index a382b7c13a..8de5329688 100644 --- a/ui/src/components/NewIssueDialog.tsx +++ b/ui/src/components/NewIssueDialog.tsx @@ -688,7 +688,7 @@ export function NewIssueDialog() { const uploadDescriptionImage = useMutation({ mutationFn: async (file: File) => { - if (!effectiveCompanyId) throw new Error("No company selected"); + if (!effectiveCompanyId) throw new Error("No organization selected"); return assetsApi.uploadImage(effectiveCompanyId, file, "issues/drafts"); }, }); @@ -2341,7 +2341,7 @@ export function NewIssueDialog() {
{selectedAssigneeAgent.name} is paused and will not start work on this task until it is resumed - {selectedAssigneeAgent.pauseReason === "import" ? " — it arrived paused from a company import" : ""}. You can resume it from the task page after creating the task. + {selectedAssigneeAgent.pauseReason === "import" ? " — it arrived paused from an organization import" : ""}. You can resume it from the task page after creating the task.
) : null} diff --git a/ui/src/components/NewProjectDialog.tsx b/ui/src/components/NewProjectDialog.tsx index 7bb3158f7d..a041a72a65 100644 --- a/ui/src/components/NewProjectDialog.tsx +++ b/ui/src/components/NewProjectDialog.tsx @@ -96,7 +96,7 @@ export function NewProjectDialog() { const uploadDescriptionImage = useMutation({ mutationFn: async (file: File) => { - if (!selectedCompanyId) throw new Error("No company selected"); + if (!selectedCompanyId) throw new Error("No organization selected"); return assetsApi.uploadImage(selectedCompanyId, file, "projects/drafts"); }, }); diff --git a/ui/src/components/OnboardingWizard.step.test.tsx b/ui/src/components/OnboardingWizard.step.test.tsx index 66304ba1a6..fb4cb0170c 100644 --- a/ui/src/components/OnboardingWizard.step.test.tsx +++ b/ui/src/components/OnboardingWizard.step.test.tsx @@ -961,7 +961,7 @@ describe("OnboardingWizard — which step it lands on", () => { expect(segments.every((segment) => segment.disabled)).toBe(true); // And company creation is genuinely unreachable, not merely unlinked. - expect(document.body.textContent).not.toContain("Name your company"); + expect(document.body.textContent).not.toContain("Name your organization"); }); }); }); diff --git a/ui/src/components/OnboardingWizard.tsx b/ui/src/components/OnboardingWizard.tsx index 55a6880b69..138f100c23 100644 --- a/ui/src/components/OnboardingWizard.tsx +++ b/ui/src/components/OnboardingWizard.tsx @@ -1025,7 +1025,7 @@ function OnboardingWizardInner({ ): Promise { if (!createdCompanyId) { setAdapterEnvError( - "Create or select a company before testing adapter environment." + "Create or select an organization before testing adapter environment." ); return null; } @@ -1209,7 +1209,7 @@ function OnboardingWizardInner({ setStep(3); // → Create your team lead } catch (err) { - setError(err instanceof Error ? err.message : "Failed to create company"); + setError(err instanceof Error ? err.message : "Failed to create organization"); } finally { setLoading(false); } @@ -1255,7 +1255,7 @@ function OnboardingWizardInner({ setSelectedCompanyId(company.id); setStep(3); } catch (err) { - setError(err instanceof Error ? err.message : "Failed to create company"); + setError(err instanceof Error ? err.message : "Failed to create organization"); } finally { creatingCompanyRef.current = false; setLoading(false); diff --git a/ui/src/components/ProjectProperties.tsx b/ui/src/components/ProjectProperties.tsx index d4f890772a..7a4cde1df5 100644 --- a/ui/src/components/ProjectProperties.tsx +++ b/ui/src/components/ProjectProperties.tsx @@ -293,7 +293,7 @@ export function ProjectProperties({ project, onUpdate, onFieldUpdate, getFieldSa }); const createSecret = useMutation({ mutationFn: (input: { name: string; value: string }) => { - if (!selectedCompanyId) throw new Error("Select a company to create secrets"); + if (!selectedCompanyId) throw new Error("Select an organization to create secrets"); return secretsApi.create(selectedCompanyId, input); }, onSuccess: () => { diff --git a/ui/src/components/ReportsToPicker.tsx b/ui/src/components/ReportsToPicker.tsx index 3c279f7881..d3a4bf0d0b 100644 --- a/ui/src/components/ReportsToPicker.tsx +++ b/ui/src/components/ReportsToPicker.tsx @@ -99,7 +99,7 @@ export function ReportsToPicker({ )} {unknownManager && (
- Saved manager is missing from this company. Choose a new manager or clear. + Saved manager is missing from this organization. Choose a new manager or clear.
)} {rows.map((a) => ( diff --git a/ui/src/components/SecretBindingPicker.test.tsx b/ui/src/components/SecretBindingPicker.test.tsx index 476ab5b5d3..787e3b1af0 100644 --- a/ui/src/components/SecretBindingPicker.test.tsx +++ b/ui/src/components/SecretBindingPicker.test.tsx @@ -88,7 +88,7 @@ describe("SecretBindingPicker", () => { await render(readyContext("active")); expect(container.textContent).toContain("DAYTONA_API_KEY — Other Team"); - expect(container.textContent).toContain("Owned by the Other Team company"); + expect(container.textContent).toContain("Owned by the Other Team organization"); expect(container.textContent).not.toContain("Missing secret"); expect(container.querySelector("select")?.className).not.toContain("border-destructive"); }); diff --git a/ui/src/components/SecretBindingPicker.tsx b/ui/src/components/SecretBindingPicker.tsx index a25891f0a4..f04033ae54 100644 --- a/ui/src/components/SecretBindingPicker.tsx +++ b/ui/src/components/SecretBindingPicker.tsx @@ -197,7 +197,7 @@ export function SecretBindingPicker({ {selectedMissing && value ? (
- {loading &&

Loading companies...

} + {loading &&

Loading organizations...

} {error &&

{error.message}

}
@@ -253,7 +253,7 @@ export function Companies() { onClick={() => setConfirmDeleteId(company.id)} > - Delete Company + Delete Organization @@ -296,7 +296,7 @@ export function Companies() { onClick={(e) => e.stopPropagation()} >

- Delete this company and all its data? This cannot be undone. + Delete this organization and all its data? This cannot be undone.

{archiveMutation.isError && ( {archiveMutation.error instanceof Error ? archiveMutation.error.message - : "Failed to archive company"} + : "Failed to archive organization"} )}
diff --git a/ui/src/pages/CompanySettingsPluginPage.tsx b/ui/src/pages/CompanySettingsPluginPage.tsx index 2ad5ba5193..091c7d6830 100644 --- a/ui/src/pages/CompanySettingsPluginPage.tsx +++ b/ui/src/pages/CompanySettingsPluginPage.tsx @@ -50,7 +50,7 @@ export function CompanySettingsPluginPage() { if (hasInvalidCompanyPrefix) { return ; } - return
Select a company to view this page.
; + return
Select an organization to view this page.
; } if (!settingsRoutePath || isLoading) { diff --git a/ui/src/pages/CompanySkills.test.tsx b/ui/src/pages/CompanySkills.test.tsx index ff565fdf9a..cabcb1a4c6 100644 --- a/ui/src/pages/CompanySkills.test.tsx +++ b/ui/src/pages/CompanySkills.test.tsx @@ -655,7 +655,7 @@ describe("SkillDetailPage settings", () => { detail: makeDetail(v1, { folderPath: "engineering/code-review" }), }); - expect(node.textContent).toContain("Company / Engineering / Code Review"); + expect(node.textContent).toContain("Organization / Engineering / Code Review"); }); it("shows a direct fork action for read-only skills", async () => { diff --git a/ui/src/pages/CompanySkills.tsx b/ui/src/pages/CompanySkills.tsx index 0f9e67ddb7..6440e73a9c 100644 --- a/ui/src/pages/CompanySkills.tsx +++ b/ui/src/pages/CompanySkills.tsx @@ -321,7 +321,7 @@ type SourceFilter = "all" | "company" | "bundled" | "optional" | "external"; const SOURCE_FILTER_LABELS: Record = { all: "All", - company: "Company", + company: "Organization", bundled: "Bundled", optional: "Optional", external: "External", @@ -654,7 +654,7 @@ function categorySetKey(categories: string[]) { } function skillSettingsToastBody(skill: Pick) { - const sharing = skill.sharingScope === "private" ? "Sharing: private" : "Sharing: company"; + const sharing = skill.sharingScope === "private" ? "Sharing: private" : "Sharing: organization"; const categories = skill.categories.length ? `Categories: ${skill.categories.join(", ")}` : "Categories: none"; return `${sharing} | ${categories}`; } @@ -1644,7 +1644,7 @@ function NewSkillWizard({ Slug {effectiveSlug || "skill"} Scope - {draft.sharingScope === "private" ? "Private" : "Company"} + {draft.sharingScope === "private" ? "Private" : "Organization"} Categories {draft.categories.length ? draft.categories.join(", ") : "none"}
@@ -1661,9 +1661,9 @@ function NewSkillWizard({ draft.sharingScope === scope ? "border-foreground bg-accent/50" : "border-border", )} > - {scope === "company" ? "Company" : "Private"} + {scope === "company" ? "Organization" : "Private"} - {scope === "company" ? "Visible inside this company." : "Only visible in your library."} + {scope === "company" ? "Visible inside this organization." : "Only visible in your library."} ))} @@ -2175,7 +2175,7 @@ export function InstallPreviewDialog({
Enable for agents

- Installing adds the skill to the company library. Agents can only use it once it is enabled for them. + Installing adds the skill to the organization library. Agents can only use it once it is enabled for them.

{ const option = agent as AttachAgentOption; return option.required || !option.supportsSkills; @@ -2315,7 +2315,7 @@ function AttachAgentsPopover({
) : null} - emptyMessage={eligible.length === 0 ? "No agents in this company support skills yet." : "No agents yet."} + emptyMessage={eligible.length === 0 ? "No agents in this organization support skills yet." : "No agents yet."} isAgentDisabled={(agent) => { const option = agent as AttachAgentOption; return option.required || !option.supportsSkills; @@ -3367,7 +3367,7 @@ export function SkillDetailPage({ {detail.attachedAgentCount === 1 ? "install" : "installs"} - Agents in this company that currently have this skill installed. + Agents in this organization that currently have this skill installed. } > - Agents from a company import arrive paused as a safety default. Resume them so assigned tasks can start. + Agents from an organization import arrive paused as a safety default. Resume them so assigned tasks can start. ) : pausedBanner?.kind === "all-paused" ? ( Review agents diff --git a/ui/src/pages/DashboardLive.tsx b/ui/src/pages/DashboardLive.tsx index 8c50ae09d4..a7a4323068 100644 --- a/ui/src/pages/DashboardLive.tsx +++ b/ui/src/pages/DashboardLive.tsx @@ -23,7 +23,7 @@ export function DashboardLive() { return ( ); } diff --git a/ui/src/pages/DecisionQueuePage.tsx b/ui/src/pages/DecisionQueuePage.tsx index 71c960f7a1..b442fd02bf 100644 --- a/ui/src/pages/DecisionQueuePage.tsx +++ b/ui/src/pages/DecisionQueuePage.tsx @@ -212,7 +212,7 @@ export function DecisionQueuePage() { }); if (!selectedCompanyId) { - return

Select a company first.

; + return

Select an organization first.

; } if (isLoading) { return ; diff --git a/ui/src/pages/GoalDetail.tsx b/ui/src/pages/GoalDetail.tsx index f22ce4604b..e922a6e700 100644 --- a/ui/src/pages/GoalDetail.tsx +++ b/ui/src/pages/GoalDetail.tsx @@ -99,7 +99,7 @@ export function GoalDetail() { const uploadImage = useMutation({ mutationFn: async (file: File) => { - if (!resolvedCompanyId) throw new Error("No company selected"); + if (!resolvedCompanyId) throw new Error("No organization selected"); return assetsApi.uploadImage( resolvedCompanyId, file, diff --git a/ui/src/pages/Goals.tsx b/ui/src/pages/Goals.tsx index 7dca9e18dd..3c58263375 100644 --- a/ui/src/pages/Goals.tsx +++ b/ui/src/pages/Goals.tsx @@ -27,7 +27,7 @@ export function Goals() { }); if (!selectedCompanyId) { - return ; + return ; } if (isLoading) { diff --git a/ui/src/pages/Inbox.tsx b/ui/src/pages/Inbox.tsx index 1d2fa37c62..60799b7c4c 100644 --- a/ui/src/pages/Inbox.tsx +++ b/ui/src/pages/Inbox.tsx @@ -2210,7 +2210,7 @@ export function Inbox() { }, [selectedIndex]); if (!selectedCompanyId) { - return ; + return ; } const hasRunFailures = failedRuns.length > 0; diff --git a/ui/src/pages/InstanceAccess.tsx b/ui/src/pages/InstanceAccess.tsx index 0dadd26d1e..ddfa8b1f3c 100644 --- a/ui/src/pages/InstanceAccess.tsx +++ b/ui/src/pages/InstanceAccess.tsx @@ -66,7 +66,7 @@ export function InstanceAccess() { onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: queryKeys.access.userCompanyAccess(selectedUserId!) }); await queryClient.invalidateQueries({ queryKey: queryKeys.access.adminUsers(search) }); - pushToast({ title: "Company access updated", tone: "success" }); + pushToast({ title: "Organization access updated", tone: "success" }); }, }); @@ -107,7 +107,7 @@ export function InstanceAccess() {

Instance Access

- Search users, manage instance-admin status, and control which companies they can access. + Search users, manage instance-admin status, and control which organizations they can access.

@@ -144,7 +144,7 @@ export function InstanceAccess() { ) : null}
- {user.activeCompanyMembershipCount} active company memberships + {user.activeCompanyMembershipCount} active organization memberships
))} @@ -182,9 +182,9 @@ export function InstanceAccess() {
-

Company access

+

Organization access

- Toggle company membership for this user. New access defaults to an active operator membership. + Toggle organization membership for this user. New access defaults to an active operator membership.

@@ -216,7 +216,7 @@ export function InstanceAccess() { onClick={() => updateCompanyAccessMutation.mutate()} disabled={updateCompanyAccessMutation.isPending} > - {updateCompanyAccessMutation.isPending ? "Saving…" : "Save company access"} + {updateCompanyAccessMutation.isPending ? "Saving…" : "Save organization access"}
diff --git a/ui/src/pages/InstanceSettings.tsx b/ui/src/pages/InstanceSettings.tsx index 77d371a731..c6ef6c4013 100644 --- a/ui/src/pages/InstanceSettings.tsx +++ b/ui/src/pages/InstanceSettings.tsx @@ -171,14 +171,14 @@ export function InstanceSettings() {

Scheduler Heartbeats

- Agents with a timer heartbeat enabled across all of your companies. + Agents with a timer heartbeat enabled across all of your organizations.

{activeCount} active {disabledCount} disabled - {grouped.length} {grouped.length === 1 ? "company" : "companies"} + {grouped.length} {grouped.length === 1 ? "organization" : "organizations"} {anyEnabled && ( )} @@ -465,7 +465,7 @@ export function OrgChart() { )} diff --git a/ui/src/pages/PipelineSettings.tsx b/ui/src/pages/PipelineSettings.tsx index eec8bacb6b..5e53515a63 100644 --- a/ui/src/pages/PipelineSettings.tsx +++ b/ui/src/pages/PipelineSettings.tsx @@ -1391,7 +1391,7 @@ export function PipelineSettings() { const createSecret = useMutation({ mutationFn: (input: { name: string; value: string }) => { - if (!selectedCompanyId) throw new Error("Select a company to create secrets"); + if (!selectedCompanyId) throw new Error("Select an organization to create secrets"); return secretsApi.create(selectedCompanyId, input); }, onSuccess: () => { @@ -2119,7 +2119,7 @@ export function PipelineSettings() { }; if (!selectedCompanyId) { - return ; + return ; } if (!pipelineId) { diff --git a/ui/src/pages/Pipelines.tsx b/ui/src/pages/Pipelines.tsx index 66b411bf84..3589753b0d 100644 --- a/ui/src/pages/Pipelines.tsx +++ b/ui/src/pages/Pipelines.tsx @@ -941,7 +941,7 @@ function PipelinesIndex() { }); if (!selectedCompanyId) { - return
Select a company to view pipelines.
; + return
Select an organization to view pipelines.
; } if (pipelinesQuery.isLoading) return ; @@ -4941,7 +4941,7 @@ export function ReviewQueue() { const bulkApprove = useMutation({ mutationFn: async (targetRows: ReviewQueueRow[]) => { - if (!selectedCompanyId) throw new Error("Select a company first."); + if (!selectedCompanyId) throw new Error("Select an organization first."); const reviewRows = targetRows.filter((row) => row.kind === "review"); const suggestionRows = targetRows.filter((row) => row.kind === "suggestion" && row.suggestionId); const tasks: Promise[] = []; @@ -5046,7 +5046,7 @@ export function ReviewQueue() { }, [activeRowId, decideRow, openItem, visibleRows]); if (!selectedCompanyId) { - return ; + return ; } if (attentionQuery.isLoading || reviewCasesQuery.isLoading) { @@ -5170,7 +5170,7 @@ export function Learnings() { }); if (!selectedCompanyId) { - return ; + return ; } if (learningsQuery.isLoading && !learningsQuery.data) { diff --git a/ui/src/pages/PluginManager.tsx b/ui/src/pages/PluginManager.tsx index e13ab4ce28..e1cccb4060 100644 --- a/ui/src/pages/PluginManager.tsx +++ b/ui/src/pages/PluginManager.tsx @@ -99,7 +99,7 @@ export function PluginManager() { useEffect(() => { setBreadcrumbs([ - { label: selectedCompany?.name ?? "Company", href: "/dashboard" }, + { label: selectedCompany?.name ?? "Organization", href: "/dashboard" }, { label: "Settings", href: "/company/settings" }, { label: "Plugins" }, ]); diff --git a/ui/src/pages/PluginPage.tsx b/ui/src/pages/PluginPage.tsx index f22ee4a930..1a8b9a2269 100644 --- a/ui/src/pages/PluginPage.tsx +++ b/ui/src/pages/PluginPage.tsx @@ -130,7 +130,7 @@ export function PluginPage() { } return (
-

Select a company to view this page.

+

Select an organization to view this page.

); } diff --git a/ui/src/pages/PluginSettings.test.tsx b/ui/src/pages/PluginSettings.test.tsx index b1a6c047e6..2b631e4d5d 100644 --- a/ui/src/pages/PluginSettings.test.tsx +++ b/ui/src/pages/PluginSettings.test.tsx @@ -165,7 +165,7 @@ describe("PluginSettings", () => { const root = await renderSettings(container); expect(container.textContent).toContain("Configure this plugin from Settings → Environments."); - expect(container.textContent).toContain("secret bindings still resolve through the selected company context"); + expect(container.textContent).toContain("secret bindings still resolve through the selected organization context"); const link = container.querySelector('a[href="/company/settings/instance/environments"]'); expect(link?.textContent).toContain("Open Environments"); diff --git a/ui/src/pages/PluginSettings.tsx b/ui/src/pages/PluginSettings.tsx index 4985765efc..2aeab483bb 100644 --- a/ui/src/pages/PluginSettings.tsx +++ b/ui/src/pages/PluginSettings.tsx @@ -120,7 +120,7 @@ export function PluginSettings() { useEffect(() => { setBreadcrumbs([ - { label: selectedCompany?.name ?? "Company", href: "/dashboard" }, + { label: selectedCompany?.name ?? "Organization", href: "/dashboard" }, { label: "Settings", href: "/company/settings" }, { label: "Plugins", href: "/company/settings/instance/plugins" }, { label: plugin?.manifestJson?.displayName ?? plugin?.packageName ?? "Plugin Details" }, @@ -261,7 +261,7 @@ export function PluginSettings() {

Configure this plugin from Settings → Environments.

{driverLabel || "This plugin"} registers environment runtime settings there so the execution target - stays instance-scoped while secret bindings still resolve through the selected company context. + stays instance-scoped while secret bindings still resolve through the selected organization context.

@@ -598,7 +598,7 @@ function PluginLocalFoldersSettings({ pluginId, companyId, declarations }: Plugi if (!companyId) { return (
- Select a company to configure this plugin's local folders. + Select an organization to configure this plugin's local folders.
); } @@ -982,7 +982,7 @@ function PluginConfigForm({ pluginId, companyId, schema, initialValues, isLoadin // Save mutation const saveMutation = useMutation({ mutationFn: (configJson: Record) => { - if (!companyId) throw new Error("Select a company before saving plugin configuration."); + if (!companyId) throw new Error("Select an organization before saving plugin configuration."); return pluginsApi.saveConfig(pluginId, companyId, configJson); }, onSuccess: () => { @@ -1002,7 +1002,7 @@ function PluginConfigForm({ pluginId, companyId, schema, initialValues, isLoadin // Test configuration mutation const testMutation = useMutation({ mutationFn: (configJson: Record) => { - if (!companyId) throw new Error("Select a company before testing plugin configuration."); + if (!companyId) throw new Error("Select an organization before testing plugin configuration."); return pluginsApi.testConfig(pluginId, companyId, configJson); }, onSuccess: (result) => { diff --git a/ui/src/pages/ProfileSettings.tsx b/ui/src/pages/ProfileSettings.tsx index 8dbd86cd62..1b7717c5ac 100644 --- a/ui/src/pages/ProfileSettings.tsx +++ b/ui/src/pages/ProfileSettings.tsx @@ -87,7 +87,7 @@ export function ProfileSettings() { const uploadAvatarMutation = useMutation({ mutationFn: async (file: File) => { if (!selectedCompanyId) { - throw new Error("Select a company before uploading a profile avatar."); + throw new Error("Select an organization before uploading a profile avatar."); } const asset = await assetsApi.uploadImage( @@ -137,7 +137,7 @@ export function ProfileSettings() { const isSavingProfile = updateMutation.isPending || uploadAvatarMutation.isPending || removeAvatarMutation.isPending; const uploadHint = selectedCompany ? `Stored in Paperclip file storage for ${selectedCompany.name}.` - : "Select a company to upload an avatar into Paperclip storage."; + : "Select an organization to upload an avatar into Paperclip storage."; return (
diff --git a/ui/src/pages/ProjectDetail.tsx b/ui/src/pages/ProjectDetail.tsx index db612c6ce0..8d9a64df7e 100644 --- a/ui/src/pages/ProjectDetail.tsx +++ b/ui/src/pages/ProjectDetail.tsx @@ -514,7 +514,7 @@ export function ProjectDetail() { const uploadImage = useMutation({ mutationFn: async (file: File) => { - if (!resolvedCompanyId) throw new Error("No company selected"); + if (!resolvedCompanyId) throw new Error("No organization selected"); return assetsApi.uploadImage(resolvedCompanyId, file, `projects/${projectLookupRef || "draft"}`); }, }); diff --git a/ui/src/pages/Projects.tsx b/ui/src/pages/Projects.tsx index 50c5133c82..02006e0f28 100644 --- a/ui/src/pages/Projects.tsx +++ b/ui/src/pages/Projects.tsx @@ -119,7 +119,7 @@ export function Projects() { const sortLabel = PROJECT_SORT_OPTIONS.find((option) => option.field === sortField)?.label ?? "Name"; if (!selectedCompanyId) { - return ; + return ; } if (isLoading) { diff --git a/ui/src/pages/RoutineDetail.tsx b/ui/src/pages/RoutineDetail.tsx index 88d4443bef..ffaca21049 100644 --- a/ui/src/pages/RoutineDetail.tsx +++ b/ui/src/pages/RoutineDetail.tsx @@ -251,7 +251,7 @@ export function RoutineDetail() { }); const createSecret = useMutation({ mutationFn: (input: { name: string; value: string }) => { - if (!selectedCompanyId) throw new Error("Select a company to create secrets"); + if (!selectedCompanyId) throw new Error("Select an organization to create secrets"); return secretsApi.create(selectedCompanyId, input); }, onSuccess: () => { @@ -674,7 +674,7 @@ export function RoutineDetail() { ); if (!selectedCompanyId) { - return ; + return ; } // Back-compat redirect: `?tab=x` → `/routines/:id/x`. diff --git a/ui/src/pages/Routines.tsx b/ui/src/pages/Routines.tsx index 4ec6f10503..1c93762451 100644 --- a/ui/src/pages/Routines.tsx +++ b/ui/src/pages/Routines.tsx @@ -796,7 +796,7 @@ export function Routines() { } if (!selectedCompanyId) { - return ; + return ; } if (isLoading) { diff --git a/ui/src/pages/Search.tsx b/ui/src/pages/Search.tsx index 51625bd02b..3f528a50f9 100644 --- a/ui/src/pages/Search.tsx +++ b/ui/src/pages/Search.tsx @@ -805,7 +805,7 @@ function SearchTabContent({ return (
-

Type to search company memory.

+

Type to search organization memory.

Tasks, comments, plan documents, artifacts, agents, projects — same surface, ranked by relevance.

diff --git a/ui/src/pages/Secrets.render.test.tsx b/ui/src/pages/Secrets.render.test.tsx index bd4b62ba11..9e945ba3ba 100644 --- a/ui/src/pages/Secrets.render.test.tsx +++ b/ui/src/pages/Secrets.render.test.tsx @@ -771,7 +771,7 @@ describe("Secrets page layout", () => { expect(container.textContent).toContain("OPENAI_API_KEY"); expect(container.textContent).toContain("Personal GitHub token"); - expect(container.textContent).toContain("Company"); + expect(container.textContent).toContain("Organization"); expect(container.textContent).toContain("Each user"); expect(container.textContent).toContain("3/5 set"); expect(container.textContent).not.toContain("User secret definitions"); diff --git a/ui/src/pages/Secrets.tsx b/ui/src/pages/Secrets.tsx index b385b0276d..7d4698d79a 100644 --- a/ui/src/pages/Secrets.tsx +++ b/ui/src/pages/Secrets.tsx @@ -1787,7 +1787,7 @@ export function Secrets() { if (!selectedCompanyId) { return ( -
Select a company to manage secrets.
+
Select an organization to manage secrets.
); } @@ -1958,7 +1958,7 @@ export function Secrets() { !(showFolderView && folderPath) ? ( @@ -2076,7 +2076,7 @@ export function Secrets() {
{row.kind === "company" ? ( - Company + Organization ) : ( @@ -2141,7 +2141,7 @@ export function Secrets() { {row.kind === "company" ? ( <> - Company + Organization
- Company + Organization {modeLabel(selectedSecret.managedMode)} {providerLabel(providers, selectedSecret.provider)} @@ -2581,12 +2581,12 @@ export function Secrets() { }} > - Company + Organization Each user

- Company stores one shared value. Each user lets every member supply their own value under My secrets. + Organization stores one shared value. Each user lets every member supply their own value under My secrets.

) : null} @@ -3182,7 +3182,7 @@ export function Secrets() { Delete user-provided secret - Permanently removes {definitionDeleteConfirm?.name} for the whole company. + Permanently removes {definitionDeleteConfirm?.name} for the whole organization. Existing member values become unreferenced and active bindings must be remapped. @@ -3351,7 +3351,7 @@ function SecretsFiltersPopover({
{[ { value: "all" as const, label: "All sources" }, - { value: "company" as const, label: "Company" }, + { value: "company" as const, label: "Organization" }, { value: "user" as const, label: "Each user" }, ].map((option) => (
@@ -1407,7 +1407,7 @@ export function StepTargetManager({ className="rounded-md border border-blue-500/30 bg-blue-500/10 px-3 py-2.5 text-sm text-blue-700 dark:text-blue-300" id="target-manager-help" > - This team's root agents need a manager in your company. Pick the agent who will become + This team's root agents need a manager in your organization. Pick the agent who will become their parent. Internal team hierarchy is preserved.
@@ -1461,7 +1461,7 @@ export function StepTargetManager({ checked={fullCompany} onChange={(e) => onToggleFullCompany(e.target.checked)} /> - Use this team as a full-company package (no target manager) + Use this team as a full-organization package (no target manager) )}
@@ -1998,7 +1998,7 @@ export function ApplySuccess({

Team installed

- {team.name} was imported into your company. Imported entities are stamped with catalog provenance. + {team.name} was imported into your organization. Imported entities are stamped with catalog provenance.

{result && (
    @@ -2299,7 +2299,7 @@ export function TeamCatalog() { if (!selectedCompanyId) { return (
    - +
    ); } diff --git a/ui/src/pages/Timeline.tsx b/ui/src/pages/Timeline.tsx index afa400ae22..1957742740 100644 --- a/ui/src/pages/Timeline.tsx +++ b/ui/src/pages/Timeline.tsx @@ -352,7 +352,7 @@ export function Timeline() { return ( <> - + ); } diff --git a/ui/src/pages/UserProfile.tsx b/ui/src/pages/UserProfile.tsx index 260ae6b4e2..f91e33c2f9 100644 --- a/ui/src/pages/UserProfile.tsx +++ b/ui/src/pages/UserProfile.tsx @@ -243,7 +243,7 @@ export function UserProfile() { ); if (!selectedCompanyId) { - return ; + return ; } if (isLoading) { @@ -251,7 +251,7 @@ export function UserProfile() { } if (error || !data) { - return ; + return ; } const allTimeTokens = allTime ? totalTokens(allTime) : 0; diff --git a/ui/src/pages/WhatNeedsMe.tsx b/ui/src/pages/WhatNeedsMe.tsx index 0e51fc88bf..05ce04e3ac 100644 --- a/ui/src/pages/WhatNeedsMe.tsx +++ b/ui/src/pages/WhatNeedsMe.tsx @@ -507,7 +507,7 @@ export function WhatNeedsMe() { }, [handleDismiss, keyboardItems, navigate, selectedAttentionId]); if (!selectedCompanyId) { - return

    Select a company first.

    ; + return

    Select an organization first.

    ; } if (isLoading) { diff --git a/ui/src/pages/agent-skills/AgentSkillsTab.tsx b/ui/src/pages/agent-skills/AgentSkillsTab.tsx index 4ec4d2b82e..f4057d4b11 100644 --- a/ui/src/pages/agent-skills/AgentSkillsTab.tsx +++ b/ui/src/pages/agent-skills/AgentSkillsTab.tsx @@ -452,7 +452,7 @@ export function AgentSkillsTab({ agent, companyId }: { agent: Agent; companyId?: className="flex items-center justify-between gap-3 border-b border-amber-300/40 bg-amber-50/60 px-3 py-2 text-xs text-amber-800 last:border-b-0 dark:border-amber-500/20 dark:bg-amber-950/20 dark:text-amber-200" > - {key} is enabled but missing from the company library. + {key} is enabled but missing from the organization library.
@@ -607,7 +607,7 @@ export function AuditFeed({ ? "Try a wider date range or different filters." : resolvedMode === "agents" ? "As soon as your agents start doing things, their actions show up here." - : "As soon as anyone in your company does something, it shows up here."} + : "As soon as anyone in your organization does something, it shows up here."}

{hasActiveFilters ? ( diff --git a/ui/src/pages/audit/CompanyActivity.tsx b/ui/src/pages/audit/CompanyActivity.tsx index 8bde7c66b8..c986ef58c0 100644 --- a/ui/src/pages/audit/CompanyActivity.tsx +++ b/ui/src/pages/audit/CompanyActivity.tsx @@ -42,7 +42,7 @@ export function CompanyActivity() { ); if (!selectedCompanyId) { - return ; + return ; } return ; diff --git a/ui/src/pages/secrets/MyUserSecretsTab.tsx b/ui/src/pages/secrets/MyUserSecretsTab.tsx index 53d7935971..04686763b9 100644 --- a/ui/src/pages/secrets/MyUserSecretsTab.tsx +++ b/ui/src/pages/secrets/MyUserSecretsTab.tsx @@ -81,7 +81,7 @@ export function MyUserSecretsTab({ companyId }: { companyId: string }) { ) : entries.length === 0 && !mySecretsQuery.isPending ? ( ) : (
    diff --git a/ui/src/pages/skills/ImportSkillsFromProjectDialog.tsx b/ui/src/pages/skills/ImportSkillsFromProjectDialog.tsx index f20b87625b..0785ae7a40 100644 --- a/ui/src/pages/skills/ImportSkillsFromProjectDialog.tsx +++ b/ui/src/pages/skills/ImportSkillsFromProjectDialog.tsx @@ -685,7 +685,7 @@ function PickProjectStep({
    {readableErrorMessage(error)}
    ) : totalProjects === 0 ? ( - + ) : projects.length === 0 ? ( ) : ( @@ -955,7 +955,7 @@ function SelectStep({

    {grant - ? "Your account doesn't have permission to add skills to this company. Ask an owner to grant the skills permission, then try again." + ? "Your account doesn't have permission to add skills to this organization. Ask an owner to grant the skills permission, then try again." : readableErrorMessage(scanError)}

    {!grant && ( diff --git a/ui/src/pages/tools/ProfilesTab.tsx b/ui/src/pages/tools/ProfilesTab.tsx index 6b58e00806..ca8d312eef 100644 --- a/ui/src/pages/tools/ProfilesTab.tsx +++ b/ui/src/pages/tools/ProfilesTab.tsx @@ -538,7 +538,7 @@ export function EffectiveAgentPanel({ companyId, agentOptions }: { companyId: st
    {profile.name} {profile.summary.isCompanyDefault ? ( - Company default + Organization default ) : null}
    ))} @@ -935,7 +935,7 @@ export function ProfilesTab({ companyId }: { companyId: string }) { setCreateOpen(true)} /> diff --git a/ui/src/pages/tools/RunYourOwnTab.tsx b/ui/src/pages/tools/RunYourOwnTab.tsx index a2aac5a266..418cb8491a 100644 --- a/ui/src/pages/tools/RunYourOwnTab.tsx +++ b/ui/src/pages/tools/RunYourOwnTab.tsx @@ -94,7 +94,7 @@ export function RunYourOwnTab({ companyId }: { companyId: string }) { return (

    - For a tool that runs from a command. Paperclip runs it in your company's own isolated workspace. + For a tool that runs from a command. Paperclip runs it in your organization's own isolated workspace. Administrators only.

    diff --git a/ui/src/pages/tools/RuntimeTab.tsx b/ui/src/pages/tools/RuntimeTab.tsx index 3af13ae8c9..8687fee11f 100644 --- a/ui/src/pages/tools/RuntimeTab.tsx +++ b/ui/src/pages/tools/RuntimeTab.tsx @@ -94,7 +94,7 @@ function howItRuns(slot: ToolRuntimeSlot): string { function scopeLabel(scope: string | null | undefined): string { switch (scope) { case "company": - return "Whole company"; + return "Whole organization"; case "project": case "project_workspace": return "This project"; diff --git a/ui/src/pages/tools/ToolsAccess.tsx b/ui/src/pages/tools/ToolsAccess.tsx index 1ffeff8049..e9c0aa781e 100644 --- a/ui/src/pages/tools/ToolsAccess.tsx +++ b/ui/src/pages/tools/ToolsAccess.tsx @@ -65,7 +65,7 @@ export function ToolsAccess() { }, [setBreadcrumbs, selectedCompany?.name, advanced, tabLabel]); if (!selectedCompanyId) { - return
    Select a company to open advanced setup.
    ; + return
    Select an organization to open advanced setup.
    ; } // Retired developer tabs (PAP-10915/PAP-10928) — keep old links working. diff --git a/ui/src/pages/tools/profiles/ProfileActionDialog.tsx b/ui/src/pages/tools/profiles/ProfileActionDialog.tsx index 20a4dc7582..2142332b62 100644 --- a/ui/src/pages/tools/profiles/ProfileActionDialog.tsx +++ b/ui/src/pages/tools/profiles/ProfileActionDialog.tsx @@ -48,7 +48,7 @@ export function ProfileActionDialog({ delete: { title: "Delete profile", body: defaultDeleteBlocked - ? "This profile is the company default. Reassign the company default to another profile before deleting it." + ? "This profile is the organization default. Reassign the organization default to another profile before deleting it." : `This permanently deletes the profile and removes ${profile.summary.assignmentCount} ${profile.summary.assignmentCount === 1 ? "assignment" : "assignments"}.`, confirm: "Delete", action: onDelete, @@ -65,7 +65,7 @@ export function ProfileActionDialog({ {defaultDeleteBlocked ? (
    - Choose another access profile and make it the company default first. + Choose another access profile and make it the organization default first.
    ) : null} diff --git a/ui/src/pages/tools/profiles/ProfileDetail.test.tsx b/ui/src/pages/tools/profiles/ProfileDetail.test.tsx index e86f006be4..7d1958b063 100644 --- a/ui/src/pages/tools/profiles/ProfileDetail.test.tsx +++ b/ui/src/pages/tools/profiles/ProfileDetail.test.tsx @@ -339,7 +339,7 @@ describe("ProfileDetail", () => { }); await Promise.resolve(); - expect(document.body.textContent).toContain("Reassign the company default to another profile before deleting it."); + expect(document.body.textContent).toContain("Reassign the organization default to another profile before deleting it."); const dialogDelete = [...document.body.querySelectorAll('[role="dialog"] button')].find((b) => b.textContent?.trim() === "Delete") as HTMLButtonElement | undefined; expect(dialogDelete?.disabled).toBe(true); expect(api.deleteProfile).not.toHaveBeenCalled(); diff --git a/ui/src/pages/tools/profiles/ProfileDetail.tsx b/ui/src/pages/tools/profiles/ProfileDetail.tsx index be4b3c4321..f3a04bf454 100644 --- a/ui/src/pages/tools/profiles/ProfileDetail.tsx +++ b/ui/src/pages/tools/profiles/ProfileDetail.tsx @@ -534,7 +534,7 @@ function Assignments({
    - {binding.targetType === "company" ? "Co" : binding.targetType.slice(0, 2).toUpperCase()} + {binding.targetType === "company" ? "Or" : binding.targetType.slice(0, 2).toUpperCase()}

    {assignmentLabel(binding, companyId, maps)}

    @@ -730,7 +730,7 @@ function RemoveAssignmentDialog({ Remove assignment {binding?.targetType === "company" - ? "Removing the company default changes access for every agent that relies on it." + ? "Removing the organization default changes access for every agent that relies on it." : `Remove this profile from ${label}.`} @@ -831,16 +831,16 @@ function assignmentLabel( companyId: string, maps: ReturnType["maps"], ): string { - if (binding.targetType === "company") return "Company default"; + if (binding.targetType === "company") return "Organization default"; if (binding.targetType === "agent") return maps.agentsById.get(binding.targetId) ?? "Unknown agent"; if (binding.targetType === "project") return maps.projectsById.get(binding.targetId) ?? "Unknown project"; if (binding.targetType === "routine") return maps.routinesById.get(binding.targetId) ?? "Unknown routine"; - if (binding.targetId === companyId) return "Company"; + if (binding.targetId === companyId) return "Organization"; return binding.targetId; } function assignmentTypeLabel(type: ToolProfileBinding["targetType"]): string { - if (type === "company") return "Company default"; + if (type === "company") return "Organization default"; if (type === "agent") return "Agent"; if (type === "project") return "Project"; if (type === "routine") return "Routine"; diff --git a/ui/src/pages/tools/profiles/ProfileDetailRoute.tsx b/ui/src/pages/tools/profiles/ProfileDetailRoute.tsx index ec1d695946..28c684462d 100644 --- a/ui/src/pages/tools/profiles/ProfileDetailRoute.tsx +++ b/ui/src/pages/tools/profiles/ProfileDetailRoute.tsx @@ -22,7 +22,7 @@ export function ProfileDetailRoute() { }, [setBreadcrumbs, selectedCompany?.name]); if (!selectedCompanyId || !params.profileId) { - return
    Select a company and profile.
    ; + return
    Select an organization and profile.
    ; } return ( diff --git a/ui/src/pages/tools/profiles/ProfileWizard.tsx b/ui/src/pages/tools/profiles/ProfileWizard.tsx index eebfbcbd87..704be38582 100644 --- a/ui/src/pages/tools/profiles/ProfileWizard.tsx +++ b/ui/src/pages/tools/profiles/ProfileWizard.tsx @@ -609,7 +609,7 @@ export function StepAssign({ onChange={(e) => onCompanyDefault(e.target.checked)} /> - Make this the company default + Make this the organization default Every agent without its own profile uses this one. {defaultProfileName ? ` Replaces “${defaultProfileName}”.` : ""} @@ -630,7 +630,7 @@ export function StepAssign({ getDescription={(agent) => { const context = contextByAgent.get(agent.id) ?? []; const bits = [...context]; - if (defaultProfileName) bits.push("company default"); + if (defaultProfileName) bits.push("organization default"); return bits.length > 0 ? `already has: ${bits.join(" · ")}` : "no profiles yet"; }} /> diff --git a/ui/src/pages/tools/profiles/ProfileWizardRoute.tsx b/ui/src/pages/tools/profiles/ProfileWizardRoute.tsx index 9b6b34a77b..12a7e51bc9 100644 --- a/ui/src/pages/tools/profiles/ProfileWizardRoute.tsx +++ b/ui/src/pages/tools/profiles/ProfileWizardRoute.tsx @@ -28,7 +28,7 @@ export function ProfileWizardRoute({ mode }: { mode: "new" | "edit" }) { useEffect(() => { setBreadcrumbs([ - { label: selectedCompany?.name ?? "Company", href: "/dashboard" }, + { label: selectedCompany?.name ?? "Organization", href: "/dashboard" }, { label: "Apps", href: "/apps" }, { label: "Access profiles", href: advancedTabHref("profiles") }, { label: mode === "edit" ? "Resume draft" : "New profile" }, @@ -37,7 +37,7 @@ export function ProfileWizardRoute({ mode }: { mode: "new" | "edit" }) { }, [setBreadcrumbs, selectedCompany?.name, mode]); if (!selectedCompanyId) { - return
    Select a company to create a profile.
    ; + return
    Select an organization to create a profile.
    ; } return ( diff --git a/ui/src/pages/tools/profiles/ProfilesIndex.test.tsx b/ui/src/pages/tools/profiles/ProfilesIndex.test.tsx index 70744341cc..73052caa3d 100644 --- a/ui/src/pages/tools/profiles/ProfilesIndex.test.tsx +++ b/ui/src/pages/tools/profiles/ProfilesIndex.test.tsx @@ -140,7 +140,7 @@ describe("ProfilesIndex", () => { expect(container.textContent).toContain("9 tools · 3 apps"); expect(container.textContent).toContain("2 agents"); expect(container.textContent).toContain("All except 2 tools"); - expect(container.textContent).toContain("Company default"); + expect(container.textContent).toContain("Organization default"); }); it("shows a new-tools chip in the Allows column", async () => { @@ -266,7 +266,7 @@ describe("ProfilesIndex", () => { await Promise.resolve(); expect(confirm).not.toHaveBeenCalled(); - expect(document.body.textContent).toContain("Reassign the company default to another profile before deleting it."); + expect(document.body.textContent).toContain("Reassign the organization default to another profile before deleting it."); const dialogDelete = [...document.body.querySelectorAll('[role="dialog"] button')].find((b) => b.textContent?.trim() === "Delete") as HTMLButtonElement | undefined; expect(dialogDelete?.disabled).toBe(true); expect(api.deleteProfile).not.toHaveBeenCalled(); diff --git a/ui/src/pages/tools/profiles/profile-summary.test.ts b/ui/src/pages/tools/profiles/profile-summary.test.ts index c22859ebde..01ed6c98c0 100644 --- a/ui/src/pages/tools/profiles/profile-summary.test.ts +++ b/ui/src/pages/tools/profiles/profile-summary.test.ts @@ -37,7 +37,7 @@ describe("allowsLabel", () => { describe("assignedLabel", () => { it("prefers the company-default label", () => { expect(assignedLabel(summary({ isCompanyDefault: true, appliesToAgentCount: 4 }))).toEqual({ - text: "Company default", + text: "Organization default", unassigned: false, }); }); diff --git a/ui/src/pages/tools/profiles/profile-summary.ts b/ui/src/pages/tools/profiles/profile-summary.ts index 3f9fe33a5e..978839f6e6 100644 --- a/ui/src/pages/tools/profiles/profile-summary.ts +++ b/ui/src/pages/tools/profiles/profile-summary.ts @@ -31,9 +31,9 @@ export interface AssignedLabel { unassigned: boolean; } -/** "Company default" / "2 agents" / "Not assigned yet". */ +/** "Organization default" / "2 agents" / "Not assigned yet". */ export function assignedLabel(summary: ToolProfileSummary): AssignedLabel { - if (summary.isCompanyDefault) return { text: "Company default", unassigned: false }; + if (summary.isCompanyDefault) return { text: "Organization default", unassigned: false }; if (summary.appliesToAgentCount > 0) { return { text: plural(summary.appliesToAgentCount, "agent"), unassigned: false }; } diff --git a/ui/src/plugins/bridge-init.ts b/ui/src/plugins/bridge-init.ts index 5cccc7769b..e94a3e880c 100644 --- a/ui/src/plugins/bridge-init.ts +++ b/ui/src/plugins/bridge-init.ts @@ -324,7 +324,7 @@ function PluginSdkIssuesList({ }); if (!companyId) { - return createElement("div", { className: "text-sm text-muted-foreground" }, "Select a company to view tasks."); + return createElement("div", { className: "text-sm text-muted-foreground" }, "Select an organization to view tasks."); } return createElement(HostIssuesList, {