@hasna/knowledge 0.2.26 → 0.2.28

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.
Files changed (61) hide show
  1. package/README.md +61 -0
  2. package/bin/open-knowledge-mcp.js +85 -9
  3. package/bin/open-knowledge.js +86 -86
  4. package/dist/agent.d.ts +35 -0
  5. package/dist/artifact-store.d.ts +63 -0
  6. package/dist/auth.d.ts +35 -0
  7. package/dist/embeddings.d.ts +77 -0
  8. package/dist/index.d.ts +20 -0
  9. package/dist/index.js +5709 -0
  10. package/dist/knowledge-db.d.ts +27 -0
  11. package/dist/manifest-ingest.d.ts +35 -0
  12. package/dist/outbox-consume.d.ts +25 -0
  13. package/dist/provenance.d.ts +50 -0
  14. package/dist/providers.d.ts +89 -0
  15. package/dist/reindex.d.ts +37 -0
  16. package/dist/remote-client.d.ts +108 -0
  17. package/dist/retrieval.d.ts +71 -0
  18. package/dist/safety.d.ts +70 -0
  19. package/dist/sdk.d.ts +72 -0
  20. package/dist/search.d.ts +65 -0
  21. package/dist/service.d.ts +117 -0
  22. package/dist/source-ingest.d.ts +18 -0
  23. package/dist/source-ref.d.ts +30 -0
  24. package/dist/source-resolver.d.ts +92 -0
  25. package/dist/storage-contract.d.ts +106 -0
  26. package/dist/web-search.d.ts +40 -0
  27. package/dist/wiki-compiler.d.ts +67 -0
  28. package/dist/wiki-layout.d.ts +23 -0
  29. package/dist/workspace.d.ts +111 -0
  30. package/docs/architecture/ai-native-knowledge-base.md +24 -0
  31. package/docs/architecture/hosted-wrapper-responsibilities.md +8 -0
  32. package/docs/canonical-secrets-bootstrap-2026-06-08.md +127 -0
  33. package/package.json +15 -7
  34. package/src/agent.ts +0 -367
  35. package/src/artifact-store.ts +0 -184
  36. package/src/auth.ts +0 -123
  37. package/src/cli.ts +0 -1181
  38. package/src/embeddings.ts +0 -516
  39. package/src/knowledge-db.ts +0 -354
  40. package/src/manifest-ingest.ts +0 -515
  41. package/src/mcp-http.js +0 -110
  42. package/src/mcp.js +0 -1503
  43. package/src/outbox-consume.ts +0 -463
  44. package/src/provenance.ts +0 -93
  45. package/src/providers.ts +0 -308
  46. package/src/reindex.ts +0 -260
  47. package/src/remote-client.ts +0 -268
  48. package/src/retrieval.ts +0 -326
  49. package/src/safety.ts +0 -265
  50. package/src/schema.js +0 -25
  51. package/src/search.ts +0 -510
  52. package/src/service.ts +0 -432
  53. package/src/source-ingest.ts +0 -268
  54. package/src/source-ref.ts +0 -104
  55. package/src/source-resolver.ts +0 -436
  56. package/src/storage-contract.ts +0 -293
  57. package/src/store.ts +0 -113
  58. package/src/web-search.ts +0 -330
  59. package/src/wiki-compiler.ts +0 -711
  60. package/src/wiki-layout.ts +0 -251
  61. package/src/workspace.ts +0 -213
package/README.md CHANGED
@@ -32,6 +32,47 @@ Or run directly:
32
32
  bun x @hasna/knowledge add "My Note" "Some content"
