snipara-companion 3.2.6 → 3.2.7

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 CHANGED
@@ -133,9 +133,10 @@ verification hints.
133
133
  Session Snapshot V0 includes latest activity, risk reasons, touched files, a
134
134
  next action, and advisory Intent Detection V0. Intent Detection V0 reports the
135
135
  inferred intent, confidence, reason-code signals, local evidence counts, and a
136
- suggested workflow mode hint for the human or agent to consider. It is
137
- observational and keeps `hardRoutingAllowed=false` until explicit routing policy
138
- and receipts exist.
136
+ suggested workflow mode. `workflow run --mode auto` uses that same Control Plane
137
+ principle to choose lite, standard, full, or orchestrate. Lite runs with zero
138
+ mandatory hosted context calls; recall/context/code-impact are on-demand
139
+ escalations, not an entry toll.
139
140
  `workflow timeline --export md` prints a compact redacted Markdown timeline for
140
141
  handoff or publication.
141
142
 
package/dist/index.js CHANGED
@@ -18886,11 +18886,23 @@ function resolveAutoWorkflowMode(query) {
18886
18886
  )) {
18887
18887
  return "full";
18888
18888
  }
18889
+ if (/\b(why|pourquoi|decision|décision|rationale|positioning|positionnement|strategy|stratégie|cross-session|previous decision|prior decision|historical context)\b/.test(
18890
+ normalized
18891
+ )) {
18892
+ return "standard";
18893
+ }
18889
18894
  if (/\b(status|show|list|read|lookup|recall|brief|summarize|summary|what changed|question|docs?|documentation)\b/.test(
18890
18895
  normalized
18891
18896
  ) && !/\b(implement|change|fix|ship|code|refactor|test|write|create|build)\b/.test(normalized)) {
18892
18897
  return "lite";
18893
18898
  }
18899
+ if (/\b(typo|copy edit|small diff|tiny diff|one-line|one line|known file|obvious fix|quick fix|format|formatting|rename)\b/.test(
18900
+ normalized
18901
+ ) && !/\b(architecture|release|deploy|migration|schema|auth|billing|security|multi-file|many files|5\+ files|cross-session|decision|décision)\b/.test(
18902
+ normalized
18903
+ )) {
18904
+ return "lite";
18905
+ }
18894
18906
  return "standard";
18895
18907
  }
