|
1 | 1 | # fincrawl |
2 | 2 |
|
3 | | -`fincrawl` is a reusable local-first crawler/archive tool for support |
4 | | -conversation systems, starting with Intercom and Fin. |
5 | | - |
6 | | -The project is the generic crawler core: CLI, schemas, local archive mechanics, |
7 | | -search, encryption pipeline, fake fixtures, tests, and docs. Tenant credentials, |
8 | | -runtime config, crawl state, logs, reports, screenshots, plaintext snapshots, |
9 | | -encrypted snapshots, and transcript-derived examples do not belong in this repo. |
10 | | - |
11 | | -## Start Here |
12 | | - |
13 | | -- [Architecture](docs/architecture.md) describes the current CLI, package, |
14 | | - store, sync, artifact, and agent-use shape. |
15 | | -- [Roadmap](docs/roadmap.md) describes what works now and what comes next. |
16 | | -- [Contributing](CONTRIBUTING.md) explains setup, verification, commit style, |
17 | | - and the no-tenant-data contribution boundary. |
18 | | -- [Security](SECURITY.md) explains how to report vulnerabilities without |
19 | | - disclosing credentials or tenant data. |
20 | | -- [Open source readiness](docs/runbooks/open-source-readiness.md) is the |
21 | | - checklist to complete before changing repository visibility. |
22 | | -- [Intercom API reference](docs/references/intercom-api.md) collects public API |
23 | | - links and extraction patterns for agents implementing sync. |
24 | | -- [Tenant data boundary](docs/tenant-data-boundary.md) is the reusable policy |
25 | | - for credentials, real artifacts, manual tenant testing, and committed |
26 | | - fixtures. |
27 | | -- [Local live smoke](docs/runbooks/local-live-smoke.md) shows how to exercise |
28 | | - read-only Intercom calls without committing tenant state. |
29 | | - |
30 | | -## Development Boundary |
31 | | - |
32 | | -Committed tests and fixtures must be fake or synthetic. Real tenant crawl state |
33 | | -and generated artifacts belong in tenant-controlled private storage outside this |
34 | | -repository, even when encrypted. |
35 | | - |
36 | | -## Current Offline Slice |
37 | | - |
38 | | -The bootstrapped CLI runs without live Intercom credentials and stores only |
39 | | -synthetic fixture data during deterministic checks: |
| 3 | +Local-first support conversation archive CLI for Intercom workspaces, including |
| 4 | +conversation metadata that Intercom exposes for Fin participation. |
| 5 | + |
| 6 | +`fincrawl` syncs support conversations into a private local SQLite archive, |
| 7 | +searches them without going back through the Intercom UI, and exports portable |
| 8 | +snapshots as compressed age-encrypted JSONL. |
| 9 | + |
| 10 | +This repository is the generic crawler core. Tenant credentials, tenant config, |
| 11 | +runtime state, crawl output, logs, reports, screenshots, plaintext snapshots, |
| 12 | +encrypted tenant snapshots, and transcript-derived examples do not belong here. |
| 13 | + |
| 14 | +## Install |
| 15 | + |
| 16 | +Download a binary from the latest |
| 17 | +[GitHub Release](https://github.com/uinaf/fincrawl/releases), or install from |
| 18 | +source with Go: |
40 | 19 |
|
41 | 20 | ```bash |
42 | | -./scripts/smoke |
43 | | -./scripts/verify |
| 21 | +go install github.com/uinaf/fincrawl/cmd/fincrawl@latest |
44 | 22 | ``` |
45 | 23 |
|
46 | | -`mise` is available as a convenience task index for ad-hoc local work. The |
47 | | -underlying scripts remain the source of truth for verification: |
| 24 | +To work from a checkout: |
48 | 25 |
|
49 | 26 | ```bash |
50 | | -mise trust mise.toml |
51 | | -mise tasks |
52 | | -mise run smoke |
53 | | -mise run fixture-loop |
54 | | -mise run verify |
55 | | -mise run guard |
| 27 | +go run ./cmd/fincrawl version |
| 28 | +./scripts/smoke |
56 | 29 | ``` |
57 | 30 |
|
58 | | -Use `FINCRAWL_HOME=tmp/fincrawl-home` to keep local CLI smoke state inside the |
59 | | -ignored repo `tmp/` directory. Archive examples in this README use a synthetic |
60 | | -public age recipient for smoke tests only. The CLI may read ignored `.env.local` for |
61 | | -`FINCRAWL_AGE_RECIPIENT`; it does not shell out to 1Password. |
62 | | - |
63 | | -## Local Live Smoke |
| 31 | +## Quick Start |
64 | 32 |
|
65 | | -Live sync is intentionally manual and local. Use a read-only Intercom app token |
66 | | -from ignored `.env.local`; do not write tenant config or generated artifacts |
67 | | -inside this repository. The safe default smoke hydrates admins, teams, and tags |
68 | | -only; contact listing and conversation hydration are explicit opt-ins. |
| 33 | +Keep local state outside tracked paths: |
69 | 34 |
|
70 | 35 | ```bash |
71 | | -cp .env.local.example .env.local.tpl |
72 | | -op inject -i .env.local.tpl -o .env.local |
73 | | -chmod 600 .env.local |
74 | | -./scripts/local-live-smoke |
| 36 | +export FINCRAWL_HOME=/tmp/fincrawl-home |
| 37 | +fincrawl doctor --offline |
75 | 38 | ``` |
76 | 39 |
|
77 | | -For contact scope proof, keep the list capped: |
| 40 | +Try the archive path with synthetic fixtures from a source checkout: |
78 | 41 |
|
79 | 42 | ```bash |
80 | | -FINCRAWL_LIVE_CONTACT_LIMIT=10 ./scripts/local-live-smoke |
| 43 | +fincrawl sync --fixture testdata/synthetic |
| 44 | +fincrawl search "billing refund" --fields provider_id,subject,updated_at |
81 | 45 | ``` |
82 | 46 |
|
83 | | -For bounded conversation proof, prefer a short window and explicit limit: |
| 47 | +For live Intercom access, use a tenant-authorized read-only token from your |
| 48 | +environment or ignored local env file: |
84 | 49 |
|
85 | 50 | ```bash |
86 | | -FINCRAWL_LIVE_UPDATED_SINCE=2h FINCRAWL_LIVE_CONVERSATION_LIMIT=5 ./scripts/local-live-smoke |
| 51 | +fincrawl sync --entities |
| 52 | +fincrawl sync --updated-since 2h --limit 50 |
| 53 | +fincrawl search "login code expired" --fields provider_id,subject,updated_at |
87 | 54 | ``` |
88 | 55 |
|
89 | | -See [Local live smoke](docs/runbooks/local-live-smoke.md) for the full local |
90 | | -workflow and cleanup notes. |
| 56 | +Use exact hydration when you already know a conversation ID: |
| 57 | + |
| 58 | +```bash |
| 59 | +fincrawl sync --conversation <intercom-conversation-id> |
| 60 | +``` |
91 | 61 |
|
92 | | -## Current Local Slice |
| 62 | +## Snapshots |
93 | 63 |
|
94 | | -The current local slice focuses on entity hydration, useful local search, and |
95 | | -local encrypted snapshot portability: |
| 64 | +Snapshots are compressed and encrypted before storage: |
96 | 65 |
|
97 | | -- Hydrate and normalize Intercom admins, teams, tags, and capped contacts/users |
98 | | - where the tenant-authorized token exposes them. |
99 | | -- Enrich SQLite and FTS with participant, assignee, tag, rating, state, and |
100 | | - Fin-like metadata while keeping provider-specific raw JSON for replay. |
101 | | -- Provide local smoke checks for read-only scopes without writing tenant config, |
102 | | - logs, snapshots, or generated artifacts into this repo. |
103 | | -- Publish local SQLite state as compressed age-encrypted JSONL with |
104 | | - `fincrawl publish`. |
105 | | -- Import compressed age-encrypted JSONL into a fresh local SQLite archive with |
106 | | - `fincrawl import`. |
| 66 | +```bash |
| 67 | +fincrawl publish \ |
| 68 | + --recipient <age-recipient-or-ssh-public-key> \ |
| 69 | + --out snapshots/local.jsonl.zst.age \ |
| 70 | + --dry-run |
| 71 | +``` |
107 | 72 |
|
108 | | -The local publish/import loop is the current portability path. Remote |
109 | | -publish/push/subscribe flows are intentionally deferred while tenant-controlled |
110 | | -local usage proves the archive is useful. |
| 73 | +Import validates and hydrates a local SQLite archive: |
111 | 74 |
|
112 | | -The default Intercom API version is `2.15`. Set |
113 | | -`FINCRAWL_INTERCOM_BASE_URL` only for a regional Intercom API host and |
114 | | -`FINCRAWL_INTERCOM_VERSION` only when intentionally testing another supported |
115 | | -API version. |
| 75 | +```bash |
| 76 | +FINCRAWL_AGE_IDENTITY=<age-identity> \ |
| 77 | + fincrawl import --in snapshots/local.jsonl.zst.age --dry-run |
| 78 | +``` |
116 | 79 |
|
117 | | -## Agent Workflow |
| 80 | +Plaintext archive output is local scratch data only. Tenant encrypted snapshots |
| 81 | +still belong in tenant-controlled private storage, not in this repository. |
118 | 82 |
|
119 | | -Agents that need to use `fincrawl` as a local support archive should load the |
120 | | -repo skill at [skills/fincrawl/SKILL.md](skills/fincrawl/SKILL.md). It covers |
121 | | -local search, bounded live sync, tenant-data boundaries, and current CLI Agent |
122 | | -DX guidance. |
| 83 | +## Commands |
123 | 84 |
|
124 | | -Useful agent-facing commands: |
| 85 | +The CLI defaults to JSON output for agents and automation: |
125 | 86 |
|
126 | 87 | ```bash |
127 | | -fincrawl describe search |
128 | | -fincrawl search "login code expired" --fields provider_id,subject,updated_at |
129 | | -fincrawl search "login code expired" --fields provider_id,subject,updated_at --ndjson |
130 | | -fincrawl sync --updated-since 2h --limit 50 --dry-run |
131 | | -fincrawl archive --fixture testdata/synthetic --recipient age1n9zrm0rcxehv7cm55uqw27v9cguz4ev5dtyl7kxkn3vdpvap94ds2gn6rl --out tmp/snapshot.jsonl.zst.age --dry-run |
132 | | -fincrawl publish --recipient <age-recipient> --out snapshots/local.jsonl.zst.age --dry-run |
133 | | -FINCRAWL_AGE_IDENTITY=<age-identity> fincrawl import --in snapshots/local.jsonl.zst.age --dry-run |
| 88 | +fincrawl describe --json |
| 89 | +fincrawl describe search --json |
| 90 | +fincrawl status --json |
| 91 | +fincrawl guard --json |
134 | 92 | ``` |
135 | 93 |
|
136 | | -CLI output defaults to JSON, including structured error envelopes. Use |
137 | | -`--json=false` only for human-oriented text output. |
138 | | - |
139 | | -`./scripts/smoke` runs a fast offline CLI proof against synthetic fixtures. |
140 | | -`./scripts/verify` runs the full local gate: module tidy check, tests, vet, race |
141 | | -tests, smoke, guardrails, and whitespace checks. |
142 | | -`./scripts/release-check` validates the GoReleaser release config. |
143 | | - |
144 | | -Enable the repo hook path if you want the local pre-push gate: |
| 94 | +Common flows: |
| 95 | + |
| 96 | +| Need | Command | |
| 97 | +| --- | --- | |
| 98 | +| Check local config | `fincrawl doctor --offline` | |
| 99 | +| Sync metadata | `fincrawl sync --entities` | |
| 100 | +| Sync a recent window | `fincrawl sync --updated-since 2h --limit 50` | |
| 101 | +| Hydrate one conversation | `fincrawl sync --conversation <id>` | |
| 102 | +| Search local archive | `fincrawl search "<query>" --fields provider_id,subject,updated_at` | |
| 103 | +| Export encrypted snapshot | `fincrawl publish --recipient <recipient> --out snapshots/local.jsonl.zst.age` | |
| 104 | +| Import encrypted snapshot | `fincrawl import --identity <identity> --in snapshots/local.jsonl.zst.age` | |
| 105 | +| Check repo guardrails | `fincrawl guard --json` | |
| 106 | + |
| 107 | +## Docs |
| 108 | + |
| 109 | +| Need | Read | |
| 110 | +| --- | --- | |
| 111 | +| Understand the CLI and storage design | [Architecture](docs/architecture.md) | |
| 112 | +| See what exists and what is next | [Roadmap](docs/roadmap.md) | |
| 113 | +| Keep tenant data out of the repo | [Tenant data boundary](docs/tenant-data-boundary.md) | |
| 114 | +| Run bounded live Intercom checks | [Local live smoke](docs/runbooks/local-live-smoke.md) | |
| 115 | +| Work on releases and CI | [Distribution](docs/distribution.md) | |
| 116 | +| Implement Intercom sync safely | [Intercom API reference](docs/references/intercom-api.md) | |
| 117 | +| Use fincrawl as an agent skill | [Agent guide](skills/fincrawl/SKILL.md) | |
| 118 | +| Contribute changes | [Contributing](CONTRIBUTING.md) | |
| 119 | +| Report a vulnerability | [Security](SECURITY.md) | |
| 120 | + |
| 121 | +## Contributing |
| 122 | + |
| 123 | +Run the local gate before sending changes: |
145 | 124 |
|
146 | 125 | ```bash |
147 | | -git config core.hooksPath .git-hooks |
| 126 | +./scripts/verify |
148 | 127 | ``` |
149 | 128 |
|
150 | | -The pre-push hook runs tests, vet, smoke, and guardrails. The commit-msg hook |
151 | | -enforces Conventional Commit subjects for semantic-release. |
| 129 | +See [Contributing](CONTRIBUTING.md) for setup, validation, commit style, and the |
| 130 | +tenant-data contribution boundary. |
152 | 131 |
|
153 | | -## Release |
| 132 | +## Security |
154 | 133 |
|
155 | | -Pushes and pull requests run the verify job in GitHub Actions. Pushes to `main` |
156 | | -also run semantic-release; Conventional Commit messages decide whether a release |
157 | | -is needed. During bootstrap, releasable commit types advance the patch-only |
158 | | -`0.0.x` line. When a release is published, GoReleaser builds `fincrawl` |
159 | | -binaries for Linux, macOS, and Windows and appends them to the GitHub Release. |
| 134 | +Report vulnerabilities privately. See [Security](SECURITY.md). |
160 | 135 |
|
161 | 136 | ## License |
162 | 137 |
|
163 | | -`fincrawl` is released under the [MIT License](LICENSE). |
| 138 | +MIT. See [License](LICENSE). |
0 commit comments