sensemaking 0.9.5 → 0.10.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.
Files changed (156) hide show
  1. package/README.md +24 -18
  2. package/dist/cjs/cli/check.js +7 -13
  3. package/dist/cjs/cli/check.js.map +1 -1
  4. package/dist/cjs/cli/download.d.cts +3 -0
  5. package/dist/cjs/cli/download.d.ts +3 -0
  6. package/dist/cjs/cli/download.js +214 -0
  7. package/dist/cjs/cli/download.js.map +1 -0
  8. package/dist/cjs/cli/index.d.cts +6 -3
  9. package/dist/cjs/cli/index.d.ts +6 -3
  10. package/dist/cjs/cli/index.js +23 -5
  11. package/dist/cjs/cli/index.js.map +1 -1
  12. package/dist/cjs/cli/init.js +4 -1
  13. package/dist/cjs/cli/init.js.map +1 -1
  14. package/dist/cjs/cli/map.js +2 -2
  15. package/dist/cjs/cli/map.js.map +1 -1
  16. package/dist/cjs/cli/named.js +10 -18
  17. package/dist/cjs/cli/named.js.map +1 -1
  18. package/dist/cjs/cli/path.d.cts +3 -0
  19. package/dist/cjs/cli/path.d.ts +3 -0
  20. package/dist/cjs/cli/path.js +161 -0
  21. package/dist/cjs/cli/path.js.map +1 -0
  22. package/dist/cjs/cli/peek.js +3 -2
  23. package/dist/cjs/cli/peek.js.map +1 -1
  24. package/dist/cjs/cli/related.d.cts +3 -0
  25. package/dist/cjs/cli/related.d.ts +3 -0
  26. package/dist/cjs/cli/related.js +279 -0
  27. package/dist/cjs/cli/related.js.map +1 -0
  28. package/dist/cjs/cli/search.js +3 -7
  29. package/dist/cjs/cli/search.js.map +1 -1
  30. package/dist/cjs/cli/shared.d.cts +3 -1
  31. package/dist/cjs/cli/shared.d.ts +3 -1
  32. package/dist/cjs/cli/shared.js +28 -5
  33. package/dist/cjs/cli/shared.js.map +1 -1
  34. package/dist/cjs/cli/sql.d.cts +3 -0
  35. package/dist/cjs/cli/sql.d.ts +3 -0
  36. package/dist/cjs/cli/{query.js → sql.js} +4 -4
  37. package/dist/cjs/cli/sql.js.map +1 -0
  38. package/dist/cjs/cli/status.js +9 -2
  39. package/dist/cjs/cli/status.js.map +1 -1
  40. package/dist/cjs/cli.js +14 -15
  41. package/dist/cjs/cli.js.map +1 -1
  42. package/dist/cjs/commands.d.cts +12 -4
  43. package/dist/cjs/commands.d.ts +12 -4
  44. package/dist/cjs/commands.js +138 -58
  45. package/dist/cjs/commands.js.map +1 -1
  46. package/dist/cjs/config.d.cts +6 -4
  47. package/dist/cjs/config.d.ts +6 -4
  48. package/dist/cjs/config.js +137 -58
  49. package/dist/cjs/config.js.map +1 -1
  50. package/dist/cjs/db.js +14 -34
  51. package/dist/cjs/db.js.map +1 -1
  52. package/dist/cjs/errors.d.cts +1 -1
  53. package/dist/cjs/errors.d.ts +1 -1
  54. package/dist/cjs/errors.js.map +1 -1
  55. package/dist/cjs/features/embed.d.cts +14 -0
  56. package/dist/cjs/features/embed.d.ts +14 -0
  57. package/dist/cjs/features/embed.js +248 -54
  58. package/dist/cjs/features/embed.js.map +1 -1
  59. package/dist/cjs/features/links.js +7 -16
  60. package/dist/cjs/features/links.js.map +1 -1
  61. package/dist/cjs/features/rank.js +2 -6
  62. package/dist/cjs/features/rank.js.map +1 -1
  63. package/dist/cjs/index.d.cts +1 -1
  64. package/dist/cjs/index.d.ts +1 -1
  65. package/dist/cjs/index.js.map +1 -1
  66. package/dist/cjs/output.js +11 -14
  67. package/dist/cjs/output.js.map +1 -1
  68. package/dist/cjs/progress.js +2 -4
  69. package/dist/cjs/progress.js.map +1 -1
  70. package/dist/cjs/scan.d.cts +1 -0
  71. package/dist/cjs/scan.d.ts +1 -0
  72. package/dist/cjs/scan.js +67 -32
  73. package/dist/cjs/scan.js.map +1 -1
  74. package/dist/cjs/search-error.js +4 -6
  75. package/dist/cjs/search-error.js.map +1 -1
  76. package/dist/cjs/traverse.d.cts +8 -0
  77. package/dist/cjs/traverse.d.ts +8 -0
  78. package/dist/cjs/traverse.js +97 -0
  79. package/dist/cjs/traverse.js.map +1 -0
  80. package/dist/esm/cli/check.js +7 -13
  81. package/dist/esm/cli/check.js.map +1 -1
  82. package/dist/esm/cli/download.d.ts +3 -0
  83. package/dist/esm/cli/download.js +27 -0
  84. package/dist/esm/cli/download.js.map +1 -0
  85. package/dist/esm/cli/index.d.ts +6 -3
  86. package/dist/esm/cli/index.js +13 -7
  87. package/dist/esm/cli/index.js.map +1 -1
  88. package/dist/esm/cli/init.js +4 -1
  89. package/dist/esm/cli/init.js.map +1 -1
  90. package/dist/esm/cli/map.js +3 -2
  91. package/dist/esm/cli/map.js.map +1 -1
  92. package/dist/esm/cli/named.js +10 -16
  93. package/dist/esm/cli/named.js.map +1 -1
  94. package/dist/esm/cli/path.d.ts +3 -0
  95. package/dist/esm/cli/path.js +51 -0
  96. package/dist/esm/cli/path.js.map +1 -0
  97. package/dist/esm/cli/peek.js +4 -2
  98. package/dist/esm/cli/peek.js.map +1 -1
  99. package/dist/esm/cli/related.d.ts +3 -0
  100. package/dist/esm/cli/related.js +26 -0
  101. package/dist/esm/cli/related.js.map +1 -0
  102. package/dist/esm/cli/search.js +2 -5
  103. package/dist/esm/cli/search.js.map +1 -1
  104. package/dist/esm/cli/shared.d.ts +3 -1
  105. package/dist/esm/cli/shared.js +28 -5
  106. package/dist/esm/cli/shared.js.map +1 -1
  107. package/dist/esm/cli/sql.d.ts +3 -0
  108. package/dist/esm/cli/{query.js → sql.js} +4 -4
  109. package/dist/esm/cli/sql.js.map +1 -0
  110. package/dist/esm/cli/status.js +8 -1
  111. package/dist/esm/cli/status.js.map +1 -1
  112. package/dist/esm/cli.js +13 -10
  113. package/dist/esm/cli.js.map +1 -1
  114. package/dist/esm/commands.d.ts +12 -4
  115. package/dist/esm/commands.js +111 -68
  116. package/dist/esm/commands.js.map +1 -1
  117. package/dist/esm/config.d.ts +6 -4
  118. package/dist/esm/config.js +126 -75
  119. package/dist/esm/config.js.map +1 -1
  120. package/dist/esm/db.js +16 -38
  121. package/dist/esm/db.js.map +1 -1
  122. package/dist/esm/errors.d.ts +1 -1
  123. package/dist/esm/errors.js.map +1 -1
  124. package/dist/esm/features/embed.d.ts +14 -0
  125. package/dist/esm/features/embed.js +110 -35
  126. package/dist/esm/features/embed.js.map +1 -1
  127. package/dist/esm/features/links.js +8 -17
  128. package/dist/esm/features/links.js.map +1 -1
  129. package/dist/esm/features/rank.js +2 -6
  130. package/dist/esm/features/rank.js.map +1 -1
  131. package/dist/esm/features/types.js.map +1 -1
  132. package/dist/esm/index.d.ts +1 -1
  133. package/dist/esm/index.js.map +1 -1
  134. package/dist/esm/output.js +13 -16
  135. package/dist/esm/output.js.map +1 -1
  136. package/dist/esm/progress.js +2 -4
  137. package/dist/esm/progress.js.map +1 -1
  138. package/dist/esm/scan.d.ts +1 -0
  139. package/dist/esm/scan.js +41 -34
  140. package/dist/esm/scan.js.map +1 -1
  141. package/dist/esm/search-error.js +4 -6
  142. package/dist/esm/search-error.js.map +1 -1
  143. package/dist/esm/traverse.d.ts +8 -0
  144. package/dist/esm/traverse.js +71 -0
  145. package/dist/esm/traverse.js.map +1 -0
  146. package/package.json +7 -3
  147. package/schema.json +12 -16
  148. package/skills/sense/EXAMPLES.md +8 -8
  149. package/skills/sense/SKILL.md +41 -19
  150. package/skills/sense-setup/EXAMPLES.md +24 -21
  151. package/skills/sense-setup/SKILL.md +9 -9
  152. package/dist/cjs/cli/query.d.cts +0 -3
  153. package/dist/cjs/cli/query.d.ts +0 -3
  154. package/dist/cjs/cli/query.js.map +0 -1
  155. package/dist/esm/cli/query.d.ts +0 -3
  156. package/dist/esm/cli/query.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { relatedNotes } from '../commands.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, parseK, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst RELATED_DEFAULT_K = 5;\n\nconst relatedCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.related}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...FORMAT, ...CONFIG, k: { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? RELATED_DEFAULT_K;\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, async (db, cfg) => {\n const overrides = scopeOf(values);\n printRows((await relatedNotes(db, cfg, pathArg, overrides, k)) as Row[], format);\n });\n};\nexport default relatedCmd;\n"],"names":["relatedNotes","printRows","USAGE","CONFIG","FORMAT","formatOf","parse","parseK","SCOPE","scopeOf","withDb","RELATED_DEFAULT_K","relatedCmd","ctx","usage","name","related","values","positionals","argv","k","type","pathArg","usageError","format","config","db","cfg","overrides"],"mappings":"AAAA,SAASA,YAAY,QAAQ,iBAAiB;AAE9C,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAG9F,MAAMC,oBAAoB;AAE1B,MAAMC,aAAsB,CAACC;QAKjBN;IAJV,MAAMO,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEb,MAAMc,OAAO,EAAE;IACnD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGZ,MAAMO,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGN,KAAK;QAAE,GAAGJ,MAAM;QAAE,GAAGD,MAAM;QAAEiB,GAAG;YAAEC,MAAM;QAAS;IAAE;IAC/G,MAAM,CAACC,QAAQ,GAAGJ;IAClB,IAAI,CAACI,SAAST,IAAIU,UAAU,CAACT;IAC7B,MAAMM,KAAIb,UAAAA,OAAOU,OAAOG,CAAC,EAAwBP,IAAIU,UAAU,eAArDhB,qBAAAA,UAA0DI;IACpE,MAAMa,SAASnB,SAASY;IACxB,OAAOP,OAAOG,KAAKI,OAAOQ,MAAM,EAAwB,OAAOC,IAAIC;QACjE,MAAMC,YAAYnB,QAAQQ;QAC1BhB,UAAW,MAAMD,aAAa0B,IAAIC,KAAKL,SAASM,WAAWR,IAAcI;IAC3E;AACF;AACA,eAAeZ,WAAW"}
