# dify-playwright
Playwright-based command-line tools for developing and diagnosing Dify workflows. The toolkit can authenticate to a Dify console with a Dify email/password account, inspect and publish workflow drafts, run workflows, and export per-node usage data.
## Security Model
- Credentials come from `DIFY_EMAIL` and `DIFY_PASSWORD` environment variables.
- Credentials, cookies, API keys, and browser storage are never printed by the tools.
- Browser contexts are ephemeral by default.
- `.env`, browser profiles, storage state, generated output, and logs are ignored by Git.
- No deployment URL or application identifier is built into the source.
For shared or production environments, inject secrets through your shell, CI secret store, or password manager rather than writing them into command history.
## Requirements
- Node.js 20 or newer
- A reachable Dify deployment
- A Dify deployment with email/password login enabled, and a valid Dify account
Install dependencies and Chromium:
```bash
npm install
npx playwright install chromium
```
## Configuration
Copy the placeholder environment file and edit only your local copy:
```bash
cp .env.example .env
set -a
source .env
set +a
```
Core variables:
| Variable | Purpose |
| --- | --- |
| `DIFY_BASE_URL` | Dify web-console origin, such as `http://localhost` |
| `DIFY_EMAIL` | Dify account email |
| `DIFY_PASSWORD` | Dify account password |
| `DIFY_APP_ID` | Console application ID for app-specific commands |
| `DIFY_CONSOLE_API_URL` | Optional console API override; defaults to `<base>/console/api` |
| `DIFY_SERVICE_API_URL` | Optional Service API override; defaults to `<base>/v1` |
| `DIFY_HEADLESS` | `true` by default; set to `false` to watch the browser |
| `DIFY_PROFILE_DIR` | Optional persistent browser profile directory |
| `DIFY_BROWSER_EXECUTABLE_PATH` | Optional Chrome/Chromium executable override |
Run a login check:
```bash
npm run login
```
Every browser-backed command can sign in automatically, so a separate login step is optional. Set `DIFY_PROFILE_DIR` only when you intentionally want the authenticated browser profile to persist between commands.
OAuth-only and SSO-enforced deployments are outside this authentication mode; use a deployment-supported login adapter for those environments.
## Console Operations
These commands use Playwright to establish a console session, then call Dify's console API with the resulting session cookies and CSRF header:
```bash
npm run dify -- state
npm run dify -- get-draft output/draft.json
npm run dify -- get-published output/published.json
npm run dify -- save-draft input/save-payload.json
npm run dify -- publish
npm run dify -- list-runs output/runs.json 1 20
npm run dify -- run-nodes <workflow-run-id> output/nodes.json
```
Read [references/workflow-ops.md](references/workflow-ops.md) before saving or publishing a workflow draft.
## Published Workflow Service API
When you only need to run a published workflow, Dify's Service API does not require Playwright. Create an app API key in Dify and export it locally:
```bash
export DIFY_APP_API_KEY='<app-api-key>'
npm run dify -- run-formal input/run.json output/result.json
```
Example request body:
```json
{
"inputs": {
"topic": "Example input"
},
"files": [],
"user": "local-test-user"
}
```
The command uses streaming mode and extracts the final `workflow_finished` event.
## Generic Batch Runs
`scripts/run_workflow_batch.mjs` accepts a JSON array, or an object with a `records` array. Each record has an arbitrary `inputs` object and optional top-level Dify files:
```json
[
{
"id": "case-001",
"inputs": {
"topic": "First example"
},
"files": [],
"user": "batch-test"
}
]
```
Run a draft batch:
```bash
export BATCH_INPUT=input/batch.json
export BATCH_OUTPUT=output/batch-results.json
export DIFY_RUN_MODE=draft
export CONCURRENCY=10
export MAX_ATTEMPTS=2
node scripts/run_workflow_batch.mjs
```
For a console-session published run, set `DIFY_RUN_MODE=published` and `DIFY_INSTALLED_APP_ID`.
## Node Usage Export
Create a manifest containing workflow run IDs:
```json
{
"runs": [
{
"appId": "<app-id>",
"runId": "<workflow-run-id>"
}
]
}
```
Then run:
```bash
MANIFEST=input/runs.json OUTPUT=output/node-usage.json \
node scripts/fetch_batch_node_usage.mjs
```
## Image Inputs
Dify distinguishes ordinary JSON objects from file segments. For workflows with vision input, prefer top-level `files` and wire the LLM node to `sys.files`. See [references/dify-vision-files.md](references/dify-vision-files.md).
## Development
```bash
npm test
npm run check
```
`npm run check` runs unit tests, syntax checks, and the repository sensitive-content scanner.
## License
MIT