18896
18908
  function effectiveWorkflowMode(mode, query = "") {
@@ -18939,14 +18951,15 @@ function safeDecisionPendingCount() {
18939
18951
  function printManagedWorkflowDiscipline() {
18940
18952
  console.log(import_chalk6.default.bold("Coding workflow mode"));
18941
18953
  console.log(
18942
- "- LITE: small single-phase edits still start with Snipara recall/context and end with local verification."
18954
+ "- LITE: small single-phase edits have no mandatory Snipara calls; use local verification and escalate on demand."
18943
18955
  );
18944
18956
  console.log(
18945
- "- STANDARD: normal coding work uses context plus recommended code-graph follow-up; --mode auto deterministically selects lite/standard/full/orchestrate from task intent."
18957
+ "- STANDARD: normal coding work uses context or code graph when the task needs source truth or prior rationale."
18946
18958
  );
18947
18959
  console.log(
18948
18960
  "- FULL: use this managed workflow with phases/chunks for multi-file, risky, release/deploy, architectural, or compaction-prone coding work."
18949
18961
  );
18962
+ console.log("- --mode auto routes by task intent; a nudge is advisory, not a gate.");
18950
18963
  console.log(
18951
18964
  "- FULL + ORCHESTRATED: use explicit snipara-orchestrator handoff only for production gates, drift checks, htasks, or multi-agent coordination."
18952
18965
  );
@@ -20026,6 +20039,17 @@ function printRuntimeHint(query, mode) {
20026
20039
  console.log("Fresh setup: npx create-snipara --profile full-stack --advanced");
20027
20040
  console.log("Manual install: pip install 'snipara-sandbox[all]'");
20028
20041
  }
20042
+ function printLiteWorkflowRun(query, requestedMode) {
20043
+ console.log(import_chalk6.default.bold("Workflow Lite"));
20044
+ printKeyValue2("Requested mode:", requestedMode);
20045
+ printKeyValue2("Effective mode:", "lite");
20046
+ printKeyValue2("Task:", query);
20047
+ console.log("No Snipara recall, context query, or bootstrap call was run.");
20048
+ console.log(
20049
+ "Escalate with recall, context_query, code impact, or task-commit only when the task creates that need."
20050
+ );
20051
+ console.log("");
20052
+ }
20029
20053
  function runtimeHintVersionLabel(report) {
20030
20054
  if (!report.runtime.cliVersion) {
20031
20055
  return report.runtime.version ? ` (${report.runtime.version})` : "";
@@ -20722,37 +20746,29 @@ function printChunkResult(chunkId, result) {
20722
20746
  function readSessionEntryPreview(entry) {
20723
20747
  return toPreview(entry.text ?? entry.content ?? entry.summary ?? entry.title, 220);
20724
20748
  }
20725
- function printSessionTier(label, tier) {
20726
- if (tier.memories.length === 0) {
20727
- return;
20728
- }
20729
- console.log(import_chalk6.default.bold(label));
20730
- for (const entry of tier.memories.slice(0, 5)) {
20731
- console.log(`- ${readSessionEntryPreview(entry)}`);
20732
- }
20733
- console.log("");
20749
+ function compactSessionEntryLine(entry) {
20750
+ const label = typeof entry.type === "string" && entry.type.trim().length > 0 ? entry.type.trim() : typeof entry.category === "string" && entry.category.trim().length > 0 ? entry.category.trim() : "memory";
20751
+ return `- ${label}: ${readSessionEntryPreview(entry)}`;
20734
20752
  }
20735
20753
  function printSessionBootstrap(result, options) {
20736
20754
  const normalized = normalizeSessionMemoriesResult(result);
20737
- printKeyValue2("Durable memory:", normalized.critical.count);
20738
- printKeyValue2(
20739
- "Session context:",
20740
- options.includeSessionContext ? normalized.daily.count : "skipped by default (use --include-session-context)"
20741
- );
20742
- if (typeof normalized.total_tokens === "number") {
20743
- printKeyValue2("Tokens:", normalized.total_tokens);
20744
- }
20745
- if (typeof normalized.message === "string" && normalized.message.length > 0) {
20746
- printKeyValue2("Message:", normalized.message);
20755
+ const entries = [
20756
+ ...normalized.critical.memories,
20757
+ ...options.includeSessionContext ? normalized.daily.memories : []
20758
+ ].slice(0, 5);
20759
+ if (entries.length === 0) {
20760
+ return false;
20747
20761
  }
20748
- console.log("");
20749
- printSessionTier("Durable Memory", normalized.critical);
20750
- if (options.includeSessionContext) {
20751
- printSessionTier("Session Context (weak carryover)", normalized.daily);
20762
+ console.log(import_chalk6.default.bold("Snipara Bootstrap Brief"));
20763
+ for (const entry of entries) {
20764
+ console.log(compactSessionEntryLine(entry));
20752
20765
  }
20753
- if (normalized.critical.count === 0 && normalized.daily.count === 0) {
20754
- printJson2(normalized);
20766
+ const hiddenCount = normalized.critical.count + (options.includeSessionContext ? normalized.daily.count : 0) - entries.length;
20767
+ if (hiddenCount > 0) {
20768
+ console.log(`- ${hiddenCount} more available on demand via recall/session-bootstrap --json.`);
20755
20769
  }
20770
+ console.log("");
20771
+ return true;
20756
20772
  }
20757
20773
  function printSessionBootstrapQuality(report) {
20758
20774
  if (report.warnings.length === 0) {
@@ -22039,10 +22055,11 @@ async function sharedContextCommand(options) {
22039
22055
  }
22040
22056
  async function workflowRunCommand(options) {
22041
22057
  const hostedConfigured = isConfigured();
22058
+ const effectiveMode = effectiveWorkflowMode(options.mode, options.query);
22042
22059
  const localAdaptiveRoutingPolicy = readLocalAdaptiveRoutingProjectPolicy();
22043
22060
  const localAdaptiveRoutingRequested = shouldBuildAdaptiveRouting(options);
22044
- const canRunLocalAdaptiveRouting = !hostedConfigured && options.mode !== "orchestrate" && (localAdaptiveRoutingRequested || localAdaptiveRoutingPolicy !== null && localAdaptiveRoutingPolicy.mode !== "off");
22045
- if (!hostedConfigured && !canRunLocalAdaptiveRouting) {
22061
+ const canRunLocalAdaptiveRouting = !hostedConfigured && effectiveMode !== "orchestrate" && (localAdaptiveRoutingRequested || localAdaptiveRoutingPolicy !== null && localAdaptiveRoutingPolicy.mode !== "off");
22062
+ if (!hostedConfigured && !canRunLocalAdaptiveRouting && effectiveMode !== "lite") {
22046
22063
  ensureConfigured();
22047
22064
  }
22048
22065
  const client = hostedConfigured ? createClient(2e4) : null;
@@ -22068,7 +22085,6 @@ async function workflowRunCommand(options) {
22068
22085
  routingOptions,
22069
22086
  adaptiveRoutingWithCatalog
22070
22087
  ) ? enrichAdaptiveRoutingWithLocalOrchestrator(adaptiveRoutingWithCatalog, routingOptions) : adaptiveRoutingWithCatalog;
22071
- const effectiveMode = effectiveWorkflowMode(options.mode, options.query);
22072
22088
  const orchestratorRecommendation = getOrchestratorRecommendation(options.query, effectiveMode, {
22073
22089
  policyAutoRoute: options.autoRouteOrchestrator,
22074
22090
  policySource: options.orchestratorPolicySource,
@@ -22090,11 +22106,16 @@ async function workflowRunCommand(options) {
22090
22106
  effective_mode: effectiveMode,
22091
22107
  local_only: true,
22092
22108
  local_policy_path: localAdaptiveRoutingPolicy ? ADAPTIVE_ROUTING_POLICY_RELATIVE_PATH2 : null,
22109
+ retrieval_policy: effectiveMode === "lite" ? {
22110
+ mandatory_calls: [],
22111
+ escalation: "Run recall, context_query, or code impact only when the task needs them.",
22112
+ persistence: "Use task-commit only when reusable durable knowledge was learned."
22113
+ } : void 0,
22093
22114
  orchestrator_recommendation: orchestratorRecommendation,
22094
22115
  orchestrator_handoff: preparedHandoff,
22095
22116
  adaptive_routing: adaptiveRouting,
22096
22117
  local_worker: localWorkerRoutingDefaults?.worker,
22097
- warnings: [
22118
+ warnings: effectiveMode === "lite" ? [] : [
22098
22119
  "Hosted Snipara is not configured; workflow run is limited to local Adaptive Work Routing metadata."
22099
22120
  ]
22100
22121
  };
@@ -22102,10 +22123,44 @@ async function workflowRunCommand(options) {
22102
22123
  printJson2(payload2);
22103
22124
  return;
22104
22125
  }
22105
- console.log(import_chalk6.default.bold("Local Adaptive Work Routing"));
22106
- console.log(
22107
- "Hosted Snipara is not configured; no context query, hosted catalog, or planner call ran."
22108
- );
22126
+ if (effectiveMode === "lite") {
22127
+ printLiteWorkflowRun(options.query, options.mode);
22128
+ } else {
22129
+ console.log(import_chalk6.default.bold("Local Adaptive Work Routing"));
22130
+ console.log(
22131
+ "Hosted Snipara is not configured; no context query, hosted catalog, or planner call ran."
22132
+ );
22133
+ }
22134
+ if (adaptiveRouting) {
22135
+ printAdaptiveRoutingRecommendation(adaptiveRouting);
22136
+ }
22137
+ if (preparedHandoff) {
22138
+ printPreparedOrchestratorHandoff2(preparedHandoff);
22139
+ }
22140
+ return;
22141
+ }
22142
+ if (effectiveMode === "lite") {
22143
+ const payload2 = {
22144
+ mode: options.mode,
22145
+ effective_mode: effectiveMode,
22146
+ retrieval_policy: {
22147
+ mandatory_calls: [],
22148
+ escalation: "Run recall, context_query, or code impact only when the task needs them.",
22149
+ persistence: "Use task-commit only when reusable durable knowledge was learned."
22150
+ },
22151
+ orchestrator_recommendation: orchestratorRecommendation,
22152
+ orchestrator_handoff: preparedHandoff,
22153
+ adaptive_routing: adaptiveRouting,
22154
+ local_worker: localWorkerRoutingDefaults?.worker
22155
+ };
22156
+ if (options.json) {
22157
+ printJson2(payload2);
22158
+ return;
22159
+ }
22160
+ printLiteWorkflowRun(options.query, options.mode);
22161
+ if (options.runtimeHint !== false) {
22162
+ printRuntimeHint(options.query, effectiveMode);
22163
+ }
22109
22164
  if (adaptiveRouting) {
22110
22165
  printAdaptiveRoutingRecommendation(adaptiveRouting);
22111
22166
  }
@@ -22231,11 +22286,13 @@ async function workflowRunCommand(options) {
22231
22286
  return;
22232
22287
  }
22233
22288
  if (effectiveMode === "full" && payload.session_bootstrap) {
22234
- console.log(import_chalk6.default.bold("Workflow Bootstrap"));
22235
- printSessionBootstrap(payload.session_bootstrap, {
22236
- includeSessionContext: Boolean(workflowBudget?.include_session_context)
22237
- });
22238
- if (payload.session_bootstrap_quality && typeof payload.session_bootstrap_quality === "object") {
22289
+ const printedBootstrap = printSessionBootstrap(
22290
+ payload.session_bootstrap,
22291
+ {
22292
+ includeSessionContext: Boolean(workflowBudget?.include_session_context)
22293
+ }
22294
+ );
22295
+ if (printedBootstrap && payload.session_bootstrap_quality && typeof payload.session_bootstrap_quality === "object") {
22239
22296
  printSessionBootstrapQuality(
22240
22297
  payload.session_bootstrap_quality
22241
22298
  );
@@ -23181,10 +23238,12 @@ async function workflowResumeCommand(options) {
23181
23238
  }
23182
23239
  console.log(import_chalk6.default.bold("Workflow Resume"));
23183
23240
  printManagedWorkflowState(state);
23184
- printSessionBootstrap(bootstrap, {
23241
+ const printedBootstrap = printSessionBootstrap(bootstrap, {
23185
23242
  includeSessionContext: resolvedContextTokens > 0
23186
23243
  });
23187
- printSessionBootstrapQuality(bootstrapQuality);
23244
+ if (printedBootstrap) {
23245
+ printSessionBootstrapQuality(bootstrapQuality);
23246
+ }
23188
23247
  printWorkflowLocalSessionSnapshot(localSessionSnapshot);
23189
23248
  printWorkflowTeamSyncResume(teamSyncResume);
23190
23249
  printWorkflowRuntimeResumePlan(runtimeResume);
@@ -23706,11 +23765,13 @@ async function sessionBootstrapCommand(options) {
23706
23765
  });
23707
23766
  return;
23708
23767
  }
23709
- printSessionBootstrap(result, {
23768
+ const printedBootstrap = printSessionBootstrap(result, {
23710
23769
  includeSessionContext: resolvedContextTokens > 0
23711
23770
  });
23712
- printSessionBootstrapQuality(bootstrapQuality);
23713
- if (warmSnapshot.storedEntries > 0) {
23771
+ if (printedBootstrap) {
23772
+ printSessionBootstrapQuality(bootstrapQuality);
23773
+ }
23774
+ if (printedBootstrap && warmSnapshot.storedEntries > 0) {
23714
23775
  printKeyValue2(
23715
23776
  "Warm cache:",
23716
23777
  `${warmSnapshot.storedEntries} bootstrap memory/context entries primed locally`
@@ -930,7 +930,9 @@ without an extra LLM provider key because your AI client supplies the reasoning;
930
930
  runtime-bound phases it also restores the recorded Sandbox binding and prints a reattach or
931
931
  rehydrate plan. It does not snapshot or exactly restore a live Snipara Sandbox or REPL process.
932
932
  Short-lived session context is skipped unless you pass `--include-session-context`
933
- or an explicit `--max-context-tokens`; durable memory still loads by default.
933
+ or an explicit `--max-context-tokens`. Text output is a compact bootstrap brief
934
+ and is silent when no high-signal item is available; use `--json` for the full
935
+ payload.
934
936
  `workflow run --mode full --json` also reports `workflow_budget`,
935
937
  `session_bootstrap_quality`, and `plan_quality.warnings` so agents can detect
936
938
  oversized bootstrap context or weak generated-plan file hints before editing.
@@ -1121,16 +1123,16 @@ snipara-companion workflow scaffold \
1121
1123
  ### Context vs Memory
1122
1124
 
1123
1125
  - Use `snipara-companion query`, `shared-context`, and `load-document` for source truth.
1124
- - Use `snipara-companion recall`, `session-bootstrap`, and `task-commit` for durable memory.
1126
+ - Use `snipara-companion recall`, `session-bootstrap`, and `task-commit` for durable memory when the task needs it.
1125
1127
  - Do not use memory as a substitute for document retrieval.
1126
1128
  - Do not upload specs or raw documents into memory.
1127
1129
 
1128
1130
  Semantics:
1129
1131
 
1130
1132
  - `snipara-companion query --follow-recommendation` = execute the hosted recommended structural tool instead of only printing it
1131
- - `snipara-companion workflow run --mode lite` = focused context query for small known-file work
1133
+ - `snipara-companion workflow run --mode lite` = zero mandatory hosted calls for small known-file work
1132
1134
  - `snipara-companion workflow run --mode standard` = context query plus automatic `snipara_code_*` follow-up when Snipara recommends one
1133
- - `snipara-companion workflow run --mode auto` = compatibility alias for STANDARD behavior
1135
+ - `snipara-companion workflow run --mode auto` = routes to lite, standard, full, or orchestrate from task intent
1134
1136
  - `snipara-companion workflow run --mode full` = budgeted durable bootstrap + optional session context + context query + automatic structural follow-up + hosted plan with quality diagnostics
1135
1137
  - `snipara-companion plan --write-plan-file ./plan.json` = convert hosted `snipara_plan` output into managed workflow JSON
1136
1138
  - `snipara-companion plan --start-workflow` or `workflow run --mode full --start-workflow-from-plan` = create local `.snipara/workflow/current.json` from a valid generated plan
@@ -1193,13 +1195,15 @@ Semantics:
1193
1195
  - `snipara-companion reindex` = trigger or poll hosted `snipara_reindex`; use after uploads when immediate chunk availability matters
1194
1196
  - `snipara-companion code *` = direct access to the code graph tools without routing through `snipara_context_query`
1195
1197
  - `snipara-companion recall` = direct durable memory lookup for decisions, learnings, preferences, and carryover
1196
- - `snipara-companion session-bootstrap` = durable memory first, optional weak session carryover second
1198
+ - `snipara-companion session-bootstrap` = pushed compact brief of durable memory first, optional weak session carryover second; empty brief is silent in text mode
1197
1199
  - `snipara-companion task-commit` = durable task/phase/workflow outcomes only, not a mechanical mirror of every Git commit
1198
- - `snipara-companion memory-guard check` = forced memory/context recall before retries, commits, or finalization when a command failed or a publishable package surface is touched
1200
+ - `snipara-companion memory-guard check` = deterministic guard recall/context before retries, commits, or finalization when a command failed or a publishable package surface is touched
1199
1201
  - `snipara-companion memory-guard check --intent "<action>" --destructive --strict` = contradiction check before irreversible actions; blocks until the user explicitly confirms when memory/context disagrees or the action is destructive
1200
1202
  - `snipara-companion memory-guard remember --guard-tag pre-commit --text "..."` = create a project/team memory in a guard category such as `pre-commit`, `commit`, `failure`, `pre-final`, or `workflow-policy`
1201
1203
  - `--max-daily-tokens` is still accepted as a compatibility alias for `--max-context-tokens`
1202
1204
 
1205
+ Use Outcome Loop data to calibrate these defaults: for small tasks, compare whether entry recall/context actually preceded retained commits before promoting a nudge into a gate.
1206
+
1203
1207
  ### Memory Guard Before Commit Or Destructive Actions
1204
1208
 
1205
1209
  Memory Guard is deterministic, not a user preference. It detects two global signals:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snipara-companion",
3
- "version": "3.2.6",
3
+ "version": "3.2.7",
4
4
  "description": "Local-first CLI that asks your repo what breaks before an AI coding agent edits it.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {