third-audience-mdx 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +41 -0
- package/INSTALLATION.md +367 -0
- package/README.md +303 -0
- package/WORKLOG.md +162 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +208 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +185 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/dashboard/auth.d.mts +16 -0
- package/dist/dashboard/auth.d.ts +16 -0
- package/dist/dashboard/auth.js +123 -0
- package/dist/dashboard/auth.js.map +1 -0
- package/dist/dashboard/auth.mjs +87 -0
- package/dist/dashboard/auth.mjs.map +1 -0
- package/dist/dashboard/routes/analytics-api-route.d.mts +6 -0
- package/dist/dashboard/routes/analytics-api-route.d.ts +6 -0
- package/dist/dashboard/routes/analytics-api-route.js +180 -0
- package/dist/dashboard/routes/analytics-api-route.js.map +1 -0
- package/dist/dashboard/routes/analytics-api-route.mjs +145 -0
- package/dist/dashboard/routes/analytics-api-route.mjs.map +1 -0
- package/dist/dashboard/routes/api-key-route.d.mts +8 -0
- package/dist/dashboard/routes/api-key-route.d.ts +8 -0
- package/dist/dashboard/routes/api-key-route.js +173 -0
- package/dist/dashboard/routes/api-key-route.js.map +1 -0
- package/dist/dashboard/routes/api-key-route.mjs +137 -0
- package/dist/dashboard/routes/api-key-route.mjs.map +1 -0
- package/dist/dashboard/routes/citation-route.d.mts +14 -0
- package/dist/dashboard/routes/citation-route.d.ts +14 -0
- package/dist/dashboard/routes/citation-route.js +202 -0
- package/dist/dashboard/routes/citation-route.js.map +1 -0
- package/dist/dashboard/routes/citation-route.mjs +166 -0
- package/dist/dashboard/routes/citation-route.mjs.map +1 -0
- package/dist/dashboard/routes/llms-txt-route.d.mts +6 -0
- package/dist/dashboard/routes/llms-txt-route.d.ts +6 -0
- package/dist/dashboard/routes/llms-txt-route.js +119 -0
- package/dist/dashboard/routes/llms-txt-route.js.map +1 -0
- package/dist/dashboard/routes/llms-txt-route.mjs +84 -0
- package/dist/dashboard/routes/llms-txt-route.mjs.map +1 -0
- package/dist/dashboard/routes/login-route.d.mts +6 -0
- package/dist/dashboard/routes/login-route.d.ts +6 -0
- package/dist/dashboard/routes/login-route.js +313 -0
- package/dist/dashboard/routes/login-route.js.map +1 -0
- package/dist/dashboard/routes/login-route.mjs +284 -0
- package/dist/dashboard/routes/login-route.mjs.map +1 -0
- package/dist/dashboard/routes/markdown-route.d.mts +15 -0
- package/dist/dashboard/routes/markdown-route.d.ts +15 -0
- package/dist/dashboard/routes/markdown-route.js +239 -0
- package/dist/dashboard/routes/markdown-route.js.map +1 -0
- package/dist/dashboard/routes/markdown-route.mjs +204 -0
- package/dist/dashboard/routes/markdown-route.mjs.map +1 -0
- package/dist/dashboard/routes/okf-route.d.mts +13 -0
- package/dist/dashboard/routes/okf-route.d.ts +13 -0
- package/dist/dashboard/routes/okf-route.js +184 -0
- package/dist/dashboard/routes/okf-route.js.map +1 -0
- package/dist/dashboard/routes/okf-route.mjs +149 -0
- package/dist/dashboard/routes/okf-route.mjs.map +1 -0
- package/dist/dashboard/routes/sitemap-ai-route.d.mts +6 -0
- package/dist/dashboard/routes/sitemap-ai-route.d.ts +6 -0
- package/dist/dashboard/routes/sitemap-ai-route.js +134 -0
- package/dist/dashboard/routes/sitemap-ai-route.js.map +1 -0
- package/dist/dashboard/routes/sitemap-ai-route.mjs +99 -0
- package/dist/dashboard/routes/sitemap-ai-route.mjs.map +1 -0
- package/dist/dashboard/ui/components/Sidebar.d.mts +5 -0
- package/dist/dashboard/ui/components/Sidebar.d.ts +5 -0
- package/dist/dashboard/ui/components/Sidebar.js +102 -0
- package/dist/dashboard/ui/components/Sidebar.js.map +1 -0
- package/dist/dashboard/ui/components/Sidebar.mjs +68 -0
- package/dist/dashboard/ui/components/Sidebar.mjs.map +1 -0
- package/dist/dashboard/ui/globals.css +175 -0
- package/dist/dashboard/ui/pages/BotAnalyticsPage.d.mts +5 -0
- package/dist/dashboard/ui/pages/BotAnalyticsPage.d.ts +5 -0
- package/dist/dashboard/ui/pages/BotAnalyticsPage.js +269 -0
- package/dist/dashboard/ui/pages/BotAnalyticsPage.js.map +1 -0
- package/dist/dashboard/ui/pages/BotAnalyticsPage.mjs +232 -0
- package/dist/dashboard/ui/pages/BotAnalyticsPage.mjs.map +1 -0
- package/dist/dashboard/ui/pages/BotManagementPage.d.mts +13 -0
- package/dist/dashboard/ui/pages/BotManagementPage.d.ts +13 -0
- package/dist/dashboard/ui/pages/BotManagementPage.js +177 -0
- package/dist/dashboard/ui/pages/BotManagementPage.js.map +1 -0
- package/dist/dashboard/ui/pages/BotManagementPage.mjs +153 -0
- package/dist/dashboard/ui/pages/BotManagementPage.mjs.map +1 -0
- package/dist/dashboard/ui/pages/LlmTrafficPage.d.mts +5 -0
- package/dist/dashboard/ui/pages/LlmTrafficPage.d.ts +5 -0
- package/dist/dashboard/ui/pages/LlmTrafficPage.js +203 -0
- package/dist/dashboard/ui/pages/LlmTrafficPage.js.map +1 -0
- package/dist/dashboard/ui/pages/LlmTrafficPage.mjs +168 -0
- package/dist/dashboard/ui/pages/LlmTrafficPage.mjs.map +1 -0
- package/dist/dashboard/ui/pages/SettingsPage.d.mts +8 -0
- package/dist/dashboard/ui/pages/SettingsPage.d.ts +8 -0
- package/dist/dashboard/ui/pages/SettingsPage.js +181 -0
- package/dist/dashboard/ui/pages/SettingsPage.js.map +1 -0
- package/dist/dashboard/ui/pages/SettingsPage.mjs +157 -0
- package/dist/dashboard/ui/pages/SettingsPage.mjs.map +1 -0
- package/dist/dashboard/ui/pages/SystemHealthPage.d.mts +5 -0
- package/dist/dashboard/ui/pages/SystemHealthPage.d.ts +5 -0
- package/dist/dashboard/ui/pages/SystemHealthPage.js +183 -0
- package/dist/dashboard/ui/pages/SystemHealthPage.js.map +1 -0
- package/dist/dashboard/ui/pages/SystemHealthPage.mjs +148 -0
- package/dist/dashboard/ui/pages/SystemHealthPage.mjs.map +1 -0
- package/dist/index.d.mts +84 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.js +372 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +346 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +125 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Project Rules
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
- Everything in this project's sessions stays inside THIS project folder only.
|
|
5
|
+
- Never create, modify, or move files outside this folder for this project's work.
|
|
6
|
+
- Whatever is typed in a session is scoped to this project — no spillover to other projects.
|
|
7
|
+
|
|
8
|
+
## Worklog
|
|
9
|
+
- After every meaningful task, append to WORKLOG.md: date, what was asked, what was done, files touched.
|
|
10
|
+
|
|
11
|
+
## Global Rules
|
|
12
|
+
- No deviation from the plan. No mock data.
|
|
13
|
+
- No database changes — no insert, no update, no delete, no drop. Query only.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Execution: Ultracode & Workflows
|
|
18
|
+
|
|
19
|
+
- **Ultracode** is a session-scoped effort setting (`/effort ultracode`) that pairs max (xhigh) reasoning with automatic multi-agent workflow orchestration. Only the user can turn it on. When on, default to authoring and running a workflow for every substantive task (often several in sequence: understand → design → implement → review). Token cost is not a constraint in that mode. Drop back with `/effort high` or `/effort xhigh`.
|
|
20
|
+
|
|
21
|
+
- **Dynamic Workflows** are JavaScript scripts that orchestrate many subagents deterministically (primitives: `agent()`, `pipeline()` [default, no barrier], `parallel()` [barrier], `phase()`, `log()`, `budget()`). Intermediate results live in script variables, not context. Runs in the background; watch/control via `/workflows`. Default to `pipeline()`; use a barrier only for a genuine cross-item dependency (dedup/merge-all, early-exit on zero, cross-finding comparison). Caps: ~16 concurrent agents, 1000 per run.
|
|
22
|
+
|
|
23
|
+
- Even when ultracode is **OFF**, reach for a workflow WITHOUT asking when a task is clearly multi-part and parallelizable AND large enough to justify it — e.g. codebase-wide audits or bug sweeps, large migrations/refactors across many files, multi-source research, or drafting/comparing several independent plans. For anything smaller (single-file edits, quick fixes, one-off questions), just do it directly or use a single Agent. When unsure, briefly say what you'd run and roughly what it'd cost, then ask.
|
|
24
|
+
|
|
25
|
+
- Useful quality patterns to compose inside workflows: adversarial/perspective-diverse verification, judge panels, loop-until-dry discovery, multi-modal sweeps, and a final completeness critic. Never silently cap coverage — `log()` anything dropped.
|
|
26
|
+
|
|
27
|
+
- One-off workflow trigger: the keyword `ultracode` in a message, or "use a workflow".
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Discipline: Verify, Don't Guess
|
|
32
|
+
|
|
33
|
+
- You cannot see what the user sees. When you change anything with a visible or runnable result — UI, layout, rendered page, a chart, generated output, a file — editing the code is NOT evidence the result is correct. Do not reason that it "should look fixed" and report success.
|
|
34
|
+
|
|
35
|
+
- Before claiming any such change works: actually produce the result and inspect it. Open the browser, run the thing, open the file, take a screenshot — then do a genuine, critical look, hunting for what is still broken rather than confirming your own work.
|
|
36
|
+
|
|
37
|
+
- Never say "it looks fixed now," "that's resolved," or "done" on the strength of reasoning alone. If the actual result has not been observed, say exactly that: "I changed X; I have not verified the result yet."
|
|
38
|
+
|
|
39
|
+
- This generalizes past visuals: tests are not passing until you have run them, a build is not working until it built, a bug is not fixed until you have reproduced the original failure and watched it stop. Prefer observed truth over inferred truth every time you can observe.
|
|
40
|
+
|
|
41
|
+
- When you genuinely cannot verify (no browser, no way to run it), do not fake confidence. State the limitation, say what you would check, and tell the user exactly what to look at.
|
package/INSTALLATION.md
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
# Installation Guide
|
|
2
|
+
|
|
3
|
+
Complete step-by-step guide for adding `third-audience-mdx` to an existing Next.js App Router project.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- Node.js 18+
|
|
10
|
+
- Next.js 13+ (App Router)
|
|
11
|
+
- MDX content files (`.mdx` or `.md`) in a content directory
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Step 1 — Install the package
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install third-audience-mdx
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or with pnpm / yarn:
|
|
22
|
+
```bash
|
|
23
|
+
pnpm add third-audience-mdx
|
|
24
|
+
yarn add third-audience-mdx
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Step 2 — Run the setup wizard (recommended)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx third-audience init
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The wizard will:
|
|
36
|
+
1. Detect your Next.js project
|
|
37
|
+
2. Ask for your content directory (e.g. `content`)
|
|
38
|
+
3. Ask for your data directory (e.g. `data`)
|
|
39
|
+
4. Ask for a dashboard secret
|
|
40
|
+
5. Write `middleware.ts` if it doesn't exist
|
|
41
|
+
6. Append to `.env.local`
|
|
42
|
+
7. Create the `data/` directory and update `.gitignore`
|
|
43
|
+
|
|
44
|
+
After the wizard, skip to [Step 6 — Add API routes](#step-6--add-api-routes).
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Step 3 — Wrap your Next.js config
|
|
49
|
+
|
|
50
|
+
**`next.config.ts`**
|
|
51
|
+
```ts
|
|
52
|
+
import { withThirdAudience } from 'third-audience-mdx'
|
|
53
|
+
import type { NextConfig } from 'next'
|
|
54
|
+
|
|
55
|
+
const nextConfig: NextConfig = {
|
|
56
|
+
// your existing config here
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default withThirdAudience(
|
|
60
|
+
{
|
|
61
|
+
contentDir: 'content', // folder where your .mdx files live
|
|
62
|
+
dataDir: 'data', // folder for analytics logs
|
|
63
|
+
dashboard: true,
|
|
64
|
+
dashboardSecret: process.env.THIRD_AUDIENCE_SECRET,
|
|
65
|
+
},
|
|
66
|
+
nextConfig
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Step 4 — Add middleware
|
|
73
|
+
|
|
74
|
+
Create (or update) **`middleware.ts`** in your project root:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
export { thirdAudienceMiddleware as middleware } from 'third-audience-mdx'
|
|
78
|
+
|
|
79
|
+
export const config = {
|
|
80
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This handles:
|
|
85
|
+
- `GET /any-page.md` → serves Markdown of the matching MDX file
|
|
86
|
+
- `Accept: text/markdown` header → serves Markdown automatically
|
|
87
|
+
- `/llms.txt`, `/sitemap-ai.xml`, `/okf/` → rewrites to the correct API handlers
|
|
88
|
+
|
|
89
|
+
If you already have a `middleware.ts`, call `thirdAudienceMiddleware` inside your existing function and return its result when it produces a response.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Step 5 — Set environment variables
|
|
94
|
+
|
|
95
|
+
**`.env.local`**
|
|
96
|
+
```
|
|
97
|
+
# Required
|
|
98
|
+
THIRD_AUDIENCE_SECRET=choose-a-strong-secret-here
|
|
99
|
+
NEXT_PUBLIC_SITE_URL=https://yoursite.com
|
|
100
|
+
|
|
101
|
+
# Optional (defaults shown)
|
|
102
|
+
TA_CONTENT_DIR=content
|
|
103
|
+
TA_DATA_DIR=data
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`THIRD_AUDIENCE_SECRET` protects the `/third-audience/` dashboard. Leave it blank only during local development.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Step 6 — Add API routes
|
|
111
|
+
|
|
112
|
+
Create these files inside your `app/` directory. Each one is a one-liner that re-exports the handler from the package.
|
|
113
|
+
|
|
114
|
+
**`app/api/third-audience/markdown/[...slug]/route.ts`**
|
|
115
|
+
```ts
|
|
116
|
+
export { GET } from 'third-audience-mdx/routes/markdown'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**`app/api/third-audience/okf/[...path]/route.ts`**
|
|
120
|
+
```ts
|
|
121
|
+
export { GET } from 'third-audience-mdx/routes/okf'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**`app/api/third-audience/llms-txt/route.ts`**
|
|
125
|
+
```ts
|
|
126
|
+
export { GET } from 'third-audience-mdx/routes/llms-txt'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**`app/api/third-audience/sitemap-ai/route.ts`**
|
|
130
|
+
```ts
|
|
131
|
+
export { GET } from 'third-audience-mdx/routes/sitemap-ai'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**`app/api/third-audience/citation/route.ts`**
|
|
135
|
+
```ts
|
|
136
|
+
export { GET, POST } from 'third-audience-mdx/routes/citation'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**`app/api/third-audience/analytics/route.ts`**
|
|
140
|
+
```ts
|
|
141
|
+
export { GET } from 'third-audience-mdx/routes/analytics'
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**`app/api/third-audience/bots-config/route.ts`**
|
|
145
|
+
```ts
|
|
146
|
+
export { GET, POST } from 'third-audience-mdx/routes/bots-config'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Step 7 — Add the dashboard
|
|
152
|
+
|
|
153
|
+
Create these files to mount the dashboard at `/third-audience/`.
|
|
154
|
+
|
|
155
|
+
**`app/third-audience/layout.tsx`**
|
|
156
|
+
```tsx
|
|
157
|
+
import type { ReactNode } from 'react'
|
|
158
|
+
import { Sidebar } from 'third-audience-mdx/dashboard/ui/components/Sidebar'
|
|
159
|
+
import 'third-audience-mdx/dashboard/ui/globals.css'
|
|
160
|
+
|
|
161
|
+
export const metadata = { title: 'Third Audience Dashboard' }
|
|
162
|
+
|
|
163
|
+
export default function DashboardLayout({ children }: { children: ReactNode }) {
|
|
164
|
+
return (
|
|
165
|
+
<html lang="en">
|
|
166
|
+
<body>
|
|
167
|
+
<div className="ta-layout">
|
|
168
|
+
<Sidebar />
|
|
169
|
+
<main className="ta-main">{children}</main>
|
|
170
|
+
</div>
|
|
171
|
+
</body>
|
|
172
|
+
</html>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**`app/third-audience/page.tsx`** — Bot Analytics
|
|
178
|
+
```tsx
|
|
179
|
+
import { BotAnalyticsPage } from 'third-audience-mdx/dashboard/ui/pages/BotAnalyticsPage'
|
|
180
|
+
export const dynamic = 'force-dynamic'
|
|
181
|
+
export default function Page() { return <BotAnalyticsPage /> }
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**`app/third-audience/citations/page.tsx`** — LLM Traffic
|
|
185
|
+
```tsx
|
|
186
|
+
import { LlmTrafficPage } from 'third-audience-mdx/dashboard/ui/pages/LlmTrafficPage'
|
|
187
|
+
export const dynamic = 'force-dynamic'
|
|
188
|
+
export default function Page() { return <LlmTrafficPage /> }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**`app/third-audience/bots/page.tsx`** — Bot Management
|
|
192
|
+
```tsx
|
|
193
|
+
import { BotManagementPage } from 'third-audience-mdx/dashboard/ui/pages/BotManagementPage'
|
|
194
|
+
import fs from 'fs'
|
|
195
|
+
import path from 'path'
|
|
196
|
+
export const dynamic = 'force-dynamic'
|
|
197
|
+
|
|
198
|
+
export default function Page() {
|
|
199
|
+
const dataDir = process.env.TA_DATA_DIR ?? 'data'
|
|
200
|
+
const configPath = path.join(process.cwd(), dataDir, 'ta-bots-config.json')
|
|
201
|
+
const config = fs.existsSync(configPath)
|
|
202
|
+
? JSON.parse(fs.readFileSync(configPath, 'utf-8'))
|
|
203
|
+
: { allowlist: [], blocklist: [], track_unknown: true }
|
|
204
|
+
return <BotManagementPage config={config} />
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**`app/third-audience/health/page.tsx`** — System Health
|
|
209
|
+
```tsx
|
|
210
|
+
import { SystemHealthPage } from 'third-audience-mdx/dashboard/ui/pages/SystemHealthPage'
|
|
211
|
+
export const dynamic = 'force-dynamic'
|
|
212
|
+
export default function Page() { return <SystemHealthPage /> }
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Step 8 — Add client-side citation tracker
|
|
218
|
+
|
|
219
|
+
Copy the script to your public folder:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
cp node_modules/third-audience-mdx/src/public/citation-tracker.js public/citation-tracker.js
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Add to your root layout (`app/layout.tsx`):
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
229
|
+
return (
|
|
230
|
+
<html lang="en">
|
|
231
|
+
<body>
|
|
232
|
+
{children}
|
|
233
|
+
<script src="/citation-tracker.js" async />
|
|
234
|
+
</body>
|
|
235
|
+
</html>
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
This detects when users arrive from ChatGPT, Perplexity, Claude, Gemini, or Copilot and records the citation.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Step 9 — Set up admin login
|
|
245
|
+
|
|
246
|
+
The dashboard at `/third-audience/` is protected by a login page. On first access, initialise the admin store:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npx third-audience init-admin
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Or run the Node snippet manually:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
node -e "
|
|
256
|
+
const crypto = require('crypto');
|
|
257
|
+
const fs = require('fs');
|
|
258
|
+
const secret = process.env.THIRD_AUDIENCE_SECRET || 'ta-salt';
|
|
259
|
+
const password = 'Chang3M3Now!';
|
|
260
|
+
const hash = crypto.createHash('sha256').update(secret + password).digest('hex');
|
|
261
|
+
fs.mkdirSync('data', { recursive: true });
|
|
262
|
+
fs.writeFileSync('data/ta-admin.json', JSON.stringify({
|
|
263
|
+
passwordHash: hash,
|
|
264
|
+
isDefaultPassword: true,
|
|
265
|
+
createdAt: new Date().toISOString(),
|
|
266
|
+
lastLoginAt: null
|
|
267
|
+
}, null, 2));
|
|
268
|
+
console.log('Admin store created. Default password: Chang3M3Now!');
|
|
269
|
+
"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Default password: `Chang3M3Now!`**
|
|
273
|
+
|
|
274
|
+
On first login you will be immediately redirected to a password reset form. The dashboard shows a red warning banner until the default password is changed.
|
|
275
|
+
|
|
276
|
+
Add the login route:
|
|
277
|
+
|
|
278
|
+
**`app/api/third-audience/login/route.ts`**
|
|
279
|
+
```ts
|
|
280
|
+
export { GET, POST } from 'third-audience-mdx/routes/login'
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Step 10 — Update `.gitignore`
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
# Third Audience — keep analytics local, not in git
|
|
289
|
+
data/ta-visits.jsonl
|
|
290
|
+
data/ta-citations.jsonl
|
|
291
|
+
data/ta-cache/
|
|
292
|
+
data/ta-admin.json
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
The `data/ta-bots-config.json` file (your allowlist/blocklist) can optionally be committed.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Step 10 — Verify everything works
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
npx third-audience health
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Then start your dev server and check:
|
|
306
|
+
|
|
307
|
+
| URL | Expected |
|
|
308
|
+
|---|---|
|
|
309
|
+
| `/llms.txt` | Plain text list of all your content |
|
|
310
|
+
| `/sitemap-ai.xml` | XML sitemap with AI metadata |
|
|
311
|
+
| `/okf/` | Markdown index of all content |
|
|
312
|
+
| `/your-first-post.md` | Clean Markdown of that MDX file |
|
|
313
|
+
| `/third-audience/` | Bot Analytics dashboard |
|
|
314
|
+
| `/third-audience/health` | System Health page |
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Troubleshooting
|
|
319
|
+
|
|
320
|
+
**`.md` URLs return 404**
|
|
321
|
+
Make sure `middleware.ts` is at the project root (not inside `app/`) and the matcher covers the URL pattern.
|
|
322
|
+
|
|
323
|
+
**Dashboard shows no data**
|
|
324
|
+
Bot visits only appear after a real AI crawler hits your site. Use `curl -A "ClaudeBot/1.0" http://localhost:3000/` to simulate one.
|
|
325
|
+
|
|
326
|
+
**`contentDir` not found**
|
|
327
|
+
Set `TA_CONTENT_DIR` in `.env.local` to the correct path relative to your project root.
|
|
328
|
+
|
|
329
|
+
**Citation tracker not recording**
|
|
330
|
+
Confirm `citation-tracker.js` is in `public/` and the `<script>` tag is in your root layout. Test by visiting your site with `?utm_source=chatgpt` appended to the URL.
|
|
331
|
+
|
|
332
|
+
**Dashboard is open (no auth)**
|
|
333
|
+
Set `THIRD_AUDIENCE_SECRET` in `.env.local` and restart the dev server.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Directory structure after setup
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
your-nextjs-project/
|
|
341
|
+
├── app/
|
|
342
|
+
│ ├── api/
|
|
343
|
+
│ │ └── third-audience/
|
|
344
|
+
│ │ ├── analytics/route.ts
|
|
345
|
+
│ │ ├── bots-config/route.ts
|
|
346
|
+
│ │ ├── citation/route.ts
|
|
347
|
+
│ │ ├── llms-txt/route.ts
|
|
348
|
+
│ │ ├── markdown/[...slug]/route.ts
|
|
349
|
+
│ │ ├── okf/[...path]/route.ts
|
|
350
|
+
│ │ └── sitemap-ai/route.ts
|
|
351
|
+
│ ├── third-audience/
|
|
352
|
+
│ │ ├── layout.tsx
|
|
353
|
+
│ │ ├── page.tsx
|
|
354
|
+
│ │ ├── citations/page.tsx
|
|
355
|
+
│ │ ├── bots/page.tsx
|
|
356
|
+
│ │ └── health/page.tsx
|
|
357
|
+
│ └── layout.tsx ← add citation-tracker.js <script> here
|
|
358
|
+
├── public/
|
|
359
|
+
│ └── citation-tracker.js ← copied from node_modules
|
|
360
|
+
├── data/ ← created by init wizard
|
|
361
|
+
│ ├── ta-visits.jsonl
|
|
362
|
+
│ ├── ta-citations.jsonl
|
|
363
|
+
│ └── ta-cache/
|
|
364
|
+
├── middleware.ts
|
|
365
|
+
├── next.config.ts
|
|
366
|
+
└── .env.local
|
|
367
|
+
```
|