norn-cli 4.4.0 → 4.5.1

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.
@@ -6653,7 +6653,7 @@ function ensureNornCacheDir(rootPath) {
6653
6653
  }
6654
6654
 
6655
6655
  // src/knowledge/knowledgeIndex.ts
6656
- var KNOWLEDGE_SCHEMA_VERSION = 2;
6656
+ var KNOWLEDGE_SCHEMA_VERSION = 3;
6657
6657
  var BUSY_TIMEOUT_MS = 5e3;
6658
6658
  var SCHEMA = `
6659
6659
  CREATE TABLE IF NOT EXISTS control (
@@ -6717,6 +6717,7 @@ CREATE TABLE IF NOT EXISTS snapshot_occurrences (
6717
6717
  topic_hash TEXT NOT NULL REFERENCES topics(topic_hash),
6718
6718
  authored_type TEXT,
6719
6719
  authored_use_when TEXT,
6720
+ environment_import TEXT,
6720
6721
  effective_type TEXT NOT NULL,
6721
6722
  start_line INTEGER NOT NULL,
6722
6723
  end_line INTEGER NOT NULL,
@@ -6907,7 +6908,7 @@ var KnowledgeIndex = class {
6907
6908
  fs2.mkdirSync(path2.dirname(this.databasePath), { recursive: true, mode: 448 });
6908
6909
  let database = new import_node_sqlite.DatabaseSync(this.databasePath);
6909
6910
  const version = currentSchemaVersion(database);
6910
- if (version !== 0 && version !== 1 && version !== KNOWLEDGE_SCHEMA_VERSION) {
6911
+ if (version !== 0 && version !== 1 && version !== 2 && version !== KNOWLEDGE_SCHEMA_VERSION) {
6911
6912
  database.close();
6912
6913
  if (options.rejectUnsupportedSchema) {
6913
6914
  throw new Error(`Unsupported knowledge index schema ${version}; expected ${KNOWLEDGE_SCHEMA_VERSION}.`);
@@ -6918,6 +6919,10 @@ var KnowledgeIndex = class {
6918
6919
  this.database = database;
6919
6920
  this.database.exec(`PRAGMA journal_mode = WAL; PRAGMA busy_timeout = ${BUSY_TIMEOUT_MS}; PRAGMA foreign_keys = ON;`);
6920
6921
  this.database.exec(SCHEMA);
6922
+ const occurrenceColumns = this.database.prepare("PRAGMA table_info(snapshot_occurrences)").all();
6923
+ if (!occurrenceColumns.some((column) => column.name === "environment_import")) {
6924
+ this.database.exec("ALTER TABLE snapshot_occurrences ADD COLUMN environment_import TEXT");
6925
+ }
6921
6926
  this.database.exec(`PRAGMA user_version = ${KNOWLEDGE_SCHEMA_VERSION}`);
6922
6927
  try {
6923
6928
  fs2.chmodSync(this.databasePath, 384);
@@ -6994,6 +6999,9 @@ var KnowledgeIndex = class {
6994
6999
  if (row.authored_use_when) {
6995
7000
  metadata.useWhen = { origin: "authored", value: String(row.authored_use_when) };
6996
7001
  }
7002
+ if (row.environment_import) {
7003
+ metadata.import = { origin: "authored", value: String(row.environment_import) };
7004
+ }
6997
7005
  return {
6998
7006
  declarationId: String(row.declaration_id),
6999
7007
  declarationPath: String(row.declaration_path),
@@ -7252,7 +7260,7 @@ function queryKnowledgeEditorFacts(query, options = {}) {
7252
7260
  for (const context of query.contexts) {
7253
7261
  const rows = index.all(`
7254
7262
  SELECT topic_hash, domain_path, item_key, ordinal, heading_text, effective_type,
7255
- authored_type, authored_use_when
7263
+ authored_type, authored_use_when, environment_import
7256
7264
  FROM snapshot_occurrences
7257
7265
  WHERE snapshot_id = ? AND declaration_id = ? AND source_id = ? AND item_key = ?
7258
7266
  ORDER BY ordinal
