@ainyc/canonry 1.0.1 → 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 CHANGED
@@ -197,6 +197,33 @@ Access it at [http://localhost:4100](http://localhost:4100) after running `canon
197
197
 
198
198
  - Node.js >= 20
199
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.
200
227
 
201
228
  ## Development
202
229
 
@@ -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: "0.1.0"
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-ONZDY6Q4.js";
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("To reinitialize, delete the config file first.");
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: "0.0.0.0", port });
117
+ await app.listen({ host, port });
117
118
  console.log(`
118
- Canonry server running at http://localhost:${port}`);
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 Initialize config and database
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 VERSION = "0.1.0";
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
- await initCommand();
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
  }
@@ -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
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createServer,
3
3
  loadConfig
4
- } from "./chunk-ONZDY6Q4.js";
4
+ } from "./chunk-W6AJ2472.js";
5
5
  export {
6
6
  createServer,
7
7
  loadConfig
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "bin": {
@@ -8,16 +8,16 @@
8
8
  },
9
9
  "exports": {
10
10
  ".": {
11
- "types": "./src/index.ts",
11
+ "types": "./dist/index.d.ts",
12
12
  "default": "./dist/index.js"
13
13
  }
14
14
  },
15
- "types": "./src/index.ts",
15
+ "types": "./dist/index.d.ts",
16
16
  "files": [
17
17
  "bin/",
18
18
  "dist/",
19
19
  "assets/",
20
- "src/",
20
+ "package.json",
21
21
  "README.md"
22
22
  ],
23
23
  "engines": {
@@ -31,7 +31,7 @@
31
31
  "drizzle-orm": "^0.45.1",
32
32
  "fastify": "^5.4.0",
33
33
  "node-cron": "^4.2.1",
34
- "openai": "^4.85.0",
34
+ "openai": "^6.0.0",
35
35
  "pino-pretty": "^13.1.3",
36
36
  "yaml": "^2.7.1",
37
37
  "zod": "^4.1.12"
@@ -43,11 +43,11 @@
43
43
  "tsx": "^4.19.0",
44
44
  "@ainyc/canonry-api-routes": "0.0.0",
45
45
  "@ainyc/canonry-contracts": "0.0.0",
46
- "@ainyc/canonry-db": "0.0.0",
47
- "@ainyc/canonry-provider-gemini": "0.0.0",
48
46
  "@ainyc/canonry-provider-claude": "0.0.0",
47
+ "@ainyc/canonry-provider-gemini": "0.0.0",
48
+ "@ainyc/canonry-provider-local": "0.0.0",
49
49
  "@ainyc/canonry-provider-openai": "0.0.0",
50
- "@ainyc/canonry-provider-local": "0.0.0"
50
+ "@ainyc/canonry-db": "0.0.0"
51
51
  },
52
52
  "scripts": {
53
53
  "build": "tsup && tsx build-web.ts",