@ainyc/canonry 1.0.0 → 1.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/README.md +250 -0
- package/dist/{chunk-ONZDY6Q4.js → chunk-W6AJ2472.js} +4 -1
- package/dist/cli.js +19 -11
- package/dist/index.d.ts +34 -0
- package/dist/index.js +1 -1
- package/package.json +8 -7
- package/src/cli.ts +0 -470
- package/src/client.ts +0 -152
- package/src/commands/apply.ts +0 -25
- package/src/commands/competitor.ts +0 -36
- package/src/commands/evidence.ts +0 -41
- package/src/commands/export-cmd.ts +0 -40
- package/src/commands/history.ts +0 -41
- package/src/commands/init.ts +0 -122
- package/src/commands/keyword.ts +0 -54
- package/src/commands/notify.ts +0 -70
- package/src/commands/project.ts +0 -89
- package/src/commands/run.ts +0 -54
- package/src/commands/schedule.ts +0 -90
- package/src/commands/serve.ts +0 -24
- package/src/commands/settings.ts +0 -45
- package/src/commands/status.ts +0 -52
- package/src/config.ts +0 -90
- package/src/index.ts +0 -2
- package/src/job-runner.ts +0 -368
- package/src/notifier.ts +0 -227
- package/src/provider-registry.ts +0 -55
- package/src/scheduler.ts +0 -161
- package/src/server.ts +0 -249
package/README.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Canonry
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@ainyc/canonry) [](https://www.gnu.org/licenses/agpl-3.0) [](https://nodejs.org)
|
|
4
|
+
|
|
5
|
+
**Open-source AEO monitoring for your domain.** Canonry tracks how AI answer engines (ChatGPT, Gemini, Claude, and others) cite or omit your website for the keywords you care about.
|
|
6
|
+
|
|
7
|
+
AEO (Answer Engine Optimization) is the practice of ensuring your content is accurately represented in AI-generated answers. As search shifts from links to synthesized responses, monitoring your visibility across answer engines is essential.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @ainyc/canonry
|
|
13
|
+
canonry init
|
|
14
|
+
canonry serve
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Open [http://localhost:4100](http://localhost:4100) to access the web dashboard.
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Multi-provider monitoring** -- query Gemini, OpenAI, Claude, and local LLMs (Ollama, LM Studio, or any OpenAI-compatible endpoint) from a single tool.
|
|
22
|
+
- **Three equal surfaces** -- CLI, REST API, and web dashboard all backed by the same API. No surface is privileged.
|
|
23
|
+
- **Config-as-code** -- manage projects with Kubernetes-style YAML files. Version control your monitoring setup.
|
|
24
|
+
- **Self-hosted** -- runs locally with SQLite. No cloud account, no external dependencies beyond the LLM API keys you choose to configure.
|
|
25
|
+
- **Scheduled monitoring** -- set up cron-based recurring runs to track citation changes over time.
|
|
26
|
+
- **Webhook notifications** -- get alerted when your citation status changes.
|
|
27
|
+
- **Audit logging** -- full history of every action taken through any surface.
|
|
28
|
+
|
|
29
|
+
## CLI Reference
|
|
30
|
+
|
|
31
|
+
### Setup
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
canonry init # Initialize config and database
|
|
35
|
+
canonry serve # Start server (API + web dashboard)
|
|
36
|
+
canonry settings # View/edit configuration
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Projects
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
canonry project create <name> --domain <domain> --country US --language en
|
|
43
|
+
canonry project list
|
|
44
|
+
canonry project show <name>
|
|
45
|
+
canonry project delete <name>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Keywords and Competitors
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
canonry keyword add <project> "keyword one" "keyword two"
|
|
52
|
+
canonry keyword list <project>
|
|
53
|
+
canonry keyword import <project> <file.csv>
|
|
54
|
+
|
|
55
|
+
canonry competitor add <project> competitor1.com competitor2.com
|
|
56
|
+
canonry competitor list <project>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Visibility Runs
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
canonry run <project> # Run all configured providers
|
|
63
|
+
canonry run <project> --provider gemini # Run a single provider
|
|
64
|
+
canonry runs <project> # List past runs
|
|
65
|
+
canonry status <project> # Current visibility summary
|
|
66
|
+
canonry evidence <project> # View citation evidence
|
|
67
|
+
canonry history <project> # Per-keyword citation timeline
|
|
68
|
+
canonry export <project> # Export project as YAML
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Config-as-Code
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
canonry apply canonry.yaml # Declarative project apply
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Scheduling and Notifications
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
canonry schedule set <project> --cron "0 8 * * *"
|
|
81
|
+
canonry schedule show <project>
|
|
82
|
+
canonry schedule enable <project>
|
|
83
|
+
canonry schedule disable <project>
|
|
84
|
+
canonry schedule remove <project>
|
|
85
|
+
|
|
86
|
+
canonry notify add <project> --url https://hooks.slack.com/...
|
|
87
|
+
canonry notify list <project>
|
|
88
|
+
canonry notify remove <project> <id>
|
|
89
|
+
canonry notify test <project> <id>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Config-as-Code
|
|
93
|
+
|
|
94
|
+
Define your monitoring projects in version-controlled YAML files:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
apiVersion: canonry/v1
|
|
98
|
+
kind: Project
|
|
99
|
+
metadata:
|
|
100
|
+
name: my-project
|
|
101
|
+
spec:
|
|
102
|
+
displayName: My Project
|
|
103
|
+
canonicalDomain: example.com
|
|
104
|
+
country: US
|
|
105
|
+
language: en
|
|
106
|
+
keywords:
|
|
107
|
+
- best dental implants near me
|
|
108
|
+
- emergency dentist open now
|
|
109
|
+
competitors:
|
|
110
|
+
- competitor.com
|
|
111
|
+
providers:
|
|
112
|
+
- gemini
|
|
113
|
+
- openai
|
|
114
|
+
- claude
|
|
115
|
+
- local
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Apply with the CLI or the API:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
canonry apply canonry.yaml
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
curl -X POST http://localhost:4100/api/v1/apply \
|
|
126
|
+
-H "Authorization: Bearer cnry_..." \
|
|
127
|
+
-H "Content-Type: application/yaml" \
|
|
128
|
+
--data-binary @canonry.yaml
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The database is authoritative. Config files are input, not state.
|
|
132
|
+
|
|
133
|
+
## Provider Setup
|
|
134
|
+
|
|
135
|
+
Canonry queries multiple AI answer engines. Configure the providers you want during `canonry init`, or add them later via the settings page or API.
|
|
136
|
+
|
|
137
|
+
### Gemini
|
|
138
|
+
|
|
139
|
+
Get an API key from [Google AI Studio](https://aistudio.google.com/apikey).
|
|
140
|
+
|
|
141
|
+
### OpenAI
|
|
142
|
+
|
|
143
|
+
Get an API key from [platform.openai.com](https://platform.openai.com/api-keys).
|
|
144
|
+
|
|
145
|
+
### Claude
|
|
146
|
+
|
|
147
|
+
Get an API key from [console.anthropic.com](https://console.anthropic.com/settings/keys).
|
|
148
|
+
|
|
149
|
+
### Local LLMs
|
|
150
|
+
|
|
151
|
+
Any OpenAI-compatible endpoint works -- Ollama, LM Studio, llama.cpp, vLLM, and similar tools. Configure via CLI or API:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
canonry settings provider local --base-url http://localhost:11434/v1
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The base URL is the only required field. API key is optional (most local servers don't need one). You can also set a specific model:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
canonry settings provider local --base-url http://localhost:11434/v1 --model llama3
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
> **Note:** Unless your local model has web search capabilities, responses will be based solely on its training data. Cloud providers (Gemini, OpenAI, Claude) use live web search to ground their answers, which produces more accurate citation results. Local LLMs are best used for comparing how different models perceive your brand without real-time search context.
|
|
164
|
+
|
|
165
|
+
## API
|
|
166
|
+
|
|
167
|
+
All endpoints are served under `/api/v1/`. Authenticate with a bearer token:
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
Authorization: Bearer cnry_...
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Key endpoints:
|
|
174
|
+
|
|
175
|
+
| Method | Path | Description |
|
|
176
|
+
|--------|------|-------------|
|
|
177
|
+
| `PUT` | `/api/v1/projects/{name}` | Create or update a project |
|
|
178
|
+
| `POST` | `/api/v1/projects/{name}/runs` | Trigger a visibility sweep |
|
|
179
|
+
| `GET` | `/api/v1/projects/{name}/timeline` | Per-keyword citation history |
|
|
180
|
+
| `GET` | `/api/v1/projects/{name}/snapshots/diff` | Compare two runs |
|
|
181
|
+
| `POST` | `/api/v1/apply` | Config-as-code apply |
|
|
182
|
+
| `GET` | `/api/v1/openapi.json` | OpenAPI spec (no auth required) |
|
|
183
|
+
|
|
184
|
+
## Web Dashboard
|
|
185
|
+
|
|
186
|
+
The bundled web dashboard provides five views:
|
|
187
|
+
|
|
188
|
+
- **Overview** -- portfolio-level visibility scores across all projects with sparkline trends.
|
|
189
|
+
- **Project** -- command center with score gauges, keyword evidence tables, and competitor analysis.
|
|
190
|
+
- **Runs** -- history of all visibility sweeps with per-provider breakdowns.
|
|
191
|
+
- **Settings** -- provider configuration, scheduling, and notification management.
|
|
192
|
+
- **Setup** -- guided wizard for first-time onboarding.
|
|
193
|
+
|
|
194
|
+
Access it at [http://localhost:4100](http://localhost:4100) after running `canonry serve`.
|
|
195
|
+
|
|
196
|
+
## Requirements
|
|
197
|
+
|
|
198
|
+
- Node.js >= 20
|
|
199
|
+
- At least one provider API key (or a local LLM endpoint)
|
|
200
|
+
- A C++ toolchain for building `better-sqlite3` native bindings (only needed if prebuilt binaries aren't available for your platform)
|
|
201
|
+
|
|
202
|
+
### Native dependency setup
|
|
203
|
+
|
|
204
|
+
Canonry uses `better-sqlite3` for its embedded database. Prebuilt binaries are downloaded automatically for most platforms, but if `npm install` fails with a `node-gyp` error, you need to install build tools:
|
|
205
|
+
|
|
206
|
+
**macOS:**
|
|
207
|
+
```bash
|
|
208
|
+
xcode-select --install
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Debian / Ubuntu:**
|
|
212
|
+
```bash
|
|
213
|
+
sudo apt-get install -y python3 make g++
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Alpine Linux (Docker):**
|
|
217
|
+
```bash
|
|
218
|
+
apk add --no-cache python3 make g++ gcc musl-dev
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Windows:**
|
|
222
|
+
```bash
|
|
223
|
+
npm install -g windows-build-tools
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
If you're running in a minimal Docker image or CI environment without these tools, the install will fail. See the [better-sqlite3 troubleshooting guide](https://github.com/WiseLibs/better-sqlite3/blob/master/docs/troubleshooting.md) for additional help.
|
|
227
|
+
|
|
228
|
+
## Development
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
git clone https://github.com/ainyc/canonry.git
|
|
232
|
+
cd canonry
|
|
233
|
+
pnpm install
|
|
234
|
+
pnpm run typecheck
|
|
235
|
+
pnpm run test
|
|
236
|
+
pnpm run lint
|
|
237
|
+
pnpm run dev:web # Run SPA in dev mode
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Contributing
|
|
241
|
+
|
|
242
|
+
Contributions are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions.
|
|
243
|
+
|
|
244
|
+
## License
|
|
245
|
+
|
|
246
|
+
[AGPL-3.0-only](./LICENSE)
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
Built by [AI NYC](https://ainyc.ai)
|
|
@@ -60,6 +60,7 @@ function configExists() {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
// src/server.ts
|
|
63
|
+
import { createRequire } from "module";
|
|
63
64
|
import fs2 from "fs";
|
|
64
65
|
import path2 from "path";
|
|
65
66
|
import { fileURLToPath } from "url";
|
|
@@ -3507,6 +3508,8 @@ var Notifier = class {
|
|
|
3507
3508
|
};
|
|
3508
3509
|
|
|
3509
3510
|
// src/server.ts
|
|
3511
|
+
var _require = createRequire(import.meta.url);
|
|
3512
|
+
var { version: PKG_VERSION } = _require("../package.json");
|
|
3510
3513
|
var DEFAULT_QUOTA = {
|
|
3511
3514
|
maxConcurrency: 2,
|
|
3512
3515
|
maxRequestsPerMinute: 10,
|
|
@@ -3684,7 +3687,7 @@ async function createServer(opts) {
|
|
|
3684
3687
|
app.get("/health", async () => ({
|
|
3685
3688
|
status: "ok",
|
|
3686
3689
|
service: "canonry",
|
|
3687
|
-
version:
|
|
3690
|
+
version: PKG_VERSION
|
|
3688
3691
|
}));
|
|
3689
3692
|
scheduler.start();
|
|
3690
3693
|
app.addHook("onClose", async () => {
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
loadConfig,
|
|
10
10
|
migrate,
|
|
11
11
|
saveConfig
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-W6AJ2472.js";
|
|
13
13
|
|
|
14
14
|
// src/cli.ts
|
|
15
15
|
import { parseArgs } from "util";
|
|
@@ -36,11 +36,11 @@ var DEFAULT_QUOTA = {
|
|
|
36
36
|
maxRequestsPerMinute: 10,
|
|
37
37
|
maxRequestsPerDay: 500
|
|
38
38
|
};
|
|
39
|
-
async function initCommand() {
|
|
39
|
+
async function initCommand(opts) {
|
|
40
40
|
console.log("Initializing canonry...\n");
|
|
41
|
-
if (configExists()) {
|
|
41
|
+
if (configExists() && !opts?.force) {
|
|
42
42
|
console.log(`Config already exists at ${getConfigPath()}`);
|
|
43
|
-
console.log(
|
|
43
|
+
console.log('To reinitialize, run "canonry init --force".');
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
const configDir = getConfigDir();
|
|
@@ -109,13 +109,14 @@ Config saved to ${getConfigPath()}`);
|
|
|
109
109
|
async function serveCommand() {
|
|
110
110
|
const config = loadConfig();
|
|
111
111
|
const port = parseInt(process.env.CANONRY_PORT ?? "4100", 10);
|
|
112
|
+
const host = process.env.CANONRY_HOST ?? "127.0.0.1";
|
|
112
113
|
const db = createClient(config.database);
|
|
113
114
|
migrate(db);
|
|
114
115
|
const app = await createServer({ config, db });
|
|
115
116
|
try {
|
|
116
|
-
await app.listen({ host
|
|
117
|
+
await app.listen({ host, port });
|
|
117
118
|
console.log(`
|
|
118
|
-
Canonry server running at http
|
|
119
|
+
Canonry server running at http://${host === "0.0.0.0" ? "localhost" : host}:${port}`);
|
|
119
120
|
console.log("Press Ctrl+C to stop.\n");
|
|
120
121
|
} catch (err) {
|
|
121
122
|
app.log.error(err);
|
|
@@ -668,11 +669,12 @@ function printNotification(n) {
|
|
|
668
669
|
}
|
|
669
670
|
|
|
670
671
|
// src/cli.ts
|
|
672
|
+
import { createRequire } from "module";
|
|
671
673
|
var USAGE = `
|
|
672
674
|
canonry \u2014 AEO monitoring CLI
|
|
673
675
|
|
|
674
676
|
Usage:
|
|
675
|
-
canonry init
|
|
677
|
+
canonry init [--force] Initialize config and database
|
|
676
678
|
canonry serve Start the local server
|
|
677
679
|
canonry project create <name> Create a project
|
|
678
680
|
canonry project list List all projects
|
|
@@ -707,6 +709,7 @@ Usage:
|
|
|
707
709
|
|
|
708
710
|
Options:
|
|
709
711
|
--port <port> Server port (default: 4100)
|
|
712
|
+
--host <host> Server bind address (default: 127.0.0.1)
|
|
710
713
|
--domain <domain> Canonical domain for project create
|
|
711
714
|
--country <code> Country code (default: US)
|
|
712
715
|
--language <lang> Language code (default: en)
|
|
@@ -718,7 +721,8 @@ Options:
|
|
|
718
721
|
--webhook <url> Webhook URL for notifications
|
|
719
722
|
--events <list> Comma-separated notification events
|
|
720
723
|
`.trim();
|
|
721
|
-
var
|
|
724
|
+
var _require = createRequire(import.meta.url);
|
|
725
|
+
var { version: VERSION } = _require("../package.json");
|
|
722
726
|
async function main() {
|
|
723
727
|
const args = process.argv.slice(2);
|
|
724
728
|
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
@@ -732,18 +736,22 @@ async function main() {
|
|
|
732
736
|
const command = args[0];
|
|
733
737
|
try {
|
|
734
738
|
switch (command) {
|
|
735
|
-
case "init":
|
|
736
|
-
|
|
739
|
+
case "init": {
|
|
740
|
+
const initForce = args.includes("--force") || args.includes("-f");
|
|
741
|
+
await initCommand({ force: initForce });
|
|
737
742
|
break;
|
|
743
|
+
}
|
|
738
744
|
case "serve": {
|
|
739
745
|
const { values } = parseArgs({
|
|
740
746
|
args: args.slice(1),
|
|
741
747
|
options: {
|
|
742
|
-
port: { type: "string", short: "p", default: "4100" }
|
|
748
|
+
port: { type: "string", short: "p", default: "4100" },
|
|
749
|
+
host: { type: "string", short: "H" }
|
|
743
750
|
},
|
|
744
751
|
allowPositionals: false
|
|
745
752
|
});
|
|
746
753
|
process.env.CANONRY_PORT = values.port;
|
|
754
|
+
if (values.host) process.env.CANONRY_HOST = values.host;
|
|
747
755
|
await serveCommand();
|
|
748
756
|
break;
|
|
749
757
|
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { FastifyInstance } from 'fastify';
|
|
2
|
+
import { DatabaseClient } from '@ainyc/canonry-db';
|
|
3
|
+
import { ProviderQuotaPolicy } from '@ainyc/canonry-contracts';
|
|
4
|
+
|
|
5
|
+
interface ProviderConfigEntry {
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
model?: string;
|
|
9
|
+
quota?: ProviderQuotaPolicy;
|
|
10
|
+
}
|
|
11
|
+
interface CanonryConfig {
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
database: string;
|
|
14
|
+
apiKey: string;
|
|
15
|
+
port?: number;
|
|
16
|
+
geminiApiKey?: string;
|
|
17
|
+
geminiModel?: string;
|
|
18
|
+
geminiQuota?: ProviderQuotaPolicy;
|
|
19
|
+
providers?: {
|
|
20
|
+
gemini?: ProviderConfigEntry;
|
|
21
|
+
openai?: ProviderConfigEntry;
|
|
22
|
+
claude?: ProviderConfigEntry;
|
|
23
|
+
local?: ProviderConfigEntry;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
declare function loadConfig(): CanonryConfig;
|
|
27
|
+
|
|
28
|
+
declare function createServer(opts: {
|
|
29
|
+
config: CanonryConfig;
|
|
30
|
+
db: DatabaseClient;
|
|
31
|
+
open?: boolean;
|
|
32
|
+
}): Promise<FastifyInstance>;
|
|
33
|
+
|
|
34
|
+
export { type CanonryConfig, createServer, loadConfig };
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"bin": {
|
|
@@ -8,16 +8,17 @@
|
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"types": "./
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
-
"types": "./
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
16
|
"files": [
|
|
17
17
|
"bin/",
|
|
18
18
|
"dist/",
|
|
19
19
|
"assets/",
|
|
20
|
-
"
|
|
20
|
+
"package.json",
|
|
21
|
+
"README.md"
|
|
21
22
|
],
|
|
22
23
|
"engines": {
|
|
23
24
|
"node": ">=20"
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
"drizzle-orm": "^0.45.1",
|
|
31
32
|
"fastify": "^5.4.0",
|
|
32
33
|
"node-cron": "^4.2.1",
|
|
33
|
-
"openai": "^
|
|
34
|
+
"openai": "^6.0.0",
|
|
34
35
|
"pino-pretty": "^13.1.3",
|
|
35
36
|
"yaml": "^2.7.1",
|
|
36
37
|
"zod": "^4.1.12"
|
|
@@ -44,9 +45,9 @@
|
|
|
44
45
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
45
46
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
46
47
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
47
|
-
"@ainyc/canonry-db": "0.0.0",
|
|
48
48
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
49
|
-
"@ainyc/canonry-provider-openai": "0.0.0"
|
|
49
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
50
|
+
"@ainyc/canonry-db": "0.0.0"
|
|
50
51
|
},
|
|
51
52
|
"scripts": {
|
|
52
53
|
"build": "tsup && tsx build-web.ts",
|