@hasna/knowledge 0.2.25 → 0.2.27
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 +35 -0
- package/bin/open-knowledge-mcp.js +71 -3
- package/bin/open-knowledge.js +86 -86
- package/docs/architecture/ai-native-knowledge-base.md +24 -0
- package/docs/architecture/hosted-wrapper-responsibilities.md +8 -0
- package/docs/canonical-secrets-bootstrap-2026-06-08.md +127 -0
- package/docs/examples/company-wiki-workflow.md +176 -0
- package/docs/migration/json-to-sqlite.md +151 -0
- package/package.json +1 -1
- package/src/cli.ts +8 -5
- package/src/service.ts +13 -2
- package/src/storage-contract.ts +54 -1
- package/src/workspace.ts +38 -0
package/README.md
CHANGED
|
@@ -122,6 +122,21 @@ knowledge "How do we cite handbook policy?" --scope project --json
|
|
|
122
122
|
HASNA_KNOWLEDGE_WEB_SEARCH=1 open-knowledge web search "latest AI SDK web search" --provider openai --json
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
## Guides
|
|
126
|
+
|
|
127
|
+
- [Company wiki workflow](docs/examples/company-wiki-workflow.md): an end-to-end
|
|
128
|
+
local workflow for open-files manifests, search, prompt runs, cited wiki
|
|
129
|
+
pages, linting, reindexing, MCP, and optional hosted/S3 mode.
|
|
130
|
+
- [JSON to SQLite migration](docs/migration/json-to-sqlite.md): how legacy
|
|
131
|
+
JSON notes coexist with the `.hasna/apps/knowledge` workspace and the
|
|
132
|
+
versioned SQLite catalog.
|
|
133
|
+
- [AI-native architecture](docs/architecture/ai-native-knowledge-base.md):
|
|
134
|
+
source boundaries, wiki model, search model, provider registry, and non-goals.
|
|
135
|
+
- [Hybrid semantic search](docs/architecture/hybrid-semantic-search.md):
|
|
136
|
+
keyword/vector/search-context contracts and hosted index options.
|
|
137
|
+
- [Hosted wrapper responsibilities](docs/architecture/hosted-wrapper-responsibilities.md):
|
|
138
|
+
what a future SaaS layer owns outside the OSS package.
|
|
139
|
+
|
|
125
140
|
## Commands
|
|
126
141
|
|
|
127
142
|
### add
|
|
@@ -214,10 +229,26 @@ knowledge bucket/prefix while `open-files` remains the source of truth for raw
|
|
|
214
229
|
source bytes. The command also reports artifact classes, allowed source ref
|
|
215
230
|
schemes, and warnings for non-scalable or unsafe config.
|
|
216
231
|
|
|
232
|
+
For Hasna XYZ production, the canonical generated-artifact bucket is
|
|
233
|
+
`hasna-xyz-opensource-knowledge-prod` in `us-east-1` with prefix
|
|
234
|
+
`.hasna/apps/knowledge/`. `storage status --json` exposes this under
|
|
235
|
+
`canonical_hasna_xyz` even when local storage is active. The canonical
|
|
236
|
+
metadata-only secret paths are:
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
hasna/xyz/opensource/knowledge/prod/env
|
|
240
|
+
hasna/xyz/opensource/knowledge/prod/aws
|
|
241
|
+
hasna/xyz/opensource/knowledge/prod/s3
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The future hosted database path, if provisioned, is
|
|
245
|
+
`hasna/xyz/opensource/knowledge/prod/rds`.
|
|
246
|
+
|
|
217
247
|
### setup / auth / remote
|
|
218
248
|
```bash
|
|
219
249
|
open-knowledge setup --mode local [--scope project] [--json]
|
|
220
250
|
open-knowledge setup --mode hosted [--api-url https://knowledge.hasna.xyz] [--scope project] [--json]
|
|
251
|
+
open-knowledge setup --mode hosted --canonical-hasna-xyz [--scope project] [--json]
|
|
221
252
|
open-knowledge auth login --api-key <key> [--email you@example.com] [--org <slug>] [--scope project] [--json]
|
|
222
253
|
open-knowledge auth whoami [--scope project] [--json]
|
|
223
254
|
open-knowledge auth logout [--scope project] [--json]
|
|
@@ -503,6 +534,10 @@ prompt, embedding, or agent command explicitly requests a model.
|
|
|
503
534
|
|
|
504
535
|
Generated knowledge artifacts can be stored locally under
|
|
505
536
|
`.hasna/apps/knowledge/artifacts` or through the S3 artifact-store adapter.
|
|
537
|
+
For Hasna XYZ production, `open-knowledge setup --mode hosted
|
|
538
|
+
--canonical-hasna-xyz --scope project --json` configures generated artifacts
|
|
539
|
+
under `s3://hasna-xyz-opensource-knowledge-prod/.hasna/apps/knowledge/` and
|
|
540
|
+
keeps `open-files` as the raw-source owner.
|
|
506
541
|
|
|
507
542
|
The default safety policy allows writes only under the resolved
|
|
508
543
|
`.hasna/apps/knowledge` workspace. S3 manifest/outbox reads require
|
|
@@ -13660,7 +13660,7 @@ 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.
|
|
13663
|
+
version: "0.2.27",
|
|
13664
13664
|
description: "Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",
|
|
13665
13665
|
type: "module",
|
|
13666
13666
|
bin: {
|
|
@@ -13731,6 +13731,42 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
|
13731
13731
|
import { homedir } from "os";
|
|
13732
13732
|
import { dirname, join, resolve } from "path";
|
|
13733
13733
|
var HASNA_KNOWLEDGE_APP_PATH = join(".hasna", "apps", "knowledge");
|
|
13734
|
+
var HASNA_XYZ_KNOWLEDGE_CANONICAL = {
|
|
13735
|
+
division: "xyz",
|
|
13736
|
+
app_type: "opensource",
|
|
13737
|
+
app: "knowledge",
|
|
13738
|
+
env: "prod",
|
|
13739
|
+
local_path: HASNA_KNOWLEDGE_APP_PATH,
|
|
13740
|
+
s3: {
|
|
13741
|
+
bucket: "hasna-xyz-opensource-knowledge-prod",
|
|
13742
|
+
region: "us-east-1",
|
|
13743
|
+
profile: "hasna-xyz-infra",
|
|
13744
|
+
prefix: ".hasna/apps/knowledge",
|
|
13745
|
+
server_side_encryption: "AES256"
|
|
13746
|
+
},
|
|
13747
|
+
secrets: {
|
|
13748
|
+
env: "hasna/xyz/opensource/knowledge/prod/env",
|
|
13749
|
+
aws: "hasna/xyz/opensource/knowledge/prod/aws",
|
|
13750
|
+
s3: "hasna/xyz/opensource/knowledge/prod/s3",
|
|
13751
|
+
rds: null,
|
|
13752
|
+
future_rds: "hasna/xyz/opensource/knowledge/prod/rds"
|
|
13753
|
+
},
|
|
13754
|
+
source_owner: "open-files",
|
|
13755
|
+
evidence_doc: "docs/canonical-secrets-bootstrap-2026-06-08.md"
|
|
13756
|
+
};
|
|
13757
|
+
function canonicalHasnaXyzKnowledgeStorage() {
|
|
13758
|
+
return {
|
|
13759
|
+
type: "s3",
|
|
13760
|
+
artifacts_root: "artifacts",
|
|
13761
|
+
s3: {
|
|
13762
|
+
bucket: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket,
|
|
13763
|
+
prefix: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.prefix,
|
|
13764
|
+
region: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.region,
|
|
13765
|
+
profile: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.profile,
|
|
13766
|
+
server_side_encryption: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.server_side_encryption
|
|
13767
|
+
}
|
|
13768
|
+
};
|
|
13769
|
+
}
|
|
13734
13770
|
function legacyGlobalStorePath() {
|
|
13735
13771
|
return join(homedir(), ".open-knowledge", "db.json");
|
|
13736
13772
|
}
|
|
@@ -18115,6 +18151,9 @@ function resolveStorageContract(config2, workspace, scope = "global") {
|
|
|
18115
18151
|
const s3 = config2.storage.s3 ?? null;
|
|
18116
18152
|
const prefix = s3?.prefix?.replace(/^\/+|\/+$/g, "") ?? "";
|
|
18117
18153
|
const s3UriPrefix = s3 ? `s3://${s3.bucket}/${prefix ? `${prefix}/` : ""}` : "";
|
|
18154
|
+
const canonicalPrefix = HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.prefix.replace(/^\/+|\/+$/g, "");
|
|
18155
|
+
const canonicalS3UriPrefix = `s3://${HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket}/${canonicalPrefix}/`;
|
|
18156
|
+
const canonicalActive = config2.storage.type === "s3" && s3?.bucket === HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket && (s3.region ?? null) === HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.region;
|
|
18118
18157
|
return {
|
|
18119
18158
|
scope,
|
|
18120
18159
|
mode: config2.mode,
|
|
@@ -18149,6 +18188,30 @@ function resolveStorageContract(config2, workspace, scope = "global") {
|
|
|
18149
18188
|
kms_key_configured: Boolean(s3.kms_key_id)
|
|
18150
18189
|
} : null
|
|
18151
18190
|
},
|
|
18191
|
+
canonical_hasna_xyz: {
|
|
18192
|
+
division: HASNA_XYZ_KNOWLEDGE_CANONICAL.division,
|
|
18193
|
+
app_type: HASNA_XYZ_KNOWLEDGE_CANONICAL.app_type,
|
|
18194
|
+
app: HASNA_XYZ_KNOWLEDGE_CANONICAL.app,
|
|
18195
|
+
env: HASNA_XYZ_KNOWLEDGE_CANONICAL.env,
|
|
18196
|
+
active: canonicalActive,
|
|
18197
|
+
local_path: HASNA_XYZ_KNOWLEDGE_CANONICAL.local_path,
|
|
18198
|
+
s3: {
|
|
18199
|
+
bucket: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.bucket,
|
|
18200
|
+
region: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.region,
|
|
18201
|
+
profile: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.profile,
|
|
18202
|
+
prefix: canonicalPrefix,
|
|
18203
|
+
uri_prefix: canonicalS3UriPrefix,
|
|
18204
|
+
server_side_encryption: HASNA_XYZ_KNOWLEDGE_CANONICAL.s3.server_side_encryption
|
|
18205
|
+
},
|
|
18206
|
+
secrets: {
|
|
18207
|
+
env: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.env,
|
|
18208
|
+
aws: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.aws,
|
|
18209
|
+
s3: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.s3,
|
|
18210
|
+
rds: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.rds,
|
|
18211
|
+
future_rds: HASNA_XYZ_KNOWLEDGE_CANONICAL.secrets.future_rds
|
|
18212
|
+
},
|
|
18213
|
+
evidence_doc: HASNA_XYZ_KNOWLEDGE_CANONICAL.evidence_doc
|
|
18214
|
+
},
|
|
18152
18215
|
hosted: {
|
|
18153
18216
|
enabled: config2.mode === "hosted",
|
|
18154
18217
|
api_url: normalizeKnowledgeApiOrigin(config2.hosted?.api_url ?? DEFAULT_KNOWLEDGE_API_URL),
|
|
@@ -19058,16 +19121,21 @@ class KnowledgeService {
|
|
|
19058
19121
|
hosted: {
|
|
19059
19122
|
...current.hosted ?? {},
|
|
19060
19123
|
...apiUrl ? { api_url: apiUrl } : {}
|
|
19061
|
-
}
|
|
19124
|
+
},
|
|
19125
|
+
storage: options.canonicalHasnaXyz ? canonicalHasnaXyzKnowledgeStorage() : current.storage
|
|
19062
19126
|
};
|
|
19063
19127
|
writeKnowledgeConfig(workspace.configPath, nextConfig);
|
|
19064
19128
|
this.cachedConfig = nextConfig;
|
|
19129
|
+
const storage = resolveStorageContract(nextConfig, workspace, this.scope);
|
|
19065
19130
|
return {
|
|
19066
19131
|
ok: true,
|
|
19067
19132
|
mode,
|
|
19068
19133
|
api_url: nextConfig.hosted?.api_url ?? null,
|
|
19134
|
+
storage_type: nextConfig.storage.type,
|
|
19135
|
+
artifact_uri_prefix: storage.artifact_store.uri_prefix,
|
|
19136
|
+
canonical_hasna_xyz: storage.canonical_hasna_xyz,
|
|
19069
19137
|
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>"],
|
|
19138
|
+
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
19139
|
message: `Set knowledge mode to ${mode}`
|
|
19072
19140
|
};
|
|
19073
19141
|
}
|