@@ -1,7 +1,7 @@
1
1
  import { search } from '../commands.js';
2
2
  import { printRows } from '../output.js';
3
3
  import { USAGE } from './index.js';
4
- import { CONFIG, FORMAT, formatOf, parse, parseK, SEARCH_FLAGS, withDb } from './shared.js';
4
+ import { CONFIG, FORMAT, formatOf, parse, parseK, SEARCH_FLAGS, scopeOf, withDb } from './shared.js';
5
5
  const searchCmd = async (ctx)=>{
6
6
  const usage = `usage: ${ctx.name} ${USAGE.search}`;
7
7
  const { values, positionals } = parse(ctx.argv, usage, {
@@ -15,10 +15,7 @@ const searchCmd = async (ctx)=>{
15
15
  const format = formatOf(values);
16
16
  await withDb(ctx, values.config, async (db, cfg)=>printRows(await search(db, cfg, terms, {
17
17
  k,
18
- where: values.where,
19
- preset: values.preset,
20
- include: values.include,
21
- semantic: values.lexical ? false : undefined
18
+ ...scopeOf(values)
22
19
  }), format));
23
20
  };
24
21
  export default searchCmd;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, parseK, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.search}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const [terms] = positionals;\n if (!terms) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError);\n const format = formatOf(values);\n await withDb(ctx, values.config as string | undefined, async (db, cfg) => printRows(await search(db, cfg, terms, { k, where: values.where as string | undefined, preset: values.preset as string | undefined, include: values.include as string[] | undefined, semantic: values.lexical ? false : undefined }), format));\n};\nexport default searchCmd;\n"],"names":["search","printRows","USAGE","CONFIG","FORMAT","formatOf","parse","parseK","SEARCH_FLAGS","withDb","searchCmd","ctx","usage","name","values","positionals","argv","terms","usageError","k","format","config","db","cfg","where","preset","include","semantic","lexical","undefined"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,YAAY,EAAEC,MAAM,QAAQ,cAAc;AAG5F,MAAMC,YAAqB,OAAOC;IAChC,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEX,MAAMF,MAAM,EAAE;IAClD,MAAM,EAAEc,MAAM,EAAEC,WAAW,EAAE,GAAGT,MAAMK,IAAIK,IAAI,EAAEJ,OAAO;QAAE,GAAGJ,YAAY;QAAE,GAAGJ,MAAM;QAAE,GAAGD,MAAM;IAAC;IAC/F,MAAM,CAACc,MAAM,GAAGF;IAChB,IAAI,CAACE,OAAON,IAAIO,UAAU,CAACN;IAC3B,MAAMO,IAAIZ,OAAOO,OAAOK,CAAC,EAAwBR,IAAIO,UAAU;IAC/D,MAAME,SAASf,SAASS;IACxB,MAAML,OAAOE,KAAKG,OAAOO,MAAM,EAAwB,OAAOC,IAAIC,MAAQtB,UAAU,MAAMD,OAAOsB,IAAIC,KAAKN,OAAO;YAAEE;YAAGK,OAAOV,OAAOU,KAAK;YAAwBC,QAAQX,OAAOW,MAAM;YAAwBC,SAASZ,OAAOY,OAAO;YAA0BC,UAAUb,OAAOc,OAAO,GAAG,QAAQC;QAAU,IAAIT;AAClT;AACA,eAAeV,UAAU"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { search } from '../commands.ts';\nimport { printRows } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, parseK, SEARCH_FLAGS, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.search}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const [terms] = positionals;\n if (!terms) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError);\n const format = formatOf(values);\n await withDb(ctx, values.config as string | undefined, async (db, cfg) => printRows(await search(db, cfg, terms, { k, ...scopeOf(values) }), format));\n};\nexport default searchCmd;\n"],"names":["search","printRows","USAGE","CONFIG","FORMAT","formatOf","parse","parseK","SEARCH_FLAGS","scopeOf","withDb","searchCmd","ctx","usage","name","values","positionals","argv","terms","usageError","k","format","config","db","cfg"],"mappings":"AAAA,SAASA,MAAM,QAAQ,iBAAiB;AACxC,SAASC,SAAS,QAAQ,eAAe;AACzC,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,YAAY,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGrG,MAAMC,YAAqB,OAAOC;IAChC,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEZ,MAAMF,MAAM,EAAE;IAClD,MAAM,EAAEe,MAAM,EAAEC,WAAW,EAAE,GAAGV,MAAMM,IAAIK,IAAI,EAAEJ,OAAO;QAAE,GAAGL,YAAY;QAAE,GAAGJ,MAAM;QAAE,GAAGD,MAAM;IAAC;IAC/F,MAAM,CAACe,MAAM,GAAGF;IAChB,IAAI,CAACE,OAAON,IAAIO,UAAU,CAACN;IAC3B,MAAMO,IAAIb,OAAOQ,OAAOK,CAAC,EAAwBR,IAAIO,UAAU;IAC/D,MAAME,SAAShB,SAASU;IACxB,MAAML,OAAOE,KAAKG,OAAOO,MAAM,EAAwB,OAAOC,IAAIC,MAAQvB,UAAU,MAAMD,OAAOuB,IAAIC,KAAKN,OAAO;YAAEE;YAAG,GAAGX,QAAQM,OAAO;QAAC,IAAIM;AAC/I;AACA,eAAeV,UAAU"}
