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
5 changes: 5 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"enabledPlugins": {
"doc-detective@doc-detective": true
}
}
23 changes: 23 additions & 0 deletions .doc-detective.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"input": [
"src/content/docs/docs/integrations/slack-integration.mdx",
"src/content/docs/docs/getting-started/setup-quickstart.mdx"
],
"output": ".doc-detective/results",
"recursive": true,
"origin": "https://promptless.ai",
"detectSteps": false,
"loadVariables": ".doc-detective/.env",
"beforeAny": ".doc-detective/tests/login.spec.json",
"runOn": [
{
"platforms": ["mac"],
"browsers": [
{
"name": "chrome",
"headless": false
}
]
}
]
}
4 changes: 4 additions & 0 deletions .doc-detective/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Doc Detective test credentials
# Copy this to .env and fill in your test account values
PROMPTLESS_TEST_EMAIL=your-test-user@example.com
PROMPTLESS_TEST_PASSWORD=your-test-password
67 changes: 67 additions & 0 deletions .doc-detective/extract-cookies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env node

// Extract cookies from a running Chrome instance for Doc Detective.
//
// Usage:
// 1. Quit Chrome completely
// 2. Relaunch Chrome with remote debugging:
// /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
// 3. Sign in to app.gopromptless.ai in that Chrome window
// 4. Run this script: node .doc-detective/extract-cookies.js
//
// This writes cookies in Netscape format to .doc-detective/session-cookies.txt
// which Doc Detective can load via the loadCookie action.

const puppeteer = require('puppeteer-core');
const fs = require('fs');
const path = require('path');

const OUTPUT_PATH = path.join(__dirname, 'session-cookies.txt');
const URLS = [
'https://app.gopromptless.ai',
'https://accounts.gopromptless.ai',
];

async function extractCookies() {
let browser;
try {
browser = await puppeteer.connect({ browserURL: 'http://127.0.0.1:9222' });
} catch (err) {
console.error('Could not connect to Chrome on port 9222.');
console.error('Launch Chrome with: /Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --remote-debugging-port=9222');
process.exit(1);
}

const page = (await browser.pages())[0];

const allCookies = [];
for (const url of URLS) {
const cookies = await page.cookies(url);
allCookies.push(...cookies);
}

// Deduplicate by name+domain
const seen = new Set();
const unique = allCookies.filter((c) => {
const key = `${c.name}|${c.domain}`;
if (seen.has(key)) return false;
seen.add(key);
return true;
});

// Write Netscape cookie format
const lines = unique.map(
(c) =>
`${c.domain}\tTRUE\t${c.path}\t${c.secure ? 'TRUE' : 'FALSE'}\t${Math.floor(c.expires)}\t${c.name}\t${c.value}`
);
const content = '# Netscape HTTP Cookie File\n' + lines.join('\n') + '\n';
fs.writeFileSync(OUTPUT_PATH, content);

console.log(`Exported ${unique.length} cookies to ${OUTPUT_PATH}`);
browser.disconnect();
}

extractCookies().catch((err) => {
console.error('Error:', err.message);
process.exit(1);
});
56 changes: 56 additions & 0 deletions .doc-detective/tests/login.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"tests": [
{
"testId": "clerk-login",
"description": "Sign in to Promptless with test credentials",
"steps": [
{
"description": "Navigate to the sign-in page",
"goTo": "https://accounts.gopromptless.ai/sign-in"
},
{
"description": "Click the email input",
"find": {
"selector": "#identifier-field",
"click": true
}
},
{
"description": "Type the test email",
"type": "$PROMPTLESS_TEST_EMAIL"
},
{
"description": "Click Continue after email",
"find": {
"selector": "button.cl-formButtonPrimary",
"click": true,
"timeout": 5000
}
},
{
"description": "Click the password input",
"find": {
"selector": "#password-field",
"click": true
}
},
{
"description": "Type the test password",
"type": "$PROMPTLESS_TEST_PASSWORD"
},
{
"description": "Click Continue to sign in",
"find": {
"selector": "button.cl-formButtonPrimary",
"click": true,
"timeout": 5000
}
},
{
"description": "Wait for sign-in to complete",
"wait": 5000
}
]
}
]
}
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Dependencies
/node_modules

# Doc Detective secrets and results
.doc-detective/.env
.doc-detective/session-cookies.txt
.doc-detective/results/

# Production
/build
/dist
Expand Down
27 changes: 27 additions & 0 deletions bootstrap.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env nu

# check .doc-detective/.env exists and has real values

let f = ".doc-detective/.env"

if not ($f | path exists) {
error make {msg: $"($f): no such file; cp .doc-detective/.env.example ($f) and edit"}
}