33
33
  ```
34
34
 
35
+ ## SDK
36
+
37
+ Apps can install the package and use the public SDK without shelling out to the
38
+ CLI or importing internal source files:
39
+
40
+ ```ts
41
+ import { createKnowledgeClient } from '@hasna/knowledge';
42
+
43
+ const knowledge = createKnowledgeClient({
44
+ scope: 'project',
45
+ cwd: process.cwd(),
46
+ });
47
+
48
+ await knowledge.setup({ mode: 'hosted', canonicalHasnaXyz: true });
49
+ await knowledge.ingest.source('file:///absolute/path/to/handbook.md', 'knowledge_index');
50
+
51
+ const results = await knowledge.search({
52
+ query: 'company wiki policy',
53
+ semantic: true,
54
+ limit: 5,
55
+ });
56
+
57
+ const answer = await knowledge.ask('How do we cite handbook policy?', {
58
+ semantic: true,
59
+ limit: 5,
60
+ });
61
+ ```
62
+
63
+ The stable package surface is the top-level `@hasna/knowledge` export:
64
+ `createKnowledgeClient`, `createKnowledgeSdk`, service/result types, workspace
65
+ helpers, source-ref helpers, storage contracts, search/retrieval types,
66
+ provider helpers, and remote contract types. CLI and MCP entrypoints remain
67
+ available as package bins.
68
+
69
+ The SDK uses the same `.hasna/apps/knowledge` project workspace as the CLI. In
70
+ local mode it writes the SQLite catalog and generated artifacts under that path.
71
+ In hosted/canonical mode it can point generated artifacts at S3 while keeping
72
+ raw source ownership outside open-knowledge. Source files remain referenced via
73
+ `open-files://`, `file://`, `s3://`, or web refs; open-knowledge stores derived
74
+ chunks, citations, indexes, run logs, and generated wiki artifacts.
75
+
35
76
  ## Quick Start
36
77
 
37
78
  ```bash
@@ -229,10 +270,26 @@ knowledge bucket/prefix while `open-files` remains the source of truth for raw
229
270
  source bytes. The command also reports artifact classes, allowed source ref
230
271
  schemes, and warnings for non-scalable or unsafe config.
231
272
 
273
+ For Hasna XYZ production, the canonical generated-artifact bucket is
274
+ `hasna-xyz-opensource-knowledge-prod` in `us-east-1` with prefix
275
+ `.hasna/apps/knowledge/`. `storage status --json` exposes this under
276
+ `canonical_hasna_xyz` even when local storage is active. The canonical
277
+ metadata-only secret paths are:
278
+
279
+ ```text
280
+ hasna/xyz/opensource/knowledge/prod/env
281
+ hasna/xyz/opensource/knowledge/prod/aws
282
+ hasna/xyz/opensource/knowledge/prod/s3
283
+ ```
284
+
285
+ The future hosted database path, if provisioned, is
286
+ `hasna/xyz/opensource/knowledge/prod/rds`.
287
+
232
288
  ### setup / auth / remote
233
289
  ```bash
234
290
  open-knowledge setup --mode local [--scope project] [--json]
