Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ jobs:
node-version: 22
cache: npm
- run: npm ci
- run: npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.cacheplane.ai --dry-run
- run: npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.threadplane.ai --dry-run

examples-chat-smoke:
name: examples/chat — python smoke
Expand Down Expand Up @@ -456,7 +456,7 @@ jobs:
run: |
mkdir -p .vercel
cat > .vercel/project.json <<EOF
{"projectId":"${{ secrets.VERCEL_WEBSITE_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"angular"}
{"projectId":"${{ secrets.VERCEL_WEBSITE_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"threadplane"}
EOF
npx vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
rm -rf .vercel/output
Expand All @@ -471,13 +471,13 @@ jobs:
if: steps.affected.outputs.website == 'true'
run: npx nx e2e website --skip-nx-cache
env:
BASE_URL: https://cacheplane.ai
BASE_URL: https://threadplane.ai
- name: Prepare cockpit Vercel project
if: steps.affected.outputs.cockpit == 'true'
run: |
mkdir -p .vercel
cat > .vercel/project.json <<EOF
{"projectId":"${{ secrets.VERCEL_COCKPIT_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"cockpit"}
{"projectId":"${{ secrets.VERCEL_COCKPIT_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"threadplane-cockpit"}
EOF
npx vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
rm -rf .vercel/output
Expand All @@ -491,7 +491,7 @@ jobs:
- name: Verify deployed cockpit
if: steps.affected.outputs.cockpit == 'true'
run: |
npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.cacheplane.ai --retries 20 --retry-delay-ms 5000
npx tsx apps/cockpit/scripts/deploy-smoke.ts --url https://cockpit.threadplane.ai --retries 20 --retry-delay-ms 5000

- name: Build and assemble Angular examples
if: steps.examples_changed.outputs.changed == 'true'
Expand All @@ -502,7 +502,7 @@ jobs:
run: |
mkdir -p .vercel
cat > .vercel/project.json <<EOF
{"projectId":"${{ secrets.VERCEL_EXAMPLES_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"cockpit-examples"}
{"projectId":"${{ secrets.VERCEL_EXAMPLES_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"threadplane-examples"}
EOF
npx vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
npx vercel deploy --prebuilt --prod --yes --token=${{ secrets.VERCEL_TOKEN }}
Expand Down Expand Up @@ -536,13 +536,13 @@ jobs:
run: |
mkdir -p .vercel
cat > .vercel/project.json <<EOF
{"projectId":"${{ secrets.VERCEL_DEMO_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"demo"}
{"projectId":"${{ secrets.VERCEL_DEMO_PROJECT_ID }}","orgId":"${{ secrets.VERCEL_ORG_ID }}","projectName":"threadplane-demo"}
EOF
npx vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
npx vercel deploy --prebuilt --prod --yes --token=${{ secrets.VERCEL_TOKEN }}
- name: Verify canonical demo build stamp
env:
DEMO_URL: https://demo.cacheplane.ai
DEMO_URL: https://demo.threadplane.ai
EXPECTED_SHA: ${{ github.sha }}
run: |
node <<'NODE'
Expand Down Expand Up @@ -603,9 +603,9 @@ jobs:
- name: Run production smoke tests
run: npx playwright test apps/cockpit/e2e/production-smoke.spec.ts --reporter=list
env:
BASE_URL: https://cockpit.cacheplane.ai
EXAMPLES_URL: https://examples.cacheplane.ai
DEMO_URL: https://demo.cacheplane.ai
BASE_URL: https://cockpit.threadplane.ai
EXAMPLES_URL: https://examples.threadplane.ai
DEMO_URL: https://demo.threadplane.ai
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

posthog-sync-plan:
Expand Down
4 changes: 2 additions & 2 deletions COMMERCIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ The libraries in this repository (`@ngaf/langgraph`, `@ngaf/chat`, and all relat

## Minting Service

The cacheplane minting service (`apps/minting-service/`) is a proprietary internal service and is not covered by the MIT License. See `apps/minting-service/LICENSE` for its terms.
The ThreadPlane minting service (`apps/minting-service/`) is a proprietary internal service and is not covered by the MIT License. See `apps/minting-service/LICENSE` for its terms.

## Questions

- Website: https://cacheplane.ai
- Website: https://threadplane.ai
- Email: hello@cacheplane.ai
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p align="center">
<img
src="https://cacheplane.ai/assets/hero.svg"
src="https://threadplane.ai/assets/hero.svg"
alt="Agent UI for Angular — agent UI primitives for Angular"
width="100%"
/>
Expand Down Expand Up @@ -108,7 +108,7 @@ That's it. `chat.messages()` and `chat.status()` are Angular Signals. Bind them

<p align="center">
<img
src="https://cacheplane.ai/assets/arch-diagram.svg"
src="https://threadplane.ai/assets/arch-diagram.svg"
alt="Agent UI for Angular architecture: Angular Component → agent() → StreamManager Bridge → LangGraph Platform, with signals returned reactively"
width="100%"
/>
Expand All @@ -120,11 +120,11 @@ That's it. `chat.messages()` and `chat.status()` are Angular Signals. Bind them

## Documentation

- [Agent Quickstart](https://cacheplane.ai/docs/agent/getting-started/quickstart)
- [agent() API](https://cacheplane.ai/docs/agent/api/agent)
- [Chat Introduction](https://cacheplane.ai/docs/chat/getting-started/introduction)
- [Human-in-the-Loop / Interrupts](https://cacheplane.ai/docs/agent/guides/interrupts)
- [Subgraph and Subagent Streaming](https://cacheplane.ai/docs/agent/guides/subgraphs)
- [Agent Quickstart](https://threadplane.ai/docs/agent/getting-started/quickstart)
- [agent() API](https://threadplane.ai/docs/agent/api/agent)
- [Chat Introduction](https://threadplane.ai/docs/chat/getting-started/introduction)
- [Human-in-the-Loop / Interrupts](https://threadplane.ai/docs/agent/guides/interrupts)
- [Subgraph and Subagent Streaming](https://threadplane.ai/docs/agent/guides/subgraphs)

---

Expand Down
14 changes: 7 additions & 7 deletions apps/cockpit/e2e/production-smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import { expect, test } from '@playwright/test';
* example apps are reachable after production deploy.
*
* Requires:
* BASE_URL - e.g. https://cockpit.cacheplane.ai
* EXAMPLES_URL - e.g. https://examples.cacheplane.ai
* BASE_URL - e.g. https://cockpit.threadplane.ai
* EXAMPLES_URL - e.g. https://examples.threadplane.ai
* OPENAI_API_KEY - optional; enables the single live-provider canary
*
* Run:
* BASE_URL=https://cockpit.cacheplane.ai \
* EXAMPLES_URL=https://examples.cacheplane.ai \
* BASE_URL=https://cockpit.threadplane.ai \
* EXAMPLES_URL=https://examples.threadplane.ai \
* npx playwright test apps/cockpit/e2e/production-smoke.spec.ts
*/

const COCKPIT_URL = process.env['BASE_URL'] ?? 'https://cockpit.cacheplane.ai';
const COCKPIT_URL = process.env['BASE_URL'] ?? 'https://cockpit.threadplane.ai';
const EXAMPLES_URL =
process.env['EXAMPLES_URL'] ?? 'https://examples.cacheplane.ai';
const DEMO_URL = process.env['DEMO_URL'] ?? 'https://demo.cacheplane.ai';
process.env['EXAMPLES_URL'] ?? 'https://examples.threadplane.ai';
const DEMO_URL = process.env['DEMO_URL'] ?? 'https://demo.threadplane.ai';

const CHAT_CAPABILITIES = [
'langgraph/streaming',
Expand Down
12 changes: 6 additions & 6 deletions apps/cockpit/scripts/deploy-smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ describe('deploy smoke helper', () => {
expect(
parseDeploySmokeArgs([
'--url',
'https://cockpit.cacheplane.ai',
'https://cockpit.threadplane.ai',
'--dry-run',
'--retries',
'5',
'--retry-delay-ms',
'1000',
])
).toEqual({
url: 'https://cockpit.cacheplane.ai',
url: 'https://cockpit.threadplane.ai',
expectedTitle: 'Cockpit',
dryRun: true,
retries: 5,
Expand All @@ -25,11 +25,11 @@ describe('deploy smoke helper', () => {
it('formats dry-run output without performing a network request', async () => {
await expect(
runDeploySmoke({
url: 'https://cockpit.cacheplane.ai',
url: 'https://cockpit.threadplane.ai',
expectedTitle: 'Cockpit',
dryRun: true,
})
).resolves.toBe('dry-run:https://cockpit.cacheplane.ai:Cockpit');
).resolves.toBe('dry-run:https://cockpit.threadplane.ai:Cockpit');
});

it('retries until the deployment responds with the expected title', async () => {
Expand All @@ -46,13 +46,13 @@ describe('deploy smoke helper', () => {

await expect(
runDeploySmoke({
url: 'https://cockpit.cacheplane.ai',
url: 'https://cockpit.threadplane.ai',
retries: 1,
retryDelayMs: 1,
fetchImpl,
sleep,
})
).resolves.toBe('pass:https://cockpit.cacheplane.ai:Cockpit');
).resolves.toBe('pass:https://cockpit.threadplane.ai:Cockpit');

expect(fetchImpl).toHaveBeenCalledTimes(2);
expect(sleep).toHaveBeenCalledTimes(1);
Expand Down
2 changes: 1 addition & 1 deletion apps/cockpit/src/app/opengraph-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export default async function OpenGraphImage() {
}}
>
<span style={{ fontSize: 26 }}>🛩️</span>
<span>cockpit.cacheplane.ai</span>
<span>cockpit.threadplane.ai</span>
</div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions apps/cockpit/src/lib/content-bundle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ describe('resolveRuntimeUrl', () => {
});

it('uses NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL when set', () => {
vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.cacheplane.ai');
vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.threadplane.ai');
expect(
resolveRuntimeUrl({ runtimeUrl: 'langgraph/streaming', devPort: 4300 })
).toBe('https://examples.cacheplane.ai/langgraph/streaming');
).toBe('https://examples.threadplane.ai/langgraph/streaming');
});

it('falls back to localhost with devPort when no env var is set', () => {
Expand All @@ -49,7 +49,7 @@ describe('resolveRuntimeUrl', () => {
});

it('returns null when runtimeUrl is undefined even with env var set', () => {
vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.cacheplane.ai');
vi.stubEnv('NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL', 'https://examples.threadplane.ai');
expect(
resolveRuntimeUrl({ runtimeUrl: undefined, devPort: undefined })
).toBeNull();
Expand Down
2 changes: 1 addition & 1 deletion apps/cockpit/src/lib/content-bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function resolveRuntimeUrl(options: {
}

const baseUrl = process.env['NEXT_PUBLIC_COCKPIT_RUNTIME_BASE_URL']
?? 'https://examples.cacheplane.ai';
?? 'https://examples.threadplane.ai';

if (baseUrl && runtimeUrl) {
return `${baseUrl}/${runtimeUrl}`;
Expand Down
12 changes: 6 additions & 6 deletions apps/minting-service/LICENSE
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
Commercial License

Copyright (c) 2026 Brian Love d/b/a cacheplane. All rights reserved.
Copyright (c) 2026 Brian Love d/b/a ThreadPlane. All rights reserved.

This Commercial License ("License") governs commercial use of the
cacheplane minting service ("Software"), located in apps/minting-service/
ThreadPlane minting service ("Software"), located in apps/minting-service/
of the angular-agent-framework repository. This License applies solely to
the minting service component and does not govern any other part of the
repository, which is released separately under the MIT License.

Use of the Software for commercial purposes requires a valid license
purchased from cacheplane.
purchased from ThreadPlane.

--- LICENSE TIERS ---

Expand All @@ -34,7 +34,7 @@ purchased from cacheplane.

--- TERMS ---

Grant of License. Subject to payment of the applicable license fee, cacheplane
Grant of License. Subject to payment of the applicable license fee, ThreadPlane
grants you a non-exclusive, non-transferable, worldwide license to use,
reproduce, and distribute the Software solely as integrated into your
applications, in accordance with the scope of the purchased tier.
Expand All @@ -47,7 +47,7 @@ Restrictions. You may not:

No Redistribution. You may not distribute the Software or make it available
to third parties as a service, package, or SDK, whether modified or
unmodified, without a separate written agreement with cacheplane.
unmodified, without a separate written agreement with ThreadPlane.

Warranty Disclaimer. THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND. CACHEPLANE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
Expand All @@ -66,5 +66,5 @@ Deschutes County, United States, without regard to conflict of law principles.
--- PURCHASING ---

To purchase a license or inquire about Enterprise terms:
Website: https://cacheplane.ai/pricing
Website: https://threadplane.ai/pricing
Email: hello@cacheplane.ai
2 changes: 1 addition & 1 deletion apps/minting-service/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @cacheplane/minting-service

License minting service for Cacheplane. Receives Stripe webhooks, signs
License minting service for ThreadPlane. Receives Stripe webhooks, signs
Ed25519 license tokens via `@cacheplane/licensing`, persists them to
Postgres via `@cacheplane/db`, and emails them to customers via Resend.

Expand Down
4 changes: 2 additions & 2 deletions apps/minting-service/src/lib/email.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('renderLicenseEmail', () => {
token: 't.s',
expiresAt: new Date('2027-04-20T00:00:00Z'),
});
expect(out.subject).toBe('Your Cacheplane license — developer-seat (3 seats)');
expect(out.subject).toBe('Your ThreadPlane license — developer-seat (3 seats)');
});

it('subject uses singular seat for seats === 1', () => {
Expand All @@ -32,7 +32,7 @@ describe('renderLicenseEmail', () => {
token: 't.s',
expiresAt: new Date('2027-04-20T00:00:00Z'),
});
expect(out.subject).toBe('Your Cacheplane license — app-deployment (1 seat)');
expect(out.subject).toBe('Your ThreadPlane license — app-deployment (1 seat)');
});

it('includes ISO 8601 UTC expiry in text body', () => {
Expand Down
14 changes: 7 additions & 7 deletions apps/minting-service/src/lib/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ export interface RenderedEmail {
*/
export function renderLicenseEmail(vars: LicenseEmailVars): RenderedEmail {
const seatWord = vars.seats === 1 ? 'seat' : 'seats';
const subject = `Your Cacheplane license — ${vars.tier} (${vars.seats} ${seatWord})`;
const subject = `Your ThreadPlane license — ${vars.tier} (${vars.seats} ${seatWord})`;
const expiresIso = vars.expiresAt.toISOString();

const text = `Thanks for subscribing to Cacheplane.
const text = `Thanks for subscribing to ThreadPlane.

Your license token is below. Set it as the CACHEPLANE_LICENSE
environment variable in your application:
Expand All @@ -42,13 +42,13 @@ Installation:
Or in a .env file:
CACHEPLANE_LICENSE=<paste token above>

Docs: https://cacheplane.dev/docs/licensing
Docs: https://threadplane.ai/docs/licensing
Questions: reply to this email.

-- The Cacheplane team
-- The ThreadPlane team
`;

const html = `<p>Thanks for subscribing to Cacheplane.</p>
const html = `<p>Thanks for subscribing to ThreadPlane.</p>
<p>Your license token is below. Set it as the <code>CACHEPLANE_LICENSE</code> environment variable in your application:</p>
<pre style="white-space:pre-wrap;word-break:break-all;font-family:monospace;font-size:12px;background:#f4f4f4;padding:12px;border-radius:4px">-----BEGIN CACHEPLANE LICENSE-----
${escapeHtml(vars.token)}
Expand All @@ -58,9 +58,9 @@ ${escapeHtml(vars.token)}
<strong>Expires:</strong> ${escapeHtml(expiresIso)}</p>
<p><strong>Installation:</strong></p>
<pre style="font-family:monospace;font-size:12px;background:#f4f4f4;padding:12px;border-radius:4px">export CACHEPLANE_LICENSE="&lt;paste token above&gt;"</pre>
<p>Docs: <a href="https://cacheplane.dev/docs/licensing">cacheplane.dev/docs/licensing</a><br>
<p>Docs: <a href="https://threadplane.ai/docs/licensing">threadplane.ai/docs/licensing</a><br>
Questions: reply to this email.</p>
<p>-- The Cacheplane team</p>
<p>-- The ThreadPlane team</p>
`;

return { subject, text, html };
Expand Down
2 changes: 1 addition & 1 deletion apps/minting-service/src/lib/tier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export type MintableTier = Extract<LicenseTier, 'developer-seat' | 'app-deployme
const VALID_TIERS: readonly MintableTier[] = ['developer-seat', 'app-deployment'] as const;

/**
* Extract the Cacheplane tier from a Stripe price metadata bag.
* Extract the ThreadPlane tier from a Stripe price metadata bag.
* Throws if the field is missing or holds an unknown value.
*/
export function extractTier(metadata: Record<string, string> | null | undefined): MintableTier {
Expand Down
2 changes: 1 addition & 1 deletion apps/website/content/AGENTS.md.template
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ export class ChatComponent {
- Testing: use `MockAgentTransport` — never mock `agent()` itself

## Version check
If this file is stale, fetch the latest: https://cacheplane.ai/llms-full.txt
If this file is stale, fetch the latest: https://threadplane.ai/llms-full.txt
2 changes: 1 addition & 1 deletion apps/website/content/CLAUDE.md.template
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ export class ChatComponent {
- Testing: use `MockAgentTransport` — never mock `agent()` itself

## Version check
If this file is stale, fetch the latest: https://cacheplane.ai/llms-full.txt
If this file is stale, fetch the latest: https://threadplane.ai/llms-full.txt
2 changes: 1 addition & 1 deletion apps/website/content/docs/agent/api/api-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@
{
"name": "license",
"type": "string",
"description": "Signed license token from cacheplane.dev. Optional; omitted in dev.",
"description": "Signed license token from threadplane.ai. Optional; omitted in dev.",
"optional": true
},
{
Expand Down
2 changes: 1 addition & 1 deletion apps/website/content/docs/chat/api/api-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -5555,7 +5555,7 @@
{
"name": "license",
"type": "string",
"description": "Signed license token from cacheplane.dev. Optional; omitted in dev.",
"description": "Signed license token from threadplane.ai. Optional; omitted in dev.",
"optional": true
},
{
Expand Down
Loading
Loading