@@ -1,11 +1,13 @@
1
1
  import type { ParseArgsOptionsConfig } from 'node:util';
2
- import type { ResolvedConfig } from '../config.js';
2
+ import type { ResolvedConfig, SearchOverrides } from '../config.js';
3
3
  import type { OpenResult } from '../db.js';
4
4
  import type { Ctx } from './types.js';
5
5
  export declare const FORMAT: ParseArgsOptionsConfig;
6
6
  export declare const CONFIG: ParseArgsOptionsConfig;
7
+ export declare const SCOPE: ParseArgsOptionsConfig;
7
8
  export declare const SEARCH_FLAGS: ParseArgsOptionsConfig;
8
9
  type Values = Record<string, string | boolean | string[] | undefined>;
10
+ export declare function scopeOf(values: Values): SearchOverrides;
9
11
  export declare function formatOf(values: Values): 'table' | 'json';
10
12
  export declare function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): {
11
13
  values: Values;
@@ -14,13 +14,12 @@ export const CONFIG = {
14
14
  type: 'string'
15
15
  }
16
16
  };
17
- export const SEARCH_FLAGS = {
17
+ // The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude
18
+ // globs, a where SQL condition. search adds k on top.
19
+ export const SCOPE = {
18
20
  where: {
19
21
  type: 'string'
20
22
  },
21
- k: {
22
- type: 'string'
23
- },
24
23
  preset: {
25
24
  type: 'string'
26
25
  },
@@ -28,11 +27,35 @@ export const SEARCH_FLAGS = {
28
27
  type: 'string',
29
28
  multiple: true
30
29
  },
31
- lexical: {
30
+ exclude: {
31
+ type: 'string',
32
+ multiple: true
33
+ },
34
+ // Widening, which no other flag can express: --include and --exclude each override their
35
+ // own side of the preset, so neither can drop an exclusion the preset declares.
36
+ 'no-exclude': {
32
37
  type: 'boolean',
33
38
  default: false
34
39
  }
35
40
  };
41
+ export const SEARCH_FLAGS = {
42
+ ...SCOPE,
43
+ k: {
44
+ type: 'string'
45
+ }
46
+ };
47
+ // The SCOPE fragment's parsed values as the overrides every scoped command passes down. One
48
+ // place to read them, so a new scope field is added to the fragment and here, not in each
49
+ // command's call.
50
+ export function scopeOf(values) {
51
+ return {
52
+ preset: values.preset,
53
+ include: values.include,
54
+ exclude: values.exclude,
55
+ where: values.where,
56
+ noExclude: values['no-exclude'] === true
57
+ };
58
+ }
36
59
  export function formatOf(values) {
37
60
  return values.format === 'json' ? 'json' : 'table';
38
61
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig } from '../config.ts';\nimport type { OpenResult } from '../db.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { searchError } from '../search-error.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n k: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n lexical: { type: 'boolean', default: false },\n};\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return values.format === 'json' ? 'json' : 'table';\n}\n\n// Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(2);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as\n// \"nothing\", and parseInt would silently truncate \"5.9\" -- all three are caller mistakes\n// worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, configPath: string | undefined, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath);\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n try {\n await fn(db, cfg);\n } finally {\n db.close();\n }\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n let rows: Row[];\n try {\n rows = db.prepare(sql).all(...params) as Row[];\n } catch (err) {\n db.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5\n // punctuation trap applies -- the bound parameters are the search terms there. SQL\n // without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(err as Error, params.join(' '));\n throw err;\n }\n printRows(rows, format);\n db.close();\n}\n"],"names":["parseArgs","open","printRows","searchError","FORMAT","format","type","default","CONFIG","config","SEARCH_FLAGS","where","k","preset","include","multiple","lexical","formatOf","values","parse","argv","usage","options","positionals","args","help","short","strict","allowPositionals","err","console","error","message","process","exit","log","parseK","usageError","undefined","parsed","Number","isInteger","printWarnings","warnings","w","warn","withDb","ctx","configPath","fn","cfg","resolveConfig","db","close","runSql","sql","params","label","placeholderCount","match","length","rows","prepare","all","test","join"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig, SearchOverrides } from '../config.ts';\nimport type { OpenResult } from '../db.ts';\nimport { open } from '../db.ts';\nimport type { Row } from '../output.ts';\nimport { printRows } from '../output.ts';\nimport { searchError } from '../search-error.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\n// The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude\n// globs, a where SQL condition. search adds k on top.\nexport const SCOPE: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n // Widening, which no other flag can express: --include and --exclude each override their\n // own side of the preset, so neither can drop an exclusion the preset declares.\n 'no-exclude': { type: 'boolean', default: false },\n};\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = { ...SCOPE, k: { type: 'string' } };\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\n// The SCOPE fragment's parsed values as the overrides every scoped command passes down. One\n// place to read them, so a new scope field is added to the fragment and here, not in each\n// command's call.\nexport function scopeOf(values: Values): SearchOverrides {\n return {\n preset: values.preset as string | undefined,\n include: values.include as string[] | undefined,\n exclude: values.exclude as string[] | undefined,\n where: values.where as string | undefined,\n noExclude: values['no-exclude'] === true,\n };\n}\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return values.format === 'json' ? 'json' : 'table';\n}\n\n// Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(2);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as\n// \"nothing\", and parseInt would silently truncate \"5.9\" -- all three are caller mistakes\n// worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, configPath: string | undefined, fn: (db: OpenResult['db'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath);\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n try {\n await fn(db, cfg);\n } finally {\n db.close();\n }\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: 'table' | 'json', label: string): void {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n const { db, warnings } = open(cfg);\n printWarnings(warnings);\n let rows: Row[];\n try {\n rows = db.prepare(sql).all(...params) as Row[];\n } catch (err) {\n db.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5\n // punctuation trap applies -- the bound parameters are the search terms there. SQL\n // without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(err as Error, params.join(' '));\n throw err;\n }\n printRows(rows, format);\n db.close();\n}\n"],"names":["parseArgs","open","printRows","searchError","FORMAT","format","type","default","CONFIG","config","SCOPE","where","preset","include","multiple","exclude","SEARCH_FLAGS","k","scopeOf","values","noExclude","formatOf","parse","argv","usage","options","positionals","args","help","short","strict","allowPositionals","err","console","error","message","process","exit","log","parseK","usageError","undefined","parsed","Number","isInteger","printWarnings","warnings","w","warn","withDb","ctx","configPath","fn","cfg","resolveConfig","db","close","runSql","sql","params","label","placeholderCount","match","length","rows","prepare","all","test","join"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from './types.js';
2
+ declare const sqlCmd: Command;
3
+ export default sqlCmd;
@@ -1,7 +1,7 @@
1
1
  import { USAGE } from './index.js';
