diffmode 0.1.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/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +215 -0
- package/dist/bin.js +6603 -0
- package/package.json +51 -0
- package/skills/diffmode/.cursor/rules/diffmode.mdc +32 -0
- package/skills/diffmode/AGENTS.md +35 -0
- package/skills/diffmode/SKILL.md +136 -0
- package/skills/diffmode/llms.txt +20 -0
- package/skills/diffmode/references/commands.md +295 -0
- package/skills/diffmode/references/error-codes.md +118 -0
- package/skills/diffmode/references/founder-input-schema.md +113 -0
- package/skills/diffmode/references/idea-input-schema.md +82 -0
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "diffmode",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agent-drivable CLI for the Diffmode growth pipeline",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/agentic-builders/diffmode-cli.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/agentic-builders/diffmode-cli#readme",
|
|
11
|
+
"bugs": "https://github.com/agentic-builders/diffmode-cli/issues",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=20"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"diffmode": "dist/bin.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/",
|
|
20
|
+
"skills/",
|
|
21
|
+
"NOTICE",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "esbuild src/bin.ts --bundle --platform=node --target=node20 --format=cjs --external:keytar --outfile=dist/bin.js --banner:js='#!/usr/bin/env node' && chmod +x dist/bin.js",
|
|
26
|
+
"dev": "tsx src/bin.ts",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"lint": "eslint src --ext .ts",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"sync:companions": "tsx scripts/sync-companions.ts",
|
|
32
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run build"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"commander": "^14.0.0"
|
|
36
|
+
},
|
|
37
|
+
"optionalDependencies": {
|
|
38
|
+
"keytar": "^7.9.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^22.0.0",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
43
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
44
|
+
"esbuild": "^0.28.0",
|
|
45
|
+
"eslint": "^9.0.0",
|
|
46
|
+
"msw": "^2.14.0",
|
|
47
|
+
"tsx": "^4.22.0",
|
|
48
|
+
"typescript": "^6.0.0",
|
|
49
|
+
"vitest": "^4.1.0"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Operate the diffmode CLI to generate growth plans, personas, and focus-group simulations against the hosted Diffmode API.
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
---
|
|
5
|
+
# diffmode CLI
|
|
6
|
+
|
|
7
|
+
<!-- DO NOT EDIT — generated by scripts/sync-companions.ts from SKILL.md -->
|
|
8
|
+
|
|
9
|
+
Use the `diffmode` CLI to operate the hosted growth-strategy API.
|
|
10
|
+
|
|
11
|
+
## When to invoke
|
|
12
|
+
- User asks for a growth plan, personas, focus group, or names diffmode.
|
|
13
|
+
- Confirm: `diffmode --version` and `diffmode whoami --json`.
|
|
14
|
+
|
|
15
|
+
## Default flow
|
|
16
|
+
1. `diffmode limits --json` — credits.
|
|
17
|
+
2. `diffmode run <product> --input founder.json --idempotency-key <uuid> --json`
|
|
18
|
+
3. `diffmode jobs watch <job_id> --json --wait 4h`
|
|
19
|
+
4. `diffmode results <product> --json` then `--summary --json`.
|
|
20
|
+
5. `diffmode unlock <product>` (optional, 15 cr).
|
|
21
|
+
|
|
22
|
+
## Contract
|
|
23
|
+
- Always pass `--json`. Stdout = data; stderr = progress/errors.
|
|
24
|
+
- Generate your own UUIDv4 for `--idempotency-key` (CLI never auto-generates).
|
|
25
|
+
- `--input founder.json` required for `run`/`workflow`/`smoke-test`.
|
|
26
|
+
- On exit 8, redirect user to https://diffmode.app/app/billing. No CLI top-up command exists.
|
|
27
|
+
- Exit codes: `4` auth · `5` conflict (job_id in stderr) · `7` rate-limited ·
|
|
28
|
+
`8` insufficient-credits · `10` interrupted-resumable.
|
|
29
|
+
|
|
30
|
+
## Reference
|
|
31
|
+
- https://github.com/agentic-builders/diffmode-cli
|
|
32
|
+
- https://diffmode.app
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# diffmode — agent contract
|
|
2
|
+
|
|
3
|
+
<!-- DO NOT EDIT — generated by scripts/sync-companions.ts from SKILL.md -->
|
|
4
|
+
|
|
5
|
+
Agent-drivable CLI for the Diffmode growth pipeline.
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
- User asks for a growth plan, personas, focus group, or any task using `diffmode`.
|
|
9
|
+
- Verify: `diffmode --version` and `diffmode whoami --json` (exit 4 → `diffmode login`).
|
|
10
|
+
|
|
11
|
+
## Default flow
|
|
12
|
+
1. `diffmode limits --json` — confirm credits (1 run / 5 idea-eval / 15 unlock).
|
|
13
|
+
2. `diffmode run <product> --input founder.json --idempotency-key <uuid> --json`
|
|
14
|
+
3. `diffmode jobs watch <job_id> --json --wait 4h` (stderr = progress).
|
|
15
|
+
4. `diffmode results <product> --json` — manifest first; never dump full bundle.
|
|
16
|
+
5. `diffmode results <product> --summary --json` — keyFinding sections (~3 k tok).
|
|
17
|
+
6. `diffmode unlock <product> --idempotency-key <uuid> --json` (optional, 15 cr).
|
|
18
|
+
|
|
19
|
+
## Contract
|
|
20
|
+
- `--json` on every call. Stdout = data; stderr = progress/errors.
|
|
21
|
+
- **Idempotency is yours.** Generate a UUIDv4 per submit; CLI does NOT auto-generate.
|
|
22
|
+
- **Founder input** is required for `run`, `workflow`, `smoke-test`. Use `--input` or
|
|
23
|
+
`--from-url`. `unlock` reuses the prior free-tier's input.
|
|
24
|
+
- `idea-eval` takes a JSON array (not strings) — see `references/idea-input-schema.md`.
|
|
25
|
+
- **Billing is browser-only.** On exit 8, redirect user to https://diffmode.app/app/billing.
|
|
26
|
+
|
|
27
|
+
## Exit codes (spec §8)
|
|
28
|
+
`0` ok · `1` generic · `2` usage · `3` network · `4` auth ·
|
|
29
|
+
`5` conflict · `6` not-found · `7` rate-limited · `8` insufficient-credits ·
|
|
30
|
+
`9` server · `10` interrupted-resumable · `130` SIGINT.
|
|
31
|
+
Full recovery: `references/error-codes.md`.
|
|
32
|
+
|
|
33
|
+
## See also
|
|
34
|
+
- https://github.com/agentic-builders/diffmode-cli
|
|
35
|
+
- https://diffmode.app
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diffmode
|
|
3
|
+
description: Use this skill whenever the user asks to generate, run, retrieve, or apply a growth plan, marketing strategy, persona research, or focus group simulation with the Diffmode CLI. Triggers on phrases like "growth plan", "diffmode run", "personas", "focus group", "growth strategy", and any instruction to operate the `diffmode` CLI. The skill orchestrates the `diffmode` CLI end-to-end against the hosted growth-pipeline API — authenticate, pre-flight credits, submit a run, watch the job, retrieve manifest-shaped results, and apply tactics. Use this any time the user mentions Diffmode or asks for a bootstrapped-SaaS growth plan, even if they don't explicitly name the CLI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Diffmode
|
|
7
|
+
|
|
8
|
+
You are operating the `diffmode` CLI on behalf of the user. It is a thin HTTP
|
|
9
|
+
client to a hosted growth-strategy API. A full plan run can take 10 minutes to
|
|
10
|
+
several hours and produces dozens of markdown files. **Never dump full outputs
|
|
11
|
+
into your context** — always work through the manifest emitted by
|
|
12
|
+
`diffmode results`.
|
|
13
|
+
|
|
14
|
+
## When to use this skill
|
|
15
|
+
|
|
16
|
+
- User says "use diffmode", "generate a growth plan", "run diffmode for
|
|
17
|
+
<product>", "show the personas", or asks to apply a plan produced by
|
|
18
|
+
Diffmode.
|
|
19
|
+
- User has installed the CLI (verify with `diffmode --version`) and
|
|
20
|
+
authenticated (verify with `diffmode whoami --json`).
|
|
21
|
+
|
|
22
|
+
## When NOT to use this skill
|
|
23
|
+
|
|
24
|
+
- For generic marketing advice not tied to a Diffmode product.
|
|
25
|
+
- If the user wants to top up credits — Diffmode billing is **browser-only**.
|
|
26
|
+
On exit 8, redirect them to `https://diffmode.app/app/billing` (or the
|
|
27
|
+
resolver URL in the error payload). There is no `diffmode billing topup`
|
|
28
|
+
command.
|
|
29
|
+
- If `diffmode` is not installed — instruct the user to run
|
|
30
|
+
`npx diffmode@latest login` once, then resume.
|
|
31
|
+
|
|
32
|
+
## Operating contract
|
|
33
|
+
|
|
34
|
+
- The CLI is **non-interactive** when stdout is not a TTY. Always pass
|
|
35
|
+
`--json` and parse the schema-versioned envelope.
|
|
36
|
+
- **Stdout is data; stderr is progress/errors.** Both carry valid JSON when
|
|
37
|
+
`--json` is set.
|
|
38
|
+
- **Exit codes** are part of the public contract:
|
|
39
|
+
- `0` ok · `1` generic · `2` usage · `3` network · `4` auth ·
|
|
40
|
+
`5` conflict (409) · `6` not-found · `7` rate-limited ·
|
|
41
|
+
`8` insufficient-credits (402) · `9` server ·
|
|
42
|
+
`10` interrupted-resumable · `130` SIGINT
|
|
43
|
+
- Full recovery guidance: `references/error-codes.md`.
|
|
44
|
+
- **Idempotency is the agent's responsibility.** The CLI does NOT
|
|
45
|
+
auto-generate an `Idempotency-Key` header. Generate a UUIDv4 yourself and
|
|
46
|
+
pass `--idempotency-key <uuid>` on every submit (`run`, `unlock`,
|
|
47
|
+
`workflow`, `idea-eval`, `smoke-test`). Same key + same user → same
|
|
48
|
+
`job_id` (no double-charge). Matches `gh`/`stripe` UX.
|
|
49
|
+
- **Founder input is required** for `run`, `workflow`, and `smoke-test`. Use
|
|
50
|
+
`--input founder.json` (canonical) or `--from-url <url>` (CLI calls
|
|
51
|
+
`/public/v1/analyze-website` to pre-fill). Schema:
|
|
52
|
+
`references/founder-input-schema.md`. `unlock` reuses the prior
|
|
53
|
+
free-tier's stored input — do not re-supply.
|
|
54
|
+
- **Idea-eval** takes a structured JSON array, not strings — see
|
|
55
|
+
`references/idea-input-schema.md`.
|
|
56
|
+
|
|
57
|
+
## Default workflow
|
|
58
|
+
|
|
59
|
+
1. **Authenticate (one-time per machine).**
|
|
60
|
+
`diffmode whoami --json` → on exit 4, stop and tell the user
|
|
61
|
+
`npx diffmode@latest login` (or `diffmode login --token dm_pat_…`) in
|
|
62
|
+
their terminal, then resume.
|
|
63
|
+
2. **Pre-flight credits.**
|
|
64
|
+
`diffmode limits --json` → if `credits_available < N` (1 for `run`/
|
|
65
|
+
`smoke-test`, 5 for `idea-eval`, 15 for `unlock`/`workflow`), echo the
|
|
66
|
+
`billing_url` and stop. The CLI's submit also does this pre-flight by
|
|
67
|
+
default; `--no-preflight` skips it.
|
|
68
|
+
3. **Submit a run (default = free-tier, 1 credit).**
|
|
69
|
+
Generate a UUIDv4 and run
|
|
70
|
+
`diffmode run <product> --input founder.json --idempotency-key <uuid> --json`.
|
|
71
|
+
On exit 5 (CONFLICT), parse `error.job_id` from stderr and resume at
|
|
72
|
+
step 4 with that id.
|
|
73
|
+
4. **Watch.**
|
|
74
|
+
`diffmode jobs watch <job_id> --json --wait 4h`. This blocks; the CLI
|
|
75
|
+
handles `next_poll_ms` backoff and prints progress to stderr.
|
|
76
|
+
- exit 10 (RESUMABLE) → run `diffmode jobs resume <job_id>` once, then
|
|
77
|
+
re-watch.
|
|
78
|
+
- exit 7 (rate-limited) → respect `error.retry_after`; sleep then retry.
|
|
79
|
+
- exit 9 twice in a row → stop, surface to the user.
|
|
80
|
+
- Ctrl-C never cancels the server job — print "resume with
|
|
81
|
+
`diffmode jobs watch <job_id>`" and exit 130.
|
|
82
|
+
5. **Retrieve results (manifest-first; never read the full bundle).**
|
|
83
|
+
`diffmode results <product> --json` → read the manifest only. Then read
|
|
84
|
+
`report.json` keyFinding sections via
|
|
85
|
+
`diffmode results <product> --summary --json` (~3 k tokens).
|
|
86
|
+
6. **Drill down deliberately.**
|
|
87
|
+
- Buyer personas (free-tier report sections are: `landscape`,
|
|
88
|
+
`advantages`, `buyers`, `blockers`, `growthPlan`):
|
|
89
|
+
`diffmode results <product> --stage buyers --summary --json`, then
|
|
90
|
+
`--pull` once and `--show <relative-path>.md` for any persona file
|
|
91
|
+
listed in the manifest.
|
|
92
|
+
- A tactic: `diffmode results <product> --tactic <id-or-name>` (look up
|
|
93
|
+
valid tactic ids/names via `--stage growthPlan --summary --json`).
|
|
94
|
+
- Always page large files with `--max-tokens 4000` unless the user asks
|
|
95
|
+
for the full file.
|
|
96
|
+
7. **Optional unlock (15 credits).**
|
|
97
|
+
`diffmode unlock <product> --idempotency-key <uuid> --json`. Requires a
|
|
98
|
+
completed `diffmode run` for the same product first — on 422, prompt the
|
|
99
|
+
user to run free-tier first.
|
|
100
|
+
8. **Apply the plan.** Present the executive summary and proposed actions.
|
|
101
|
+
**Stop and confirm** before making any code/copy/config changes. Treat
|
|
102
|
+
each tactic as its own edit-review-commit loop.
|
|
103
|
+
|
|
104
|
+
## Human-checkpoint policy
|
|
105
|
+
|
|
106
|
+
- Submit a run only after confirming product name AND that the user
|
|
107
|
+
understands it costs credits.
|
|
108
|
+
- Apply changes to files only after presenting a diff and getting explicit
|
|
109
|
+
user approval.
|
|
110
|
+
- Never re-run the pipeline against the same product within 30 minutes
|
|
111
|
+
without asking.
|
|
112
|
+
|
|
113
|
+
## Failure recovery (cheat sheet)
|
|
114
|
+
|
|
115
|
+
| Exit | Meaning | Action |
|
|
116
|
+
| --- | --- | --- |
|
|
117
|
+
| 4 | Auth | Ask the user to `diffmode login`. |
|
|
118
|
+
| 5 | Conflict (in-flight job) | Parse `error.job_id`; jump to step 4 (watch). |
|
|
119
|
+
| 7 | Rate limited | Sleep `error.retry_after` (or surface if > 5 min). |
|
|
120
|
+
| 8 | Insufficient credits | Print `billing_url` from the error; stop. |
|
|
121
|
+
| 10 | Interrupted (resumable) | `diffmode jobs resume <id>` once, re-watch. |
|
|
122
|
+
| 130 | SIGINT | Confirm whether to re-watch — do NOT auto-cancel. |
|
|
123
|
+
|
|
124
|
+
See `references/error-codes.md` for every code + per-command coverage.
|
|
125
|
+
|
|
126
|
+
## See also
|
|
127
|
+
|
|
128
|
+
- `references/commands.md` — full command catalog with endpoints, credit
|
|
129
|
+
costs, flags, and example invocations.
|
|
130
|
+
- `references/error-codes.md` — exit codes + per-code recovery script.
|
|
131
|
+
- `references/founder-input-schema.md` — `FounderDiagnostics` shape for
|
|
132
|
+
`--input`.
|
|
133
|
+
- `references/idea-input-schema.md` — `IdeaInput` array shape for
|
|
134
|
+
`--ideas-file`.
|
|
135
|
+
- `https://github.com/agentic-builders/diffmode-cli` — repo + issue tracker.
|
|
136
|
+
- `https://diffmode.app` — top-up + dashboard (browser-only billing).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# diffmode
|
|
2
|
+
|
|
3
|
+
<!-- DO NOT EDIT — generated by scripts/sync-companions.ts from SKILL.md -->
|
|
4
|
+
|
|
5
|
+
> Agent-drivable CLI for the Diffmode growth pipeline. Generate growth plans,
|
|
6
|
+
> personas, and focus-group simulations against the hosted Diffmode API. PAT
|
|
7
|
+
> auth, JSON-on-non-TTY, durable jobs, browser-only billing.
|
|
8
|
+
|
|
9
|
+
## Docs
|
|
10
|
+
|
|
11
|
+
- [Repository](https://github.com/agentic-builders/diffmode-cli): source, README, exit codes, CHANGELOG.
|
|
12
|
+
- [SKILL.md](https://github.com/agentic-builders/diffmode-cli/blob/main/skills/diffmode/SKILL.md): canonical agent skill.
|
|
13
|
+
- [Commands reference](https://github.com/agentic-builders/diffmode-cli/blob/main/skills/diffmode/references/commands.md): endpoint, credit cost, flags, examples per command.
|
|
14
|
+
- [Exit codes](https://github.com/agentic-builders/diffmode-cli/blob/main/skills/diffmode/references/error-codes.md): exit-code contract + per-code recovery scripts.
|
|
15
|
+
- [Founder input schema](https://github.com/agentic-builders/diffmode-cli/blob/main/skills/diffmode/references/founder-input-schema.md): `FounderDiagnostics` shape for `--input`.
|
|
16
|
+
- [Idea-eval input schema](https://github.com/agentic-builders/diffmode-cli/blob/main/skills/diffmode/references/idea-input-schema.md): `IdeaInput` array for `--ideas-file`.
|
|
17
|
+
|
|
18
|
+
## Optional
|
|
19
|
+
|
|
20
|
+
- [Dashboard](https://diffmode.app): mint PATs at `/app/tokens`, top up credits at `/app/billing`.
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Commands reference
|
|
2
|
+
|
|
3
|
+
Complete catalog of `diffmode` commands. Each entry lists: the backend
|
|
4
|
+
endpoint it calls, credit cost (where applicable), required + optional
|
|
5
|
+
flags, exit codes, and example invocations (TTY + `--json` forms). For a
|
|
6
|
+
machine-readable version of this table, run `diffmode commands --json`.
|
|
7
|
+
|
|
8
|
+
> **Drift policy.** The CLI emits its commander tree as a manifest; the
|
|
9
|
+
> test `test/commands-reference-drift.test.ts` asserts every command listed
|
|
10
|
+
> here also appears in `diffmode commands --json`. Don't add a new command
|
|
11
|
+
> without updating this file.
|
|
12
|
+
|
|
13
|
+
## Globals (apply to every command)
|
|
14
|
+
|
|
15
|
+
| Flag | Description |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `--json` | Emit machine-readable JSON (forces JSON even on a TTY). |
|
|
18
|
+
| `--no-color` | Disable ANSI colors. |
|
|
19
|
+
| `--quiet` | Suppress stderr progress. |
|
|
20
|
+
| `--verbose` | Verbose stderr output. |
|
|
21
|
+
| `--yes` | Auto-confirm interactive prompts. |
|
|
22
|
+
| `--token <pat>` | PAT override (precedence: `--token` > `DIFFMODE_TOKEN` env > stored). |
|
|
23
|
+
| `--profile <name>` | Configuration profile (default `default`). |
|
|
24
|
+
| `--timeout <s>` | Per-HTTP-request timeout in seconds (default 60). |
|
|
25
|
+
|
|
26
|
+
`--idempotency-key <uuid>` is **subcommand-scoped** (on submit commands
|
|
27
|
+
only) and **not** a global flag.
|
|
28
|
+
|
|
29
|
+
## Auth
|
|
30
|
+
|
|
31
|
+
### `diffmode login`
|
|
32
|
+
|
|
33
|
+
- **Endpoint:** `GET /public/v1/access-tokens` (validates PAT)
|
|
34
|
+
- Reads a PAT from stdin or `--token`. Stores it via OS keyring (or 0600
|
|
35
|
+
file fallback with a one-time stderr warning).
|
|
36
|
+
- **Exits:** 0, 1, 2, 3, 4, 9
|
|
37
|
+
- Examples:
|
|
38
|
+
```bash
|
|
39
|
+
diffmode login --token dm_pat_…
|
|
40
|
+
echo "$DIFFMODE_TOKEN" | diffmode login
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `diffmode logout`
|
|
44
|
+
|
|
45
|
+
- Clears stored credentials for the active profile. Idempotent.
|
|
46
|
+
- **Exits:** 0
|
|
47
|
+
|
|
48
|
+
### `diffmode whoami`
|
|
49
|
+
|
|
50
|
+
- **Endpoint:** `GET /public/v1/access-tokens`
|
|
51
|
+
- Verifies the active token; prints identity metadata.
|
|
52
|
+
- **Exits:** 0, 1, 3, 4, 9
|
|
53
|
+
- Example: `diffmode whoami --json`
|
|
54
|
+
|
|
55
|
+
## Submit (job-creating)
|
|
56
|
+
|
|
57
|
+
All submit commands accept `--idempotency-key <uuid>` (optional, no
|
|
58
|
+
auto-generation). The CLI does a pre-flight `GET /billing/balance` before
|
|
59
|
+
posting unless `--no-preflight` is set.
|
|
60
|
+
|
|
61
|
+
### `diffmode run <product>` (default, **1 credit**)
|
|
62
|
+
|
|
63
|
+
- **Endpoint:** `POST /public/v1/free-tier`
|
|
64
|
+
- **Required input:** `--input <file|->` or `--from-url <url>` (founder
|
|
65
|
+
diagnostics; see `founder-input-schema.md`).
|
|
66
|
+
- **Flags:** `--input`, `--from-url`, `--save-input`, `--idempotency-key`,
|
|
67
|
+
`--no-preflight`
|
|
68
|
+
- **Exits:** 0, 1, 2, 3, 4, 5, 7, 8, 9
|
|
69
|
+
- Examples:
|
|
70
|
+
```bash
|
|
71
|
+
diffmode run myproduct --input founder.json --idempotency-key "$(uuidgen)"
|
|
72
|
+
diffmode run myproduct --from-url https://example.com --json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `diffmode workflow <product>` (**15 credits**)
|
|
76
|
+
|
|
77
|
+
- **Endpoint:** `POST /public/v1/workflow`
|
|
78
|
+
- Cold-start full plan. Power-user verb.
|
|
79
|
+
- **Flags:** identical surface to `run`.
|
|
80
|
+
- **Exits:** 0, 1, 2, 3, 4, 5, 7, 8, 9
|
|
81
|
+
|
|
82
|
+
### `diffmode unlock <product>` (**15 credits**)
|
|
83
|
+
|
|
84
|
+
- **Endpoint:** `POST /public/v1/products/{id}/unlock`
|
|
85
|
+
- Server reuses the founder input from the prior completed free-tier run;
|
|
86
|
+
no `--input` accepted here. On 422 → CLI exits 2 with
|
|
87
|
+
`Run \`diffmode run <p>\` first.`
|
|
88
|
+
- **Flags:** `--idempotency-key`, `--no-preflight`
|
|
89
|
+
- **Exits:** 0, 1, 2, 3, 4, 5, 7, 8, 9
|
|
90
|
+
|
|
91
|
+
### `diffmode idea-eval <product>` (**5 credits**)
|
|
92
|
+
|
|
93
|
+
- **Endpoint:** `POST /public/v1/idea-eval`
|
|
94
|
+
- **Required input:** `--ideas-file <path>` — JSON array of `IdeaInput`
|
|
95
|
+
objects (see `idea-input-schema.md`). Not resumable.
|
|
96
|
+
- **Flags:** `--ideas-file`, `--intuition`, `--target-idea`,
|
|
97
|
+
`--idempotency-key`, `--no-preflight`
|
|
98
|
+
- **Exits:** 0, 1, 2, 3, 4, 5, 7, 8, 9
|
|
99
|
+
- Example:
|
|
100
|
+
```bash
|
|
101
|
+
diffmode idea-eval myproduct --ideas-file ideas.json \
|
|
102
|
+
--intuition "founder-mode onboarding is the highest-leverage" \
|
|
103
|
+
--json
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `diffmode smoke-test <product>` (**1 credit**)
|
|
107
|
+
|
|
108
|
+
- **Endpoint:** `POST /public/v1/smoke-test`
|
|
109
|
+
- Always pass `--input` (CLI does NOT rely on the server-side disk
|
|
110
|
+
fallback used by local-CLI mode). Not resumable.
|
|
111
|
+
- **Flags:** `--input`, `--from-url`, `--save-input`, `--idempotency-key`,
|
|
112
|
+
`--no-preflight`
|
|
113
|
+
- **Exits:** 0, 1, 2, 3, 4, 5, 7, 8, 9
|
|
114
|
+
|
|
115
|
+
## Jobs
|
|
116
|
+
|
|
117
|
+
### `diffmode jobs list`
|
|
118
|
+
|
|
119
|
+
- **Endpoint:** `GET /public/v1/jobs?limit=&cursor=&product_id=&status=`
|
|
120
|
+
- Keyset pagination (max `--limit 200`).
|
|
121
|
+
- **Flags:** `--product`, `--status`, `--limit`, `--cursor`
|
|
122
|
+
- **Exits:** 0, 1, 3, 4, 9
|
|
123
|
+
- Examples:
|
|
124
|
+
```bash
|
|
125
|
+
diffmode jobs list --product myproduct --json
|
|
126
|
+
diffmode jobs list --cursor "$NEXT_CURSOR"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### `diffmode jobs status <job_id>`
|
|
130
|
+
|
|
131
|
+
- **Endpoint:** `GET /public/v1/jobs/{job_id}`
|
|
132
|
+
- **Exits:** 0, 1, 3, 4, 6, 9
|
|
133
|
+
|
|
134
|
+
### `diffmode jobs watch <job_id>`
|
|
135
|
+
|
|
136
|
+
- Repeated `GET /public/v1/jobs/{job_id}`; honors `next_poll_ms` with
|
|
137
|
+
±20 % jitter clamped to `[3 s, 30 s]`.
|
|
138
|
+
- **Flags:** `--wait <duration>` (e.g. `4h`, `30m`, `300s`; this is the
|
|
139
|
+
**total polling wait**, distinct from the global per-request
|
|
140
|
+
`--timeout`). The deadline is enforced at the start of every poll
|
|
141
|
+
iteration AND retry sleeps (429 `Retry-After`, transient backoff) are
|
|
142
|
+
clamped to the remaining budget, so a single long `Retry-After` cannot
|
|
143
|
+
push the watch past `--wait`.
|
|
144
|
+
- **Exits:** 0, 1, 3, 4, 6, 7, 9, 10, 130
|
|
145
|
+
- Persistent `429` responses (≥5 in a row) surface as exit 7 with code
|
|
146
|
+
`rate_limited` and the server's `Retry-After` echoed in the envelope.
|
|
147
|
+
- `--wait` deadline exhaustion exits **1** with `code: "generic"` (the
|
|
148
|
+
server-side job keeps running; re-watch to resume). This is distinct
|
|
149
|
+
from exit 7 — the CLI has no `retry_after` to promise on a client-side
|
|
150
|
+
timeout, so it deliberately does NOT pose as back-pressure.
|
|
151
|
+
- Ctrl-C: prints `Resume with: diffmode jobs watch <id>` to stderr; never
|
|
152
|
+
calls `DELETE /jobs/{id}`.
|
|
153
|
+
|
|
154
|
+
### `diffmode jobs resume <job_id>`
|
|
155
|
+
|
|
156
|
+
- Two-step:
|
|
157
|
+
1. `GET /public/v1/jobs/{job_id}` to fetch `module_type` + `product_id`.
|
|
158
|
+
2. Branch:
|
|
159
|
+
- `free-tier` → `POST /public/v1/free-tier/{product_id}/retry`
|
|
160
|
+
- `workflow` → `POST /public/v1/workflow/resume`
|
|
161
|
+
- other modules → exit 2 with "module is not resumable" hint.
|
|
162
|
+
- **Flags:** `--idempotency-key`
|
|
163
|
+
- **Exits:** 0, 1, 2, 3, 4, 6, 9
|
|
164
|
+
|
|
165
|
+
### `diffmode jobs cancel <job_id>`
|
|
166
|
+
|
|
167
|
+
- **Endpoint:** `DELETE /public/v1/jobs/{job_id}`
|
|
168
|
+
- Idempotent; on TTY prompts unless global `--yes` is set.
|
|
169
|
+
- **Exits:** 0, 1, 2, 3, 4, 6, 9
|
|
170
|
+
- Declining the interactive `y/N` confirmation exits 2 with code `usage`
|
|
171
|
+
(no `DELETE` issued) — same envelope agents already handle for malformed
|
|
172
|
+
flags, so the path is predictable from `diffmode commands --json`.
|
|
173
|
+
|
|
174
|
+
## Results
|
|
175
|
+
|
|
176
|
+
### `diffmode results <product>`
|
|
177
|
+
|
|
178
|
+
- Resolves the latest completed job (or `--job-id <id>`), downloads
|
|
179
|
+
`/products/{id}/outputs`, and emits a manifest:
|
|
180
|
+
```json
|
|
181
|
+
{
|
|
182
|
+
"schema_version": "1",
|
|
183
|
+
"product": "<p>",
|
|
184
|
+
"job_id": "<id>",
|
|
185
|
+
"module_type": "free-tier",
|
|
186
|
+
"out_dir": ".diffmode/<p>/<id>/",
|
|
187
|
+
"total_files": 14,
|
|
188
|
+
"total_bytes_est": 184323,
|
|
189
|
+
"report_sections": ["meta", "landscape", "advantages", "growthPlan", ...]
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
- **Flags:** `--job-id`, `--out`, `--summary`, `--show <path>`,
|
|
193
|
+
`--max-tokens <n>`, `--pull`, `--stage <s>`, `--tactic <t>`
|
|
194
|
+
- **Exits:** 0, 1, 2, 3, 4, 6, 9
|
|
195
|
+
- `--summary` returns `report.json` keyFinding sections for free-tier
|
|
196
|
+
jobs; for workflow/unlock it prints a Phase-2 stub.
|
|
197
|
+
- **Phase-1 `--job-id` caveat:** `/products/{id}/outputs` returns the
|
|
198
|
+
current product workspace; the API does not yet serve per-job artifact
|
|
199
|
+
snapshots. `--job-id` pins the manifest's `job_id` field, but downloaded
|
|
200
|
+
files always reflect the latest run. If the pinned job is not the latest
|
|
201
|
+
completed run, the manifest JSON carries `latest_completed_job_id`
|
|
202
|
+
(always emitted, not silenced by `--quiet`), the CLI redirects the local
|
|
203
|
+
snapshot dir to `<latest-job>/` so any prior `<pinned>/` snapshot stays
|
|
204
|
+
intact, and a stderr note describes the redirect for humans. If the
|
|
205
|
+
advisory drift lookup itself fails (transient 429/5xx/network), the
|
|
206
|
+
manifest sets `drift_lookup_failed: true` and the CLI warns on stderr
|
|
207
|
+
that drift status could not be verified. Per-job snapshots ship with the
|
|
208
|
+
Phase-2 manifest endpoint.
|
|
209
|
+
|
|
210
|
+
## Billing (read-only)
|
|
211
|
+
|
|
212
|
+
### `diffmode account`
|
|
213
|
+
|
|
214
|
+
- **Endpoint:** `GET /public/v1/billing/balance`
|
|
215
|
+
- Pretty table on TTY; full `CreditBalance` JSON on `--json`.
|
|
216
|
+
- **Exits:** 0, 1, 3, 4, 9
|
|
217
|
+
|
|
218
|
+
### `diffmode billing balance`
|
|
219
|
+
|
|
220
|
+
- Terse `{balance, has_purchased}` (or pretty on TTY).
|
|
221
|
+
- **Exits:** 0, 1, 3, 4, 9
|
|
222
|
+
|
|
223
|
+
### `diffmode billing history`
|
|
224
|
+
|
|
225
|
+
- **Endpoint:** `GET /public/v1/billing/history?limit=&offset=`
|
|
226
|
+
- **Offset-based** pagination (not B5 keyset). NDJSON output on non-TTY.
|
|
227
|
+
- **Flags:** `--limit`, `--offset`
|
|
228
|
+
- **Exits:** 0, 1, 3, 4, 9
|
|
229
|
+
|
|
230
|
+
### `diffmode limits`
|
|
231
|
+
|
|
232
|
+
- Derives credit availability from `/billing/balance` plus the documented
|
|
233
|
+
rate-limit policy (3 submissions / 24 h for non-paying).
|
|
234
|
+
- **Exits:** 0, 1, 3, 4, 9
|
|
235
|
+
- Does NOT estimate `free_submits_remaining` — the backend doesn't expose
|
|
236
|
+
remaining slots and a CLI-local guess would lie across devices.
|
|
237
|
+
|
|
238
|
+
### NO `diffmode billing topup`
|
|
239
|
+
|
|
240
|
+
Top-up is **browser-only by design**. On exit 8 from any submit, the CLI
|
|
241
|
+
prints `Insufficient credits. Top up at <DIFFMODE_BILLING_URL or default>`
|
|
242
|
+
and exits. Override the redirect with `DIFFMODE_BILLING_URL`.
|
|
243
|
+
|
|
244
|
+
## Diagnostics helpers
|
|
245
|
+
|
|
246
|
+
### `diffmode diagnostics from-url <url>`
|
|
247
|
+
|
|
248
|
+
- **Endpoint:** `POST /public/v1/analyze-website`
|
|
249
|
+
- Prints a draft `FounderDiagnostics` JSON; `--save <path>` writes to
|
|
250
|
+
disk instead.
|
|
251
|
+
- **Exits:** 0, 1, 2, 3, 4, 9
|
|
252
|
+
|
|
253
|
+
### `diffmode diagnostics validate <path>`
|
|
254
|
+
|
|
255
|
+
- Validates a founder-input JSON file against the documented schema. Exits
|
|
256
|
+
0 if valid, 2 with field-level errors otherwise.
|
|
257
|
+
- **Exits:** 0, 1, 2
|
|
258
|
+
|
|
259
|
+
## Self-describing
|
|
260
|
+
|
|
261
|
+
### `diffmode commands`
|
|
262
|
+
|
|
263
|
+
- Emits the full commander tree as a manifest. Always JSON (no `--json`
|
|
264
|
+
required). Stable schema; use it for agent discovery.
|
|
265
|
+
- **Exits:** 0
|
|
266
|
+
|
|
267
|
+
### `diffmode --version --json`
|
|
268
|
+
|
|
269
|
+
- Emits `{schema_version, version, node, platform}`. Plain text without
|
|
270
|
+
`--json`.
|
|
271
|
+
|
|
272
|
+
## Agent integration
|
|
273
|
+
|
|
274
|
+
### `diffmode skill show`
|
|
275
|
+
|
|
276
|
+
- Prints the bundled `SKILL.md` to stdout (`{path, contents}` on `--json`).
|
|
277
|
+
Useful for agents that want to inspect the skill without installing it.
|
|
278
|
+
- **Exits:** 0, 1
|
|
279
|
+
|
|
280
|
+
### `diffmode skill install`
|
|
281
|
+
|
|
282
|
+
- Copies the bundled skill into per-tool agent dirs.
|
|
283
|
+
- **Flags:**
|
|
284
|
+
- `--target <claude|codex|cursor|all>` (default `all`)
|
|
285
|
+
- `--yes` overwrites a divergent existing file (without it, the command
|
|
286
|
+
reports `needs-confirm` and writes nothing)
|
|
287
|
+
- `--dry-run` reports the action without writing
|
|
288
|
+
- `--print-paths` prints the resolved target paths and exits
|
|
289
|
+
- **Default paths** (override with `DIFFMODE_SKILL_{CLAUDE,CODEX,CURSOR}_PATH`):
|
|
290
|
+
- Claude: `~/.claude/skills/diffmode/SKILL.md`
|
|
291
|
+
- Codex: `~/.codex/skills/diffmode/SKILL.md`
|
|
292
|
+
- Cursor: `~/.cursor/rules/diffmode.mdc`
|
|
293
|
+
- Skips a target gracefully when the parent tool's home dir is missing
|
|
294
|
+
(e.g., Claude Code not installed) — non-fatal.
|
|
295
|
+
- **Exits:** 0, 1, 2
|