235
291
  open-knowledge setup --mode hosted [--api-url https://knowledge.hasna.xyz] [--scope project] [--json]
292
+ open-knowledge setup --mode hosted --canonical-hasna-xyz [--scope project] [--json]
236
293
  open-knowledge auth login --api-key <key> [--email you@example.com] [--org <slug>] [--scope project] [--json]
237
294
  open-knowledge auth whoami [--scope project] [--json]
238
295
  open-knowledge auth logout [--scope project] [--json]
@@ -518,6 +575,10 @@ prompt, embedding, or agent command explicitly requests a model.
518
575
 
519
576
  Generated knowledge artifacts can be stored locally under
520
577
  `.hasna/apps/knowledge/artifacts` or through the S3 artifact-store adapter.
578
+ For Hasna XYZ production, `open-knowledge setup --mode hosted
579
+ --canonical-hasna-xyz --scope project --json` configures generated artifacts
580
+ under `s3://hasna-xyz-opensource-knowledge-prod/.hasna/apps/knowledge/` and
581
+ keeps `open-files` as the raw-source owner.
521
582
 
522
583
  The default safety policy allows writes only under the resolved
523
584
  `.hasna/apps/knowledge` workspace. S3 manifest/outbox reads require
@@ -13660,9 +13660,17 @@ import { existsSync as existsSync8, readFileSync as readFileSync8, writeFileSync
13660
13660
  // package.json
13661
13661
  var package_default = {
13662
13662
  name: "@hasna/knowledge",
13663
- version: "0.2.26",
13663
+ version: "0.2.28",
13664
13664
  description: "Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",
13665
13665
  type: "module",
13666
+ exports: {
13667
+ ".": {
13668
+ import: "./dist/index.js",
13669
+ types: "./dist/index.d.ts"
13670
+ }
13671
+ },
13672
+ main: "./dist/index.js",
13673
+ types: "./dist/index.d.ts",
13666
13674
  bin: {
13667
13675
  knowledge: "bin/open-knowledge.js",
13668
13676
  "open-knowledge": "bin/open-knowledge.js",
@@ -13670,7 +13678,7 @@ var package_default = {
13670
13678
  },
13671
13679
  files: [
13672
13680
  "bin",
13673
- "src",
13681
+ "dist",
13674
13682
  "docs",
13675
13683
  "LICENSE",
13676
13684
  "README.md"
@@ -13678,9 +13686,8 @@ var package_default = {
13678
13686
  scripts: {
13679
13687
  test: "bun test",
13680
13688
  "test:cli": "bun test tests/cli.test.ts",
13681
- build: "bun build --target=bun --outfile=bin/open-knowledge.js --minify --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/cli.ts && bun build --target=bun --outfile=bin/open-knowledge-mcp.js --external @modelcontextprotocol/sdk --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/mcp.js",
13682
- prepublishOnly: "bun run build",
13683
- postinstall: "bun run build"
13689
+ build: "rm -rf dist && bun build --target=bun --outfile=bin/open-knowledge.js --minify --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/cli.ts && bun build --target=bun --outfile=bin/open-knowledge-mcp.js --external @modelcontextprotocol/sdk --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/mcp.js && bun build ./src/index.ts --outdir ./dist --target bun --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek && bunx tsc -p tsconfig.build.json",
13690
+ prepublishOnly: "bun run build"
13684
13691
  },
13685
13692
  keywords: [
13686
13693
  "knowledge",
@@ -13709,12 +13716,13 @@ var package_default = {
13709
13716
  node: ">=18"
13710
13717
  },
13711
13718
  dependencies: {
13712
- "@aws-sdk/client-s3": "^3.1063.0",
13713
- "@aws-sdk/credential-providers": "^3.1063.0",
13714
13719
  "@ai-sdk/anthropic": "^3.0.81",
13715
13720
  "@ai-sdk/deepseek": "^2.0.35",
13716
13721
  "@ai-sdk/openai": "^3.0.68",
13722
+ "@aws-sdk/client-s3": "^3.1063.0",
13723
+ "@aws-sdk/credential-providers": "^3.1063.0",
13717
13724
  "@modelcontextprotocol/sdk": "^1.29.0",
13725
+ "@types/json-schema": "^7.0.15",
13718
13726
  ai: "^6.0.197",
13719
13727
  zod: "^4.3.6"
13720
13728
  },
@@ -13731,6 +13739,42 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
13731
13739
  import { homedir } from "os";
13732
13740
  import { dirname, join, resolve } from "path";
13733
13741
  var HASNA_KNOWLEDGE_APP_PATH = join(".hasna", "apps", "knowledge");
13742
+ var HASNA_XYZ_KNOWLEDGE_CANONICAL = {
13743
+ division: "xyz",
13744
+ app_type: "opensource",
13745
+ app: "knowledge",
13746
+ env: "prod",
13747
+ local_path: HASNA_KNOWLEDGE_APP_PATH,
13748
+ s3: {
13749
+ bucket: "hasna-xyz-opensource-knowledge-prod",
13750
+ region: "us-east-1",
13751
+ profile: "hasna-xyz-infra",
13752
+ prefix: ".hasna/apps/knowledge",
13753
+ server_side_encryption: "AES256"
13754
+ },
13755
+ secrets: {
13756
+ env: "hasna/xyz/opensource/knowledge/prod/env",
13757
+ aws: "hasna/xyz/opensource/knowledge/prod/aws",
13758
+ s3: "hasna/xyz/opensource/knowledge/prod/s3",
13759
+ rds: null,
13760
+ future_rds: "hasna/xyz/opensource/knowledge/prod/rds"
13761
+ },
13762
+ source_owner: "open-files",
13763
+ evidence_doc: "docs/canonical-secrets-bootstrap-2026-06-08.md"
13764
+ };
13765
+ function canonicalHasnaXyzKnowledgeStorage() {
13766
+ return {
13767
+ type: "s3",
13768
+ artifacts_root: "artifacts",
13769
+ s3: {
13770
+ bucket: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket,
13771
+ prefix: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.prefix,
13772
+ region: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.region,
13773
+ profile: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.profile,
13774
+ server_side_encryption: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.server_side_encryption
13775
+ }
13776
+ };
13777
+ }
13734
13778
  function legacyGlobalStorePath() {
13735
13779
  return join(homedir(), ".open-knowledge", "db.json");
13736
13780
  }
@@ -18115,6 +18159,9 @@ function resolveStorageContract(config2, workspace, scope = "global") {
18115
18159
  const s3 = config2.storage.s3 ?? null;
18116
18160
  const prefix = s3?.prefix?.replace(/^\/+|\/+$/g, "") ?? "";
18117
18161
  const s3UriPrefix = s3 ? `s3://${s3.bucket}/${prefix ? `${prefix}/` : ""}` : "";
18162
+ const canonicalPrefix = HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.prefix.replace(/^\/+|\/+$/g, "");
18163
+ const canonicalS3UriPrefix = `s3://${HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket}/${canonicalPrefix}/`;
18164
+ const canonicalActive = config2.storage.type === "s3" && s3?.bucket === HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket && (s3.region ?? null) === HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.region;
18118
18165
  return {
18119
18166
  scope,
18120
18167
  mode: config2.mode,
@@ -18149,6 +18196,30 @@ function resolveStorageContract(config2, workspace, scope = "global") {
18149
18196
  kms_key_configured: Boolean(s3.kms_key_id)
18150
18197
  } : null
18151
18198
  },
18199
+ canonical_hasna_xyz: {
18200
+ division: HASNA_XYZ_KNOWLEDGE_CANONICAL.division,
18201
+ app_type: HASNA_XYZ_KNOWLEDGE_CANONICAL.app_type,
18202
+ app: HASNA_XYZ_KNOWLEDGE_CANONICAL.app,
18203
+ env: HASNA_XYZ_KNOWLEDGE_CANONICAL.env,
18204
+ active: canonicalActive,
18205
+ local_path: HASNA_XYZ_KNOWLEDGE_CANONICAL.local_path,
18206
+ s3: {
18207
+ bucket: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket,
18208
+ region: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.region,
18209
+ profile: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.profile,
18210
+ prefix: canonicalPrefix,
18211
+ uri_prefix: canonicalS3UriPrefix,
18212
+ server_side_encryption: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.server_side_encryption
18213
+ },
18214
+ secrets: {
18215
+ env: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.env,
18216
+ aws: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.aws,
18217
+ s3: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.s3,
18218
+ rds: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.rds,
18219
+ future_rds: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.future_rds
18220
+ },
18221
+ evidence_doc: HASNA_XYZ_KNOWLEDGE_CANONICAL.evidence_doc
18222
+ },
18152
18223
  hosted: {
18153
18224
  enabled: config2.mode === "hosted",
18154
18225
  api_url: normalizeKnowledgeApiOrigin(config2.hosted?.api_url ?? DEFAULT_KNOWLEDGE_API_URL),
@@ -19058,16 +19129,21 @@ class KnowledgeService {
19058
19129
  hosted: {
19059
19130
  ...current.hosted ?? {},
19060
19131
  ...apiUrl ? { api_url: apiUrl } : {}
19061
- }
19132
+ },
19133
+ storage: options.canonicalHasnaXyz ? canonicalHasnaXyzKnowledgeStorage() : current.storage
19062
19134
  };
19063
19135
  writeKnowledgeConfig(workspace.configPath, nextConfig);
19064
19136
  this.cachedConfig = nextConfig;
19137
+ const storage = resolveStorageContract(nextConfig, workspace, this.scope);
19065
19138
  return {
19066
19139
  ok: true,
19067
19140
  mode,
19068
19141
  api_url: nextConfig.hosted?.api_url ?? null,
19142
+ storage_type: nextConfig.storage.type,
19143
+ artifact_uri_prefix: storage.artifact_store.uri_prefix,
19144
+ canonical_hasna_xyz: storage.canonical_hasna_xyz,
19069
19145
  config_path: workspace.configPath,
19070
- next: mode === "hosted" ? ["open-knowledge auth login --api-key <key>", "open-knowledge remote contracts --json"] : ["open-knowledge search <query>", "knowledge <prompt>"],
19146
+ next: mode === "hosted" ? ["open-knowledge auth login --api-key <key>", "open-knowledge storage status --json", "open-knowledge remote contracts --json"] : ["open-knowledge search <query>", "knowledge <prompt>"],
19071
19147
  message: `Set knowledge mode to ${mode}`
19072
19148
  };
19073
19149
  }