let vars = (open $f
| lines
| where {|l| $l !~ '^\s*#' and $l =~ '='}
| each {|l| $l | parse "{k}={v}" | get 0}
| reduce -f {} {|it, acc| $acc | merge {($it.k): $it.v}}
)

for want in [PROMPTLESS_TEST_EMAIL PROMPTLESS_TEST_PASSWORD] {
if $want not-in $vars {
error make {msg: $"($f): ($want) not set"}
}
if ($vars | get $want) in ["" "your-test-user@example.com" "your-test-password"] {
error make {msg: $"($f): ($want) still has placeholder value"}
}
}

print "env ok"
11 changes: 10 additions & 1 deletion src/content/docs/docs/getting-started/setup-quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ sidebar:
import HowItWorks from '@components/site/HowItWorks.astro';
import Success from '@components/fern/Success.astro';

Promptless automatically updates your docs, saving your team time and improving your customer experience.
{/* test {"testId": "setup-quickstart-content"} */}
{/* step {"goTo": "https://promptless.ai/docs/getting-started/setup-quickstart"} */}
{/* step {"find": "Setup & Quickstart"} */}

Promptless automatically updates your docs, saving your team time and improving your customer experience.

{/* step {"find": "Before You Start"} */}
## Before You Start

Sign up for a free account at [accounts.gopromptless.ai](https://accounts.gopromptless.ai)

{/* step {"find": "Guided Setup Wizard"} */}
## Guided Setup Wizard

{/* step {"find": "Connect Slack"} */}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have more steps eg connect docs, configure triggers, adjust HLC etc

When you first sign in, a 6-step wizard guides you through setup:

<HowItWorks
Expand Down Expand Up @@ -58,6 +65,7 @@ When you first sign in, a 6-step wizard guides you through setup:

Your progress saves automatically—if you leave and come back later, you'll pick up where you left off. Team members from the same organization can continue setup without losing previous progress.

{/* step {"find": "What Gets Configured"} */}
## What Gets Configured

During setup, you'll connect:
Expand Down Expand Up @@ -85,3 +93,4 @@ You're all set! Promptless is now ready to help automate your documentation upda
</Success>

Need help with integrations? Contact us at [help@gopromptless.ai](mailto:help@gopromptless.ai) - we add new integrations every week.
{/* test end */}
12 changes: 12 additions & 0 deletions src/content/docs/docs/integrations/slack-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ sidebar:
import Frame from '@components/fern/Frame.astro';
import Info from '@components/fern/Info.astro';

{/* test {"testId": "slack-integration-content"} */}
{/* step {"goTo": "https://promptless.ai/docs/integrations/slack-integration"} */}
{/* step {"find": "Slack Integration"} */}

**Used for: Triggers and Context**

Promptless integrates with Slack through our official Slack App, enabling automated documentation updates based on team communication and support conversations.
Expand All @@ -16,8 +20,10 @@ Promptless does not archive or store your Slack messages.

Disclaimer: Promptless uses LLMs from OpenAI and Anthropic that have the potential to generate inaccurate results.

{/* step {"find": "Installation"} */}
## Installation

{/* step {"checkLink": {"url": "https://app.gopromptless.ai/integrations"}} */}
1. Click "Connect Slack" from the [integrations page](https://app.gopromptless.ai/integrations).
<Frame>
<img src="../assets/integrations-blank.png" alt="Integrations Page" />
Expand All @@ -42,15 +48,21 @@ Disclaimer: Promptless uses LLMs from OpenAI and Anthropic that have the potenti
<img src="../assets/integrations-complete.png" alt="Slack Integration Complete" />
</Frame>

{/* step {"find": "What You Can Do with Slack"} */}
## What You Can Do with Slack

Once connected, you can use Slack for:

{/* step {"checkLink": {"url": "https://promptless.ai/docs/configuring-promptless/triggers/slack-messages"}} */}
- **[Triggers](/docs/configuring-promptless/triggers/slack-messages)**: Tag @Promptless or use message actions to trigger documentation updates
{/* step {"checkLink": {"url": "https://promptless.ai/docs/configuring-promptless/context-sources"}} */}
- **[Context Sources](/docs/configuring-promptless/context-sources)**: Search Slack conversations for team discussions and decisions

{/* step {"find": "Privacy and Channel Access"} */}
## Privacy and Channel Access

By default, Promptless only reads Slack content when you explicitly trigger it by tagging @Promptless or using the "Update Docs" message action. If you enable passive listening in your project settings, Promptless will monitor only the specific channels you select. Promptless cannot access private channels unless it has been specifically invited to those channels.

{/* step {"checkLink": {"url": "https://promptless.ai/docs/how-to-use-promptless/working-with-slack"}} */}
For more details about using Slack with Promptless, see [Working with Slack](/docs/how-to-use-promptless/working-with-slack).
{/* test end */}