2
2
  import { CONFIG, FORMAT, formatOf, parse, runSql } from './shared.js';
3
- const query = (ctx)=>{
4
- const usage = `usage: ${ctx.name} ${USAGE.query}`;
3
+ const sqlCmd = (ctx)=>{
4
+ const usage = `usage: ${ctx.name} ${USAGE.sql}`;
5
5
  const { values, positionals } = parse(ctx.argv, usage, {
6
6
  ...FORMAT,
7
7
  ...CONFIG
@@ -9,6 +9,6 @@ const query = (ctx)=>{
9
9
  const [sql, ...params] = positionals;
10
10
  if (!sql) ctx.usageError(usage);
11
11
  const format = formatOf(values);
12
- runSql(ctx.resolveConfig(values.config), sql, params, format, 'ad-hoc query');
12
+ runSql(ctx.resolveConfig(values.config), sql, params, format, 'ad-hoc statement');
13
13
  };
14
- export default query;
14
+ export default sqlCmd;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/sql.ts"],"sourcesContent":["import { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, runSql } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst sqlCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.sql}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...FORMAT, ...CONFIG });\n const [sql, ...params] = positionals;\n if (!sql) ctx.usageError(usage);\n const format = formatOf(values);\n runSql(ctx.resolveConfig(values.config as string | undefined), sql, params, format, 'ad-hoc statement');\n};\nexport default sqlCmd;\n"],"names":["USAGE","CONFIG","FORMAT","formatOf","parse","runSql","sqlCmd","ctx","usage","name","sql","values","positionals","argv","params","usageError","format","resolveConfig","config"],"mappings":"AAAA,SAASA,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,QAAQ,cAAc;AAGtE,MAAMC,SAAkB,CAACC;IACvB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAET,MAAMU,GAAG,EAAE;IAC/C,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGR,MAAMG,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGN,MAAM;QAAE,GAAGD,MAAM;IAAC;IAC9E,MAAM,CAACS,KAAK,GAAGI,OAAO,GAAGF;IACzB,IAAI,CAACF,KAAKH,IAAIQ,UAAU,CAACP;IACzB,MAAMQ,SAASb,SAASQ;IACxBN,OAAOE,IAAIU,aAAa,CAACN,OAAOO,MAAM,GAAyBR,KAAKI,QAAQE,QAAQ;AACtF;AACA,eAAeV,OAAO"}
@@ -1,6 +1,7 @@
1
1
  import { presetCoverage } from '../commands.js';
