intentional-cognition-os 1.2.2 → 1.2.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.2.4] - 2026-05-22
4
+
5
+ - fix(compiler): analyzeQuestion strict-then-broad + possessive normalization (closes fmo) (#81) (50a0053)
6
+
7
+
8
+ ## [v1.2.3] - 2026-05-22
9
+
10
+ - fix(cli,plugin): ask --json + run.sh orchestrator + first real dog-food run (P1 bug filed) (#80) (0fb8b00)
11
+
12
+
3
13
  ## [v1.2.2] - 2026-05-21
4
14
 
5
15
  - docs(dogfood): author intent-eval-core-v1 question bank + session-1 journal (#79) (1a0cb0d)
package/README.md CHANGED
@@ -152,7 +152,7 @@ Global flags on every command: `--workspace <path>`, `--json`, `--verbose`, `--q
152
152
 
153
153
  ## Status
154
154
 
155
- **v1.0.5 — stable.** 1.2.2 tests passing across 5 packages. Used daily by the author. Public release on npm.
155
+ **v1.0.5 — stable.** 1.2.4 tests passing across 5 packages. Used daily by the author. Public release on npm.
156
156
 
157
157
  - **Stable**: all 14 commands, the compilation passes, ask + research + recall + render + promote, the audit chain.
158
158
  - **In progress**: post-v1 coverage uplift on compiler + cli packages; mutation-testing baseline.
package/dist/index.js CHANGED
@@ -8394,29 +8394,46 @@ var STOP_WORDS2 = /* @__PURE__ */ new Set([
8394
8394
  "give",
8395
8395
  "show"
8396
8396
  ]);
8397
+ function extractTokens(question) {
8398
+ const noPossessives = question.replace(/[‘’']s\b/g, "");
8399
+ const spaced = noPossessives.replace(/[^\w\s]/g, " ").toLowerCase();
8400
+ return spaced.split(/\s+/).filter((t) => t.length >= 2 && !STOP_WORDS2.has(t));
8401
+ }
8397
8402
  function buildFtsQuery(question) {
8398
- const cleaned = question.replace(/[-"*()^?!]/g, " ").toLowerCase();
8399
- const tokens = cleaned.split(/\s+/).map((t) => t.replace(/[^\w]/g, "")).filter((t) => t.length >= 2 && !STOP_WORDS2.has(t));
8403
+ const tokens = extractTokens(question);
8400
8404
  if (tokens.length === 0) {
8401
8405
  return null;
8402
8406
  }
8403
- return tokens.join(" ");
8407
+ const quoted = tokens.map((t) => `"${t}"`);
8408
+ return {
8409
+ strict: quoted.join(" "),
8410
+ // implicit AND
8411
+ broad: quoted.join(" OR ")
8412
+ };
8404
8413
  }
8405
8414
  function analyzeQuestion(db, _workspacePath, question) {
8406
8415
  const ftsQuery = buildFtsQuery(question);
8407
8416
  if (ftsQuery === null) {
8408
8417
  return err(new Error("Question contains no searchable terms after stop-word removal"));
8409
8418
  }
8410
- const searchResult = searchPages(db, ftsQuery, 10);
8411
- if (!searchResult.ok) {
8412
- return err(new Error(`Search failed: ${searchResult.error.message}`));
8419
+ const strictResult = searchPages(db, ftsQuery.strict, 10);
8420
+ if (!strictResult.ok) {
8421
+ return err(new Error(`Search failed: ${strictResult.error.message}`));
8422
+ }
8423
+ let relevantPages = strictResult.value;
8424
+ if (relevantPages.length === 0 && ftsQuery.strict !== ftsQuery.broad) {
8425
+ const broadResult = searchPages(db, ftsQuery.broad, 10);
8426
+ if (!broadResult.ok) {
8427
+ return err(new Error(`Search failed: ${broadResult.error.message}`));
8428
+ }
8429
+ relevantPages = broadResult.value;
8413
8430
  }
8414
8431
  const type = classifyQuestion(question);
8415
8432
  const suggestResearch = detectComplexity(question);
8416
8433
  return ok({
8417
8434
  originalQuestion: question,
8418
8435
  type,
8419
- relevantPages: searchResult.value,
8436
+ relevantPages,
8420
8437
  suggestResearch
8421
8438
  });
8422
8439
  }
@@ -10088,7 +10105,32 @@ function resolveWorkspace(options) {
10088
10105
  }
10089
10106
 
10090
10107
  // src/commands/ask.ts
10091
- function printNoKnowledgeFallback(question, workspacePath) {
10108
+ function printNoKnowledgeFallback(question, workspacePath, asJson = false) {
10109
+ if (asJson) {
10110
+ const rawPath2 = join13(workspacePath, "raw");
10111
+ process.stdout.write(
10112
+ JSON.stringify({
10113
+ question,
10114
+ answer: "",
10115
+ citations: [],
10116
+ question_type: null,
10117
+ retrieved_pages: [],
10118
+ tokens_in: 0,
10119
+ tokens_out: 0,
10120
+ tokens_total: 0,
10121
+ cost_usd: 0,
10122
+ model: null,
10123
+ latency_ms: 0,
10124
+ verified_citations: 0,
10125
+ unverified_citations: 0,
10126
+ provenance_chain: [],
10127
+ suggest_research: false,
10128
+ no_knowledge: true,
10129
+ has_uncompiled_sources: existsSync15(rawPath2)
10130
+ }) + "\n"
10131
+ );
10132
+ return;
10133
+ }
10092
10134
  process.stdout.write("\n");
10093
10135
  process.stdout.write(formatWarning(`No compiled knowledge found for: "${question}"`) + "\n");
10094
10136
  process.stdout.write("\n");
@@ -10165,7 +10207,7 @@ async function runAsk(question, askOptions, globalOpts) {
10165
10207
  }
10166
10208
  const analysis = analysisResult.value;
10167
10209
  if (analysis.relevantPages.length === 0) {
10168
- printNoKnowledgeFallback(question, wsPath);
10210
+ printNoKnowledgeFallback(question, wsPath, globalOpts.json === true);
10169
10211
  return;
10170
10212
  }
10171
10213
  const boostResult = findRelevantPages(db, question, analysis.type, 5);
@@ -10183,10 +10225,10 @@ async function runAsk(question, askOptions, globalOpts) {
10183
10225
  pagesWithContent.push({ path: page.path, title: page.title, content });
10184
10226
  }
10185
10227
  if (pagesWithContent.length === 0) {
10186
- printNoKnowledgeFallback(question, wsPath);
10228
+ printNoKnowledgeFallback(question, wsPath, globalOpts.json === true);
10187
10229
  return;
10188
10230
  }
10189
- process.stdout.write(dim("Generating answer...") + "\n");
10231
+ process.stderr.write(dim("Generating answer...") + "\n");
10190
10232
  const generateResult = await generateAnswer(client, question, pagesWithContent, {
10191
10233
  model,
10192
10234
  ...askOptions.maxTokens !== void 0 && { maxTokens: askOptions.maxTokens }
@@ -10220,6 +10262,37 @@ async function runAsk(question, askOptions, globalOpts) {
10220
10262
  verifiedCitations: verified.length,
10221
10263
  unverifiedCitations: unverified.length
10222
10264
  });
10265
+ if (globalOpts.json) {
10266
+ const totalTokens2 = inputTokens + outputTokens;
10267
+ const cost2 = calculateCost(inputTokens, outputTokens, model);
10268
+ const verifiedSet = new Set(verified.map((c) => c.pagePath));
10269
+ const payload = {
10270
+ question,
10271
+ answer,
10272
+ citations: citations.map((c) => ({
10273
+ source: `wiki/${c.pagePath}`,
10274
+ title: c.pageTitle,
10275
+ verified: verifiedSet.has(c.pagePath)
10276
+ })),
10277
+ question_type: analysis.type,
10278
+ retrieved_pages: topPages.map((p) => p.path),
10279
+ tokens_in: inputTokens,
10280
+ tokens_out: outputTokens,
10281
+ tokens_total: totalTokens2,
10282
+ cost_usd: Number(cost2.toFixed(4)),
10283
+ model,
10284
+ latency_ms: latencyMs,
10285
+ verified_citations: verified.length,
10286
+ unverified_citations: unverified.length,
10287
+ provenance_chain: provenanceChain.map((e) => ({
10288
+ level: e.level,
10289
+ path: "path" in e ? e.path : null
10290
+ })),
10291
+ suggest_research: analysis.suggestResearch
10292
+ };
10293
+ process.stdout.write(JSON.stringify(payload) + "\n");
10294
+ return;
10295
+ }
10223
10296
  process.stdout.write("\n");
10224
10297
  process.stdout.write(formatHeader("Answer") + "\n\n");
10225
10298
  const displayAnswer = answer.split("\n").map((line) => ` ${line}`).join("\n");