@@ -7265,6 +7273,9 @@ function queryKnowledgeEditorFacts(query, options = {}) {
7265
7273
  if (row.authored_use_when !== null) {
7266
7274
  metadata.useWhen = { origin: "authored", value: String(row.authored_use_when) };
7267
7275
  }
7276
+ if (row.environment_import !== null) {
7277
+ metadata.import = { origin: "authored", value: String(row.environment_import) };
7278
+ }
7268
7279
  const topicHash = String(row.topic_hash);
7269
7280
  const bucket = occurrencesByHash.get(topicHash) ?? [];
7270
7281
  bucket.push({
@@ -8937,10 +8948,26 @@ function parseMetaBlock(lines, startLine, endLine, diagnostics) {
8937
8948
  } else {
8938
8949
  metadata.useWhen = authored(value);
8939
8950
  }
8951
+ } else if (key === "import") {
8952
+ if (metadata.import) {
8953
+ diagnostics.push({
8954
+ lineNumber: startLine + offset,
8955
+ message: "norn:meta declares import more than once.",
8956
+ code: "knowledge-meta-import-duplicate"
8957
+ });
8958
+ } else if (!/^(["']).*\.nornenv\1$/.test(value)) {
8959
+ diagnostics.push({
8960
+ lineNumber: startLine + offset,
8961
+ message: "The environment import must be a quoted .nornenv path.",
8962
+ code: "knowledge-meta-import-invalid"
8963
+ });
8964
+ } else {
8965
+ metadata.import = authored(value.slice(1, -1));
8966
+ }
8940
8967
  } else {
8941
8968
  diagnostics.push({
8942
8969
  lineNumber: startLine + offset,
8943
- message: `Unknown norn:meta key '${match[1]}'. Expected type or use_when.`,
8970
+ message: `Unknown norn:meta key '${match[1]}'. Expected type, use_when, or import.`,
8944
8971
  code: "knowledge-meta-key-unknown"
8945
8972
  });
8946
8973
  }
@@ -8993,6 +9020,15 @@ function mergeMetadata(target, incoming, lineNumber, diagnostics) {
8993
9020
  } else if (incoming.useWhen) {
8994
9021
  target.useWhen = incoming.useWhen;
8995
9022
  }
9023
+ if (target.import && incoming.import) {
9024
+ diagnostics.push({
9025
+ lineNumber,
9026
+ message: "A topic may have only one environment import.",
9027
+ code: "knowledge-meta-import-duplicate"
9028
+ });
9029
+ } else if (incoming.import) {
9030
+ target.import = incoming.import;
9031
+ }
8996
9032
  }
8997
9033
  function firstContentLine(lines, from, to, metaByLine) {
8998
9034
  for (let line = from; line <= to; line++) {
@@ -9085,6 +9121,14 @@ function extractKnowledgeTopics(text, filePath, headingDepth = 2) {
9085
9121
  const preambleEnd = firstBoundary - 1;
9086
9122
  const preamble = metadataFor(h1Line >= 0 ? h1Line : -1, preambleEnd);
9087
9123
  const preambleMetadata = preamble.metadata;
9124
+ if (preambleMetadata.import && h1Line < 0) {
9125
+ diagnostics.push({
9126
+ lineNumber: preamble.block?.startLine ?? 0,
9127
+ message: "An environment import must sit under a # title.",
9128
+ code: "knowledge-meta-import-placement"
9129
+ });
9130
+ delete preambleMetadata.import;
9131
+ }
9088
9132
  const preambleBody = bodyBetween(lines, 0, preambleEnd, removedLines);
9089
9133
  if (h1Text || preambleBody) {
9090
9134
  topics.push({
@@ -9108,6 +9152,17 @@ function extractKnowledgeTopics(text, filePath, headingDepth = 2) {
9108
9152
  const endLine = (boundaries[index + 1] ?? lines.length) - 1;
9109
9153
  const headingText = headingPattern.exec(lines[headingLine])?.[1].trim() ?? "";
9110
9154
  const { metadata, block } = metadataFor(headingLine, endLine);
9155
+ if (metadata.import) {
9156
+ diagnostics.push({
9157
+ lineNumber: block?.startLine ?? headingLine,
9158
+ message: "An environment import belongs under the # title, not a section.",
9159
+ code: "knowledge-meta-import-placement"
9160
+ });
9161
+ delete metadata.import;
9162
+ }
9163
+ if (preambleMetadata.import) {
9164
+ metadata.import = preambleMetadata.import;
9165
+ }
9111
9166
  const body = bodyBetween(lines, headingLine + 1, endLine, removedLines);
9112
9167
  let excluded = fileExcluded;
9113
9168
  let exclusionReason = fileExcluded ? "file marker <!-- norn:exclude -->" : void 0;
@@ -9160,7 +9215,7 @@ function extractKnowledgeTopics(text, filePath, headingDepth = 2) {
9160
9215
 
9161
9216
  // src/knowledge/knowledgeBuilder.ts
9162
9217
  var DEFAULT_EXTENSIONS = [".md"];
9163
- var KNOWLEDGE_MARKDOWN_ANALYZER_VERSION = 2;
9218
+ var KNOWLEDGE_MARKDOWN_ANALYZER_VERSION = 3;
9164
9219
  function normalizeRelative(filePath) {
9165
9220
  return filePath.split(path7.sep).join("/").replace(/^\.\//, "");
9166
9221
  }
@@ -10723,8 +10778,8 @@ function commitSnapshot(index, projectRoot, snapshotId, manifestJson, builtAt, d
10723
10778
  INSERT OR IGNORE INTO snapshot_occurrences(
10724
10779
  snapshot_id, declaration_id, declaration_path, declaration_alias, source_id, source_path,
10725
10780
  item_key, domain_path, heading_text, ordinal, topic_hash, authored_type, authored_use_when,
10726
- effective_type, start_line, end_line
10727
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
10781
+ environment_import, effective_type, start_line, end_line
10782
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
10728
10783
  `,
10729
10784
  snapshotId,
10730
10785
  occurrence.declarationId,
@@ -10739,6 +10794,7 @@ function commitSnapshot(index, projectRoot, snapshotId, manifestJson, builtAt, d
10739
10794
  occurrence.topicHash,
10740
10795
  occurrence.metadata.type?.value ?? null,
10741
10796
  occurrence.metadata.useWhen?.value ?? null,
10797
+ occurrence.metadata.import?.value ?? null,
10742
10798
  occurrence.effectiveType,
10743
10799
  occurrence.startLine,
10744
10800
  occurrence.endLine
@@ -10923,7 +10979,8 @@ function buildKnowledgeIndex(startPath, options = {}) {
10923
10979
  ordinal: occurrence.ordinal,
10924
10980
  topicHash: occurrence.topicHash,
10925
10981
  authoredType: occurrence.metadata.type?.value ?? null,
10926
- authoredUseWhen: occurrence.metadata.useWhen?.value ?? null
10982
+ authoredUseWhen: occurrence.metadata.useWhen?.value ?? null,
10983
+ authoredImport: occurrence.metadata.import?.value ?? null
10927
10984
  })),
10928
10985
  projectInputs: projectInputs.map((input) => ({ path: input.projectPath, contentHash: input.contentHash })).sort((left, right) => left.path.localeCompare(right.path)),
10929
10986
  analyzers: [
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "norn-cli",
3
3
  "displayName": "Norn",
4
4
  "description": "Build version-controlled agentic flows in VS Code and run them from the CLI or CI.",
5
- "version": "4.4.0",
5
+ "version": "4.5.1",
6
6
  "publisher": "Norn-PeterKrustanov",
7
7
  "author": {
8
8
  "name": "Peter Krastanov"
@@ -47,6 +47,7 @@
47
47
  "onLanguage:nornenv",
48
48
  "onLanguage:nornk8s",
49
49
  "onLanguage:nornagent",
50
+ "onLanguage:markdown",
50
51
  "workspaceContains:**/*.nornagent",
51
52
  "workspaceContains:**/*.nornai",
52
53
  "workspaceContains:**/norn.config.json",
@@ -638,7 +639,7 @@
638
639
  "test:regression": "node ./tests/test-scripts/run-regression.js",
639
640
  "test:prerelease": "npm test && npm run test:regression",
640
641
  "publish:npm": "node -e \"const fs=require('fs');const p=require('./package.json');p.name='norn-cli';fs.writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n')\" && npm publish; exit_code=$?; node -e \"const fs=require('fs');const p=require('./package.json');p.name='norn';fs.writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n')\"; exit $exit_code",
641
- "publish:vsce": "vsce publish",
642
+ "publish:vsce": "node ./scripts/publish-vsce.mjs",
642
643
  "publish:all": "npm run publish:npm && npm run publish:vsce"
643
644
  },
644
645
  "devDependencies": {