2
2
  import { embedConfig, featureStates } from '../config.js';
3
3
  import { docCount, getMeta, open } from '../db.js';
4
+ import { isDownloadable, MODEL_FILENAMES, modelPresent } from '../features/embed.js';
4
5
  import { featuresLine, presetsLines } from '../output.js';
5
6
  import { USAGE } from './index.js';
6
7
  import { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.js';
@@ -26,6 +27,7 @@ const status = (ctx)=>{
26
27
  printWarnings(warnings);
27
28
  const features = featureStates(cfg);
28
29
  const e = embedConfig(cfg);
30
+ const hasModel = e ? modelPresent(cfg) : false;
29
31
  const vectors = e ? vectorState(db) : null;
30
32
  const presets = presetCoverage(db, cfg);
31
33
  const heartbeat = getMeta(db, 'watch_heartbeat');
@@ -41,6 +43,7 @@ const status = (ctx)=>{
41
43
  embed: e ? {
42
44
  type: e.type,
43
45
  model: e.model,
46
+ downloaded: hasModel,
44
47
  ...vectors !== null && vectors !== void 0 ? vectors : {}
45
48
  } : null,
46
49
  presets,
@@ -53,7 +56,11 @@ const status = (ctx)=>{
53
56
  console.log(`db: ${result.db}`);
54
57
  console.log(`docs: ${result.docs}`);
55
58
  console.log(featuresLine(features));
56
- if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on the first semantic search)` : ''}`);
59
+ // One authoritative line, off states included: an absent model reads as a degraded
60
+ // search, not as an empty corpus.
61
+ if (!e) console.log('embed: off (no preset asks for vectors)');
62
+ else if (!hasModel) console.log(`embed: ${e.type} ${e.model} — unavailable, so search runs on words and links only (${isDownloadable(e.model) ? `run \`${ctx.name} download\`` : `no ${MODEL_FILENAMES} in that directory`})`);
63
+ else console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on the first semantic search)` : ''}`);
57
64
  for (const line of presetsLines(presets))console.log(line);
58
65
  console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);
59
66
  console.log(`busy_timeout: ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { presetCoverage } from '../commands.ts';\nimport { embedConfig, featureStates } from '../config.ts';\nimport { docCount, getMeta, open } from '../db.ts';\nimport { featuresLine, presetsLines } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast `rebuild` on\n// such a tree otherwise reads as \"the feature isn't on\".\nfunction vectorState(db: ReturnType<typeof open>['db']): { embedded: number; pending: number } | null {\n try {\n const row = db.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings').get() as { embedded: number; pending: number };\n return row;\n } catch {\n return null;\n }\n}\n\nconst status: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { db, dbPath, warnings } = open(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const vectors = e ? vectorState(db) : null;\n const presets = presetCoverage(db, cfg);\n const heartbeat = getMeta(db, 'watch_heartbeat');\n // Derived at open() (F): 3x the largest reconcile this cache has ever held its write\n // transaction for, floored at 30s -- read back from the connection rather than\n // recomputed here, so this always reports what open() actually set.\n const busyTimeoutMs = (db.prepare('PRAGMA busy_timeout').get() as { timeout: number }).timeout;\n const result = {\n db: dbPath,\n docs: docCount(db),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { type: e.type, model: e.model, ...(vectors ?? {}) } : null,\n presets,\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\n };\n\n if (format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`db: ${result.db}`);\n console.log(`docs: ${result.docs}`);\n console.log(featuresLine(features));\n if (e) console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on the first semantic search)` : ''}`);\n for (const line of presetsLines(presets)) console.log(line);\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n console.log(`busy_timeout: ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n db.close();\n};\nexport default status;\n"],"names":["presetCoverage","embedConfig","featureStates","docCount","getMeta","open","featuresLine","presetsLines","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","vectorState","db","row","prepare","get","status","ctx","values","argv","name","format","cfg","resolveConfig","config","dbPath","warnings","features","e","vectors","presets","heartbeat","busyTimeoutMs","timeout","result","docs","on","featuresOff","off","embed","type","model","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","JSON","stringify","embedded","pending","line","close"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { presetCoverage } from '../commands.ts';\nimport { embedConfig, featureStates } from '../config.ts';\nimport { docCount, getMeta, open } from '../db.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelPresent } from '../features/embed.ts';\nimport { featuresLine, presetsLines } from '../output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast `rebuild` on\n// such a tree otherwise reads as \"the feature isn't on\".\nfunction vectorState(db: ReturnType<typeof open>['db']): { embedded: number; pending: number } | null {\n try {\n const row = db.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings').get() as { embedded: number; pending: number };\n return row;\n } catch {\n return null;\n }\n}\n\nconst status: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { db, dbPath, warnings } = open(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const vectors = e ? vectorState(db) : null;\n const presets = presetCoverage(db, cfg);\n const heartbeat = getMeta(db, 'watch_heartbeat');\n // Derived at open() (F): 3x the largest reconcile this cache has ever held its write\n // transaction for, floored at 30s -- read back from the connection rather than\n // recomputed here, so this always reports what open() actually set.\n const busyTimeoutMs = (db.prepare('PRAGMA busy_timeout').get() as { timeout: number }).timeout;\n const result = {\n db: dbPath,\n docs: docCount(db),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { type: e.type, model: e.model, downloaded: hasModel, ...(vectors ?? {}) } : null,\n presets,\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\n };\n\n if (format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`db: ${result.db}`);\n console.log(`docs: ${result.docs}`);\n console.log(featuresLine(features));\n // One authoritative line, off states included: an absent model reads as a degraded\n // search, not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else if (!hasModel) console.log(`embed: ${e.type} ${e.model} — unavailable, so search runs on words and links only (${isDownloadable(e.model) ? `run \\`${ctx.name} download\\`` : `no ${MODEL_FILENAMES} in that directory`})`);\n else console.log(`embed: ${e.type} ${e.model}${vectors ? ` (vectors: ${vectors.embedded} embedded, ${vectors.pending} pending — embedded on the first semantic search)` : ''}`);\n for (const line of presetsLines(presets)) console.log(line);\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: no watcher' : `watcher: last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n console.log(`busy_timeout: ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n db.close();\n};\nexport default status;\n"],"names":["presetCoverage","embedConfig","featureStates","docCount","getMeta","open","isDownloadable","MODEL_FILENAMES","modelPresent","featuresLine","presetsLines","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","vectorState","db","row","prepare","get","status","ctx","values","argv","name","format","cfg","resolveConfig","config","dbPath","warnings","features","e","hasModel","vectors","presets","heartbeat","busyTimeoutMs","timeout","result","docs","on","featuresOff","off","embed","type","model","downloaded","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","JSON","stringify","embedded","pending","line","close"],"mappings":"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"}
package/dist/esm/cli.js CHANGED
@@ -2,10 +2,8 @@ import { createRequire } from 'node:module';
2
2
  import { parseArgs } from 'node:util';
3
3
  import { COMMANDS, USAGE } from './cli/index.js';
4
4
  import { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.js';
5
- // Parsing and dispatch only. Commands live in src/cli/, one file each, lazy-loaded --
6
- // nothing tree- or dependency-heavy may be imported at the top of this file. Flags parse
7
- // per command (each command's own parse() call); this file only handles the bare top-level
8
- // flags (--version/--help/--list/--config) and dispatch.
5
+ // Parsing and dispatch only; commands lazy-load from src/cli/, so nothing heavy is imported
6
+ // here. Flags parse per command -- this file handles only --version/--help/--list/--config.
9
7
  // Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.
10
8
  function packageVersion() {
11
9
  const load = createRequire(import.meta.url);
@@ -87,9 +85,9 @@ export default async function cli(argv, name) {
87
85
  if (values.list) {
88
86
  const queries = resolveConfigFor(name, values.config).queries;
89
87
  for (const queryName of Object.keys(queries).sort()){
90
- const entry = queries[queryName];
91
- const isSavedSearch = typeof entry === 'object' && entry !== null && 'search' in entry;
92
- console.log(isSavedSearch ? `${queryName} (search)` : queryName);
88
+ // Every entry names its verb, so --list can label both kinds rather than only
89
+ // marking the exception.
90
+ console.log(`${queryName} (${'search' in queries[queryName] ? 'search' : 'sql'})`);
93
91
  }
94
92
  return;
95
93
  }
@@ -100,9 +98,14 @@ export default async function cli(argv, name) {
100
98
  console.error(usage(name));
101
99
  process.exit(2);
102
100
  }
103
- // find -> search (breaking rename): one release of a pointer instead of "unknown query".
104
- if (first === 'find') {
105
- console.error(`${name}: find is now search`);
101
+ // Breaking renames get one release of a pointer instead of an "unknown" error: find ->
102
+ // search, and query -> sql (which took its name back from the search sense of "query").
103
+ const RENAMED = {
104
+ find: 'search',
105
+ query: 'sql'
106
+ };
107
+ if (RENAMED[first]) {
108
+ console.error(`${name}: ${first} is now ${RENAMED[first]}`);
106
109
  console.error(usage(name));
107
110
  process.exit(2);
108
111
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { COMMANDS, USAGE } from './cli/index.ts';\nimport type { Ctx } from './cli/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only. Commands live in src/cli/, one file each, lazy-loaded --\n// nothing tree- or dependency-heavy may be imported at the top of this file. Flags parse\n// per command (each command's own parse() call); this file only handles the bare top-level\n// flags (--version/--help/--list/--config) and dispatch.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n const lines = Object.values(USAGE).map((u) => ` ${name} ${u}`);\n return [`usage: ${name} <name> [params...] [--format table|json] [--config path]`, ...lines, ` ${name} --list`, ` ${name} --version`].join('\\n');\n}\n\nfunction resolveConfigFor(name: string, configPath: string | undefined) {\n const cfg = loadConfig(configPath);\n if (cfg.migratedFrom !== undefined) {\n console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);\n }\n if (cfg.unknownKeys !== undefined) {\n console.warn(`${name}: ${cfg.configPath} sets ${cfg.unknownKeys.join(', ')}, which this build does not read (no effect); see schema.json for the keys it does`);\n }\n return cfg;\n}\n\n// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n const first = argv[0];\n\n // No command word, or the first token looks like a flag: the only flags this level knows.\n if (!first || first.startsWith('-')) {\n let values: Record<string, string | boolean | undefined>;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n list: { type: 'boolean', default: false },\n config: { type: 'string' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(2);\n }\n\n try {\n if (values.version) {\n console.log(packageVersion());\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n if (values.list) {\n const queries = resolveConfigFor(name, values.config as string | undefined).queries;\n for (const queryName of Object.keys(queries).sort()) {\n const entry = queries[queryName];\n const isSavedSearch = typeof entry === 'object' && entry !== null && 'search' in entry;\n console.log(isSavedSearch ? `${queryName} (search)` : queryName);\n }\n return;\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n\n console.error(usage(name));\n process.exit(2);\n }\n\n // find -> search (breaking rename): one release of a pointer instead of \"unknown query\".\n if (first === 'find') {\n console.error(`${name}: find is now search`);\n console.error(usage(name));\n process.exit(2);\n }\n\n const ctx: Ctx = {\n name,\n argv: argv.slice(1),\n resolveConfig: (configPath) => resolveConfigFor(name, configPath),\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else await (await import('./cli/named.ts')).default(ctx, first);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["createRequire","parseArgs","COMMANDS","USAGE","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","lines","Object","values","map","u","join","resolveConfigFor","configPath","cfg","migratedFrom","undefined","console","warn","unknownKeys","cli","argv","first","startsWith","args","options","type","default","short","help","list","config","allowPositionals","err","error","message","process","exit","log","queries","queryName","keys","sort","entry","isSavedSearch","ctx","slice","resolveConfig","usageError"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { parseArgs } from 'node:util';\nimport { COMMANDS, USAGE } from './cli/index.ts';\nimport type { Ctx } from './cli/types.ts';\nimport { loadConfig, SUPPORTED_CONFIG_VERSION } from './config.ts';\n\n// Parsing and dispatch only; commands lazy-load from src/cli/, so nothing heavy is imported\n// here. Flags parse per command -- this file handles only --version/--help/--list/--config.\n\n// Works from dist/cjs and dist/esm alike: walk up past the dist type-marker package.json.\nfunction packageVersion(): string {\n const load = createRequire(import.meta.url);\n for (const rel of ['../package.json', '../../package.json', '../../../package.json']) {\n try {\n const pkg = load(rel) as { name?: string; version?: string };\n if (pkg.name === 'sensemaking' && pkg.version) return pkg.version;\n } catch {}\n }\n return 'unknown';\n}\n\nfunction usage(name: string): string {\n const lines = Object.values(USAGE).map((u) => ` ${name} ${u}`);\n return [`usage: ${name} <name> [params...] [--format table|json] [--config path]`, ...lines, ` ${name} --list`, ` ${name} --version`].join('\\n');\n}\n\nfunction resolveConfigFor(name: string, configPath: string | undefined) {\n const cfg = loadConfig(configPath);\n if (cfg.migratedFrom !== undefined) {\n console.warn(`${name}: migrated ${cfg.configPath} from config version ${cfg.migratedFrom} to ${SUPPORTED_CONFIG_VERSION}`);\n }\n if (cfg.unknownKeys !== undefined) {\n console.warn(`${name}: ${cfg.configPath} sets ${cfg.unknownKeys.join(', ')}, which this build does not read (no effect); see schema.json for the keys it does`);\n }\n return cfg;\n}\n\n// Thrown errors -> exit 1 with the message verbatim; usage errors exit 2 directly.\nexport default async function cli(argv: string[], name: string): Promise<void> {\n const first = argv[0];\n\n // No command word, or the first token looks like a flag: the only flags this level knows.\n if (!first || first.startsWith('-')) {\n let values: Record<string, string | boolean | undefined>;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n version: { type: 'boolean', default: false, short: 'v' },\n help: { type: 'boolean', default: false, short: 'h' },\n list: { type: 'boolean', default: false },\n config: { type: 'string' },\n },\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage(name));\n process.exit(2);\n }\n\n try {\n if (values.version) {\n console.log(packageVersion());\n return;\n }\n if (values.help) {\n console.log(usage(name));\n return;\n }\n if (values.list) {\n const queries = resolveConfigFor(name, values.config as string | undefined).queries;\n for (const queryName of Object.keys(queries).sort()) {\n // Every entry names its verb, so --list can label both kinds rather than only\n // marking the exception.\n console.log(`${queryName} (${'search' in queries[queryName] ? 'search' : 'sql'})`);\n }\n return;\n }\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n\n console.error(usage(name));\n process.exit(2);\n }\n\n // Breaking renames get one release of a pointer instead of an \"unknown\" error: find ->\n // search, and query -> sql (which took its name back from the search sense of \"query\").\n const RENAMED: Record<string, string> = { find: 'search', query: 'sql' };\n if (RENAMED[first]) {\n console.error(`${name}: ${first} is now ${RENAMED[first]}`);\n console.error(usage(name));\n process.exit(2);\n }\n\n const ctx: Ctx = {\n name,\n argv: argv.slice(1),\n resolveConfig: (configPath) => resolveConfigFor(name, configPath),\n usageError(message) {\n console.error(message);\n process.exit(2);\n },\n };\n\n try {\n const load = COMMANDS[first];\n if (load) await (await load()).default(ctx);\n else await (await import('./cli/named.ts')).default(ctx, first);\n } catch (err) {\n console.error((err as Error).message);\n process.exit(1);\n }\n}\n"],"names":["createRequire","parseArgs","COMMANDS","USAGE","loadConfig","SUPPORTED_CONFIG_VERSION","packageVersion","load","url","rel","pkg","name","version","usage","lines","Object","values","map","u","join","resolveConfigFor","configPath","cfg","migratedFrom","undefined","console","warn","unknownKeys","cli","argv","first","startsWith","args","options","type","default","short","help","list","config","allowPositionals","err","error","message","process","exit","log","queries","queryName","keys","sort","RENAMED","find","query","ctx","slice","resolveConfig","usageError"],"mappings":"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"}
@@ -1,14 +1,17 @@
1
1
  import type { DatabaseSync } from 'node:sqlite';
2
- import type { FeatureName, ResolvedConfig } from './config.js';
2
+ import type { FeatureName, ResolvedConfig, SearchOverrides } from './config.js';
3
3
  import type { Row } from './output.js';
4
4
  export interface SearchOptions {
5
5
  k?: number;
6
6
  where?: string;
7
7
  preset?: string;
8
8
  include?: string[];
9
- semantic?: boolean;
9
+ exclude?: string[];
10
+ noExclude?: boolean;
11
+ probe?: boolean;
10
12
  }
11
13
  export declare function search(db: DatabaseSync, cfg: ResolvedConfig, terms: string, opts?: SearchOptions): Promise<Row[]>;
14
+ export declare function scopedPaths(db: DatabaseSync, cfg: ResolvedConfig, overrides: SearchOverrides): Set<string>;
12
15
  export interface PresetCoverage {
13
16
  name: string;
14
17
  files: number;
@@ -30,7 +33,8 @@ export interface TreeMap {
30
33
  hubs: Row[];
31
34
  recent: Row[];
32
35
  }
33
- export declare function mapTree(db: DatabaseSync, cfg: ResolvedConfig): TreeMap;
36
+ export declare function mapTree(db: DatabaseSync, cfg: ResolvedConfig, overrides?: SearchOverrides): TreeMap;
37
+ export declare function resolveNote(paths: string[], arg: string): string;
34
38
  export interface Peek {
35
39
  path: string;
36
40
  tokens: number;
@@ -45,4 +49,8 @@ export interface Peek {
45
49
  unresolvedTotal: number;
46
50
  off: FeatureName[];
47
51
  }
48
- export declare function peek(db: DatabaseSync, cfg: ResolvedConfig, pathArg: string): Peek;
52
+ export declare function peek(db: DatabaseSync, cfg: ResolvedConfig, pathArg: string, overrides?: SearchOverrides): Peek;
53
+ export declare function relatedNotes(db: DatabaseSync, cfg: ResolvedConfig, pathArg: string, overrides: SearchOverrides, k: number): Promise<Array<{
54
+ path: string;
55
+ similarity: number;
56
+ }>>;