@hassangameryt/freeflow 0.6.0 → 0.7.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.
Files changed (136) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +3 -2
  3. package/.codex-plugin/plugin.json +5 -6
  4. package/.cursor-plugin/plugin.json +25 -0
  5. package/README.md +66 -56
  6. package/capabilities/cognitive-routing/SKILL.md +288 -130
  7. package/com.github.copilot/hooks/hooks.json +11 -0
  8. package/command-surface.json +0 -24
  9. package/gemini-extension.json +5 -0
  10. package/hooks/adapters/claude-session-start.mjs +16 -0
  11. package/hooks/adapters/codex-session-start.mjs +16 -0
  12. package/hooks/adapters/copilot-session-start.mjs +13 -0
  13. package/hooks/adapters/cursor-session-start.mjs +13 -0
  14. package/hooks/adapters/gemini-session-start.mjs +15 -0
  15. package/hooks/claude/hooks.json +18 -0
  16. package/hooks/codex/hooks.json +18 -0
  17. package/hooks/cursor/hooks.json +9 -0
  18. package/hooks/freeflow-runtime-context.mjs +3 -650
  19. package/hooks/hooks.json +4 -30
  20. package/hooks/shared/runtime-context.mjs +210 -0
  21. package/hooks/tests/check-host-adapters.test.mjs +82 -0
  22. package/hooks/tests/check-runtime-context-hook.sh +140 -320
  23. package/package.json +20 -4
  24. package/pi-extension/dist/cognitive-routing/commands.js +3 -3
  25. package/pi-extension/dist/cognitive-routing/config.js +16 -20
  26. package/pi-extension/dist/cognitive-routing/controller.js +478 -48
  27. package/pi-extension/dist/cognitive-routing/history.js +12 -0
  28. package/pi-extension/dist/cognitive-routing/host.js +74 -12
  29. package/pi-extension/dist/cognitive-routing/pi-routing-session.js +414 -0
  30. package/pi-extension/dist/cognitive-routing/pi-session-control.js +320 -0
  31. package/pi-extension/dist/cognitive-routing/tool.js +1 -0
  32. package/pi-extension/dist/cognitive-routing/types.js +1 -1
  33. package/pi-extension/dist/index.js +236 -219
  34. package/pi-extension/dist/runtime/runtime-context.js +126 -286
  35. package/pi-extension/dist/settings/settings-ui.js +52 -336
  36. package/pi-extension/src/cognitive-routing/commands.ts +15 -5
  37. package/pi-extension/src/cognitive-routing/config.ts +16 -20
  38. package/pi-extension/src/cognitive-routing/controller.ts +561 -51
  39. package/pi-extension/src/cognitive-routing/history.ts +12 -0
  40. package/pi-extension/src/cognitive-routing/host.ts +110 -16
  41. package/pi-extension/src/cognitive-routing/pi-routing-session.ts +538 -0
  42. package/pi-extension/src/cognitive-routing/pi-session-control.ts +444 -0
  43. package/pi-extension/src/cognitive-routing/tool.ts +1 -0
  44. package/pi-extension/src/cognitive-routing/types.ts +1 -1
  45. package/pi-extension/src/index.ts +249 -239
  46. package/pi-extension/src/runtime/runtime-context.ts +129 -305
  47. package/pi-extension/src/settings/settings-ui.ts +53 -371
  48. package/pi-extension/tests/cognitive-routing/commands.test.js +1 -1
  49. package/pi-extension/tests/cognitive-routing/controller.test.js +69 -40
  50. package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +128 -57
  51. package/pi-extension/tests/cognitive-routing/pi-normal-lifecycle.test.js +434 -0
  52. package/pi-extension/tests/cognitive-routing/pi-session-control.test.js +174 -0
  53. package/pi-extension/tests/cognitive-routing/pi-session-history.test.js +91 -0
  54. package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +47 -4
  55. package/pi-extension/tests/integration/mode-free-core.test.js +218 -0
  56. package/pi-extension/tests/integration/pi-extension.test.js +430 -2478
  57. package/pi-extension/tests/integration/prompt-architecture.test.js +124 -79
  58. package/pi-extension/tests/integration/unaffected-regressions.test.js +411 -0
  59. package/plugin.json +33 -0
  60. package/runtime/prompts/cognitive-routing.md +5 -4
  61. package/runtime/prompts/conversation-history.md +1 -1
  62. package/runtime/prompts/core.md +77 -6
  63. package/runtime/prompts/interaction-contract.md +6 -2
  64. package/skills/action-selection/SKILL.md +93 -44
  65. package/skills/action-selection/references/trajectory-stalls.md +71 -0
  66. package/skills/bypass/SKILL.md +109 -39
  67. package/skills/commit-work/SKILL.md +94 -55
  68. package/skills/commit-work/references/git-state-edges.md +94 -0
  69. package/skills/commit-work/references/simple-push.md +92 -0
  70. package/skills/commit-work/references/staging-decisions.md +79 -46
  71. package/skills/decision-gate/SKILL.md +80 -22
  72. package/skills/design-for-depth/SKILL.md +208 -43
  73. package/skills/design-for-depth/references/design-pressure-signals.md +108 -240
  74. package/skills/design-for-depth/references/interface-design-loop.md +77 -97
  75. package/skills/design-for-depth/references/module-and-dependency-design.md +147 -0
  76. package/skills/design-for-depth/references/software-design-philosophy.md +127 -173
  77. package/skills/design-for-depth/references/state-and-failure-boundaries.md +136 -0
  78. package/skills/diagnose-failure/SKILL.md +198 -52
  79. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +19 -5
  80. package/skills/diagnose-failure/references/flaky-and-performance-diagnosis.md +13 -5
  81. package/skills/discuss/SKILL.md +118 -76
  82. package/skills/discuss/references/discussion-continuity.md +84 -32
  83. package/skills/evaluate-skill/SKILL.md +166 -52
  84. package/skills/evaluate-skill/references/evaluation-definition-schema.md +2 -2
  85. package/skills/evaluate-skill/references/evaluation-design.md +56 -30
  86. package/skills/evaluate-skill/references/execution-and-evidence.md +1 -1
  87. package/skills/evaluate-skill/references/review-and-revision.md +62 -21
  88. package/skills/execute-work/SKILL.md +98 -59
  89. package/skills/execute-work/references/code-practices.md +4 -4
  90. package/skills/execute-work/references/execute-work-edges.md +42 -22
  91. package/skills/review-artifact/SKILL.md +132 -71
  92. package/skills/review-artifact/references/adjudicate-artifact-review.md +101 -0
  93. package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +52 -41
  94. package/skills/review-work/SKILL.md +115 -72
  95. package/skills/review-work/references/adjudicate-work-review.md +97 -0
  96. package/skills/review-work/references/independent-work-reviewer-contract.md +40 -35
  97. package/skills/review-work/references/security-risk-lens.md +17 -15
  98. package/skills/setup-freeflow/SKILL.md +14 -17
  99. package/skills/setup-freeflow/references/activation-contract.md +24 -30
  100. package/skills/setup-freeflow/references/host-setup.md +6 -7
  101. package/skills/simplify-code/SKILL.md +97 -39
  102. package/skills/simplify-code/references/simplification-patterns.md +1 -1
  103. package/skills/tdd/SKILL.md +108 -41
  104. package/skills/tdd/references/test-design.md +1 -1
  105. package/skills/track-work/SKILL.md +133 -300
  106. package/skills/track-work/references/working-record-format.md +515 -0
  107. package/skills/track-work/scripts/lib/document.mjs +713 -0
  108. package/skills/track-work/scripts/lib/format.mjs +166 -0
  109. package/skills/track-work/scripts/lib/store.mjs +233 -0
  110. package/skills/track-work/scripts/lib/transitions.mjs +790 -0
  111. package/skills/track-work/scripts/lib/views.mjs +27 -430
  112. package/skills/track-work/scripts/working-record.mjs +292 -98
  113. package/skills/verify-work/SKILL.md +46 -20
  114. package/skills/verify-work/references/browser-runtime-evidence.md +1 -1
  115. package/skills/verify-work/references/integration-evidence.md +1 -7
  116. package/skills/verify-work/references/performance-evidence.md +1 -1
  117. package/skills/workflow/SKILL.md +110 -80
  118. package/skills/workflow/references/domain-skill-composition.md +24 -18
  119. package/skills/write-skill/SKILL.md +218 -62
  120. package/skills/write-skill/references/activation-boundaries.md +63 -21
  121. package/skills/write-skill/references/agent-first-instructions.md +61 -27
  122. package/skills/write-skill/references/progressive-disclosure.md +91 -41
  123. package/skills/write-skill/references/skill-dependency-graphs.md +190 -0
  124. package/runtime/prompts/skills.md +0 -65
  125. package/skills/mode-contract/SKILL.md +0 -104
  126. package/skills/track-work/scripts/lib/codec.mjs +0 -570
  127. package/skills/track-work/scripts/lib/commands.mjs +0 -568
  128. package/skills/track-work/scripts/lib/contract.mjs +0 -303
  129. package/skills/track-work/scripts/lib/model.mjs +0 -506
  130. package/skills/track-work/scripts/lib/operations.mjs +0 -965
  131. package/skills/track-work/scripts/lib/record-store.mjs +0 -264
  132. package/skills/track-work/scripts/lib/result.mjs +0 -37
  133. package/skills/track-work/scripts/lib/rewrites.mjs +0 -740
  134. package/skills/track-work/scripts/lib/schema.mjs +0 -277
  135. package/skills/track-work/scripts/lib/source-inventory.mjs +0 -162
  136. package/skills/track-work/scripts/lib/workspace.mjs +0 -134
@@ -4,15 +4,12 @@ import { dirname, isAbsolute, join, resolve } from "node:path";
4
4
  import { promisify } from "node:util";
5
5
 
6
6
  import {
7
- handleModeCommand,
8
7
  readCapabilityState,
9
8
  readFreeflowConfig,
10
9
  readFreeflowConfigLayers,
11
10
  readFreeflowLocalConfig,
12
- readModeState,
13
11
  resetSessionOverrides,
14
12
  setSessionCoreOverride,
15
- VALID_MODES,
16
13
  } from "../runtime/runtime-context.js";
17
14
  import {
18
15
  PiSettingsComponent,
@@ -22,6 +19,7 @@ import {
22
19
  type SettingsWizard,
23
20
  type SettingsWizardStep,
24
21
  } from "./settings-tui.js";
22
+ import { supportsPiSessionModelStateApi } from "../cognitive-routing/pi-session-control.js";
25
23
  import { isPiFlowHost } from "../runtime/runtime-identity.js";
26
24
  import type {
27
25
  CognitiveRoutingCapabilityState,
@@ -31,22 +29,8 @@ import type {
31
29
  } from "../cognitive-routing/types.js";
32
30
 
33
31
  const DEFAULT_FREEFLOW_ENABLED = true;
34
- const DEFAULT_INTERACTION_CONTRACT_ENABLED = true;
35
- const DEFAULT_SKILLS_ENABLED = true;
36
32
  const DEFAULT_CONTEXT_VIRTUALIZATION_ENABLED = false;
37
33
  const DEFAULT_CONVERSATION_HISTORY_ENABLED = false;
38
- const MODE_VALUES = ["conversation", "workflow", "strict-workflow"];
39
- const MODE_LABELS = {
40
- default: "Use configured default",
41
- conversation: "conversation",
42
- workflow: "workflow",
43
- "strict-workflow": "strict-workflow",
44
- };
45
- const MODE_DESCRIPTIONS = {
46
- conversation: "Discussion and read-only inspection",
47
- workflow: "Adaptive workflow for consequential work",
48
- "strict-workflow": "Stronger decision and evidence pressure for high-risk work",
49
- };
50
34
  const LOCAL_INHERIT = "inherit";
51
35
  const execFileAsync = promisify(execFile);
52
36
 
@@ -307,114 +291,29 @@ function createScopedBooleanItem(options: ScopedBooleanItemOptions): SettingsIte
307
291
  return item;
308
292
  }
309
293
 
310
- type ScopedDefaultModeItemOptions = {
311
- scope: ConfigScope;
312
- repositoryDefaultMode: string;
313
- repositoryDefaultSource: ConfigSource;
314
- localDefaultMode?: string;
315
- effectiveValue: string;
316
- effectiveSource: ConfigSource;
317
- };
318
-
319
- function createScopedDefaultModeItem(options: ScopedDefaultModeItemOptions): SettingsItem {
320
- let item: SettingsItem;
321
- if (options.scope === "local") {
322
- item = {
323
- id: "freeflow.defaultMode",
324
- label: "Default mode",
325
- description:
326
- "Personal default mode for this checkout. Choose inherit to use the repository default; use /freeflow settings repo to edit shared defaults.",
327
- path: ["defaultMode"],
328
- kind: "enum",
329
- value: options.localDefaultMode ?? LOCAL_INHERIT,
330
- values: [LOCAL_INHERIT, ...MODE_VALUES],
331
- valueLabels: {
332
- inherit: "Inherit repository",
333
- ...MODE_LABELS,
334
- },
335
- valueDescriptions: {
336
- inherit: `Use ${options.repositoryDefaultMode} from ${options.repositoryDefaultSource}.`,
337
- ...MODE_DESCRIPTIONS,
338
- },
339
- format: (value) => String(value),
340
- configScope: "local",
341
- configValues: { inherit: undefined },
342
- effectiveValue: options.effectiveValue,
343
- effectiveSource: options.effectiveSource,
344
- inheritedValue: options.repositoryDefaultMode,
345
- inheritedSource: options.repositoryDefaultSource,
346
- };
347
- } else {
348
- item = {
349
- id: "freeflow.defaultMode",
350
- label: "Default mode",
351
- description:
352
- "Shared repository default Freeflow mode used when Skills are enabled. This edits .freeflow/config.json.",
353
- path: ["defaultMode"],
354
- kind: "enum",
355
- value: options.repositoryDefaultMode,
356
- values: MODE_VALUES,
357
- valueLabels: MODE_LABELS,
358
- valueDescriptions: MODE_DESCRIPTIONS,
359
- configScope: "repository",
360
- effectiveValue: options.effectiveValue,
361
- effectiveSource: options.effectiveSource,
362
- localOverrideValue: options.localDefaultMode,
363
- };
364
- }
365
- item.displaySuffix = coreDisplaySuffix(item);
366
- return item;
367
- }
368
-
369
- function sessionModeDisplaySuffix(
370
- sessionMode: string,
371
- defaultMode: string,
372
- defaultSource: ConfigSource,
373
- inactive: boolean,
374
- ): string | undefined {
375
- if (sessionMode !== "default") return undefined;
376
- const inactiveSuffix = inactive ? " · inactive" : "";
377
- return `(${defaultMode} · ${defaultSource}${inactiveSuffix})`;
378
- }
379
-
380
- function validModeOrUndefined(value: unknown): string | undefined {
381
- return typeof value === "string" && VALID_MODES.has(value) ? value : undefined;
382
- }
383
-
384
294
  function resolveSettingsCoreView(
385
295
  rawConfig: Record<string, unknown>,
386
296
  layers?: Awaited<ReturnType<typeof readFreeflowConfigLayers>>,
387
297
  ) {
388
298
  const localConfig = layers?.local.valid && isRecord(layers.local.parsed) ? layers.local.parsed : {};
389
- const repositorySkillsValue = getPath(rawConfig, ["skills"]);
390
- const repositorySkills = isRecord(repositorySkillsValue) ? repositorySkillsValue : {};
391
299
  const fallbackCore = {
392
300
  enabled: getPath(rawConfig, ["enabled"]) !== false,
393
- interactionContract: getPath(rawConfig, ["interactionContract"]) !== false,
394
301
  contextVirtualization: getPath(rawConfig, ["contextVirtualization"]) === true,
395
302
  conversationHistory: getPath(rawConfig, ["conversationHistory"]) === true,
396
- skills: { enabled: getPath(repositorySkills, ["enabled"]) !== false },
397
- defaultMode: validModeOrUndefined(rawConfig.defaultMode) ?? "workflow",
398
303
  };
399
304
  const fallbackSources = {
400
305
  enabled: typeof getPath(rawConfig, ["enabled"]) === "boolean" ? "repository" : "builtin",
401
- interactionContract: typeof getPath(rawConfig, ["interactionContract"]) === "boolean" ? "repository" : "builtin",
402
306
  contextVirtualization:
403
307
  typeof getPath(rawConfig, ["contextVirtualization"]) === "boolean" ? "repository" : "builtin",
404
308
  conversationHistory: typeof getPath(rawConfig, ["conversationHistory"]) === "boolean" ? "repository" : "builtin",
405
- skillsEnabled: typeof getPath(repositorySkills, ["enabled"]) === "boolean" ? "repository" : "builtin",
406
- defaultMode: validModeOrUndefined(rawConfig.defaultMode) === undefined ? "builtin" : "repository",
407
309
  } as const;
408
310
  return {
409
311
  localConfig,
410
312
  core: layers?.coreConfig ?? fallbackCore,
411
313
  sources: (layers?.sources ?? fallbackSources) as {
412
314
  enabled: ConfigSource;
413
- interactionContract: ConfigSource;
414
315
  contextVirtualization: ConfigSource;
415
316
  conversationHistory: ConfigSource;
416
- skillsEnabled: ConfigSource;
417
- defaultMode: ConfigSource;
418
317
  },
419
318
  };
420
319
  }
@@ -423,7 +322,7 @@ function createSessionBooleanItem(options: {
423
322
  id: string;
424
323
  label: string;
425
324
  description: string;
426
- key: "enabled" | "interactionContract" | "skillsEnabled" | "contextVirtualization" | "conversationHistory";
325
+ key: "enabled" | "contextVirtualization" | "conversationHistory";
427
326
  inheritedValue: boolean;
428
327
  inheritedSource: ConfigSource;
429
328
  effectiveValue: boolean;
@@ -469,24 +368,19 @@ function createSessionBooleanItem(options: {
469
368
 
470
369
  function sessionFreeflowItems(
471
370
  state: Awaited<ReturnType<typeof readCapabilityState>>,
472
- modeState: Awaited<ReturnType<typeof readModeState>>,
473
371
  cognitiveRoutingController?: CognitiveRoutingSettingsController,
474
372
  ): SettingsItem[] {
475
373
  const sessionOverrides = state.sessionOverrides as Record<string, boolean>;
476
374
  const configured = state.configuredCoreConfig;
477
375
  const configuredSources = state.configuredSources as {
478
376
  enabled: ConfigSource;
479
- interactionContract: ConfigSource;
480
377
  contextVirtualization: ConfigSource;
481
378
  conversationHistory: ConfigSource;
482
- skillsEnabled: ConfigSource;
483
379
  };
484
380
  const effectiveSources = state.configSources as {
485
381
  enabled: ConfigSource;
486
- interactionContract: ConfigSource;
487
382
  contextVirtualization: ConfigSource;
488
383
  conversationHistory: ConfigSource;
489
- skillsEnabled: ConfigSource;
490
384
  };
491
385
 
492
386
  const freeflowItem = createSessionBooleanItem({
@@ -500,28 +394,6 @@ function sessionFreeflowItems(
500
394
  effectiveSource: effectiveSources.enabled,
501
395
  sessionOverrides,
502
396
  });
503
- const interactionItem = createSessionBooleanItem({
504
- id: "freeflow.interactionContract",
505
- label: "Interaction Contract",
506
- description: "Temporary Interaction Contract override for this Pi session.",
507
- key: "interactionContract",
508
- inheritedValue: configured.interactionContract,
509
- inheritedSource: configuredSources.interactionContract,
510
- effectiveValue: state.interactionContract.enabled,
511
- effectiveSource: effectiveSources.interactionContract,
512
- sessionOverrides,
513
- });
514
- const skillsItem = createSessionBooleanItem({
515
- id: "freeflow.skills.enabled",
516
- label: "Skills",
517
- description: "Temporary Freeflow Skills override for this Pi session.",
518
- key: "skillsEnabled",
519
- inheritedValue: configured.skills.enabled,
520
- inheritedSource: configuredSources.skillsEnabled,
521
- effectiveValue: state.skills.enabled,
522
- effectiveSource: effectiveSources.skillsEnabled,
523
- sessionOverrides,
524
- });
525
397
  const contextVirtualizationItem = createSessionBooleanItem({
526
398
  id: "freeflow.contextVirtualization",
527
399
  label: "Context Virtualization",
@@ -546,38 +418,8 @@ function sessionFreeflowItems(
546
418
  });
547
419
 
548
420
  const freeflowInactive = !state.enabled;
549
- const skillsEnabled = state.skills.enabled;
550
- interactionItem.inactive = freeflowInactive;
551
- skillsItem.inactive = freeflowInactive;
552
- contextVirtualizationItem.inactive = freeflowInactive || !skillsEnabled;
553
- conversationHistoryItem.inactive = freeflowInactive || !skillsEnabled;
554
-
555
- const sessionMode = modeState.currentMode ?? "default";
556
- const sessionModeItem: SettingsItem = {
557
- id: "freeflow.sessionMode",
558
- label: "Mode",
559
- description: "Temporary mode override for this Pi session.",
560
- kind: "enum",
561
- value: sessionMode,
562
- values: ["default", ...MODE_VALUES],
563
- valueLabels: {
564
- ...MODE_LABELS,
565
- default: "Use configured default",
566
- },
567
- valueDescriptions: {
568
- default: `${modeState.defaultMode} from ${modeState.defaultModeSource}`,
569
- ...MODE_DESCRIPTIONS,
570
- },
571
- inactive: freeflowInactive || !skillsEnabled,
572
- displaySuffix: sessionModeDisplaySuffix(
573
- sessionMode,
574
- modeState.defaultMode,
575
- modeState.defaultModeSource,
576
- freeflowInactive || !skillsEnabled,
577
- ),
578
- inheritedValue: modeState.defaultMode,
579
- inheritedSource: modeState.defaultModeSource,
580
- };
421
+ contextVirtualizationItem.inactive = freeflowInactive;
422
+ conversationHistoryItem.inactive = freeflowInactive;
581
423
 
582
424
  const cognitiveRoutingState = cognitiveRoutingController?.state();
583
425
  const cognitiveRoutingProfile =
@@ -604,7 +446,7 @@ function sessionFreeflowItems(
604
446
  standard: "Hold the standard profile until /freeflow profile auto.",
605
447
  reasoning: "Hold the reasoning profile until /freeflow profile auto.",
606
448
  },
607
- inactive: !state.cognitiveRouting.effective || cognitiveRoutingController === undefined,
449
+ inactive: freeflowInactive || !state.cognitiveRouting.effective || cognitiveRoutingController === undefined,
608
450
  runtimeInactive: state.cognitiveRouting.blockingReason?.code === "runtime_disabled",
609
451
  displaySuffix: cognitiveRoutingState?.effective ? cognitiveRoutingProfile : "unavailable",
610
452
  }
@@ -612,15 +454,11 @@ function sessionFreeflowItems(
612
454
 
613
455
  return [
614
456
  freeflowItem,
615
- interactionItem,
616
- skillsItem,
617
- sessionModeItem,
618
457
  ...(cognitiveRoutingItem ? [cognitiveRoutingItem] : []),
619
458
  {
620
459
  id: "freeflow.session.reset",
621
460
  label: "Reset session overrides",
622
- description:
623
- "Clear Freeflow, Interaction Contract, Skills, Context Virtualization, Conversation History, and mode overrides for this Pi session.",
461
+ description: "Clear Freeflow, Context Virtualization, and Conversation History overrides for this Pi session.",
624
462
  kind: "enum",
625
463
  value: "available",
626
464
  values: ["reset"],
@@ -899,18 +737,18 @@ function cognitiveRoutingSessionStartItem(options: {
899
737
  capabilityState: CognitiveRoutingCapabilityState | undefined;
900
738
  }): SettingsItem {
901
739
  const path = ["cognitiveRouting", "sessionStart", options.setting];
902
- const defaultValue = options.setting === "control" ? "automatic" : "standard";
740
+ const defaultValue = options.setting === "control" ? "automatic" : "reasoning";
903
741
  const values = options.setting === "control" ? ["automatic", "manual"] : ["standard", "reasoning"];
904
742
  const labels = Object.fromEntries(values.map((value) => [value, value]));
905
743
  const descriptions =
906
744
  options.setting === "control"
907
745
  ? {
908
- automatic: "Let Cognitive Routing manage profile transitions for the new session.",
746
+ automatic: "Start the new session in Reasoning; automatic delegation may use Standard during execution.",
909
747
  manual: "Hold the selected profile for the new session until the user changes it.",
910
748
  }
911
749
  : {
912
- standard: "Start a new session with the configured Standard preset.",
913
- reasoning: "Start a new session with the configured Reasoning preset.",
750
+ standard: "Start a new manual session with the configured Standard preset.",
751
+ reasoning: "Start a new manual session with the configured Reasoning preset.",
914
752
  };
915
753
  const repositoryValue = getPath(options.rawConfig, path);
916
754
  const localValue = getPath(options.localConfig, path);
@@ -921,13 +759,21 @@ function cognitiveRoutingSessionStartItem(options: {
921
759
  const inheritedSource: ConfigSource = repositorySetting ? "repository" : "builtin";
922
760
  const configuredSource =
923
761
  options.capabilityState?.sessionStartSources?.[options.setting] ?? (repositorySetting ? "repository" : undefined);
924
- const effectiveValue = options.capabilityState?.sessionStart?.[options.setting] ?? inheritedValue;
762
+ const effectiveSessionStartControl =
763
+ options.capabilityState?.sessionStart?.control ??
764
+ getPath(options.localConfig, ["cognitiveRouting", "sessionStart", "control"]) ??
765
+ getPath(options.rawConfig, ["cognitiveRouting", "sessionStart", "control"]) ??
766
+ "automatic";
767
+ const effectiveValue =
768
+ options.setting === "profile" && effectiveSessionStartControl === "automatic"
769
+ ? "reasoning"
770
+ : (options.capabilityState?.sessionStart?.[options.setting] ?? inheritedValue);
925
771
  const effectiveSource = cognitiveRoutingSettingsSource(configuredSource);
926
- const label = options.setting === "control" ? "Session start control" : "Session start profile";
772
+ const label = options.setting === "control" ? "Session start control" : "Manual session-start profile";
927
773
  const description =
928
774
  options.setting === "control"
929
775
  ? "Choose automatic or manual control for new sessions only; changing this does not alter the active session."
930
- : "Choose the initial profile for new sessions only; changing this does not alter the active session.";
776
+ : "Choose the profile for manual session starts; automatic sessions always start in Reasoning.";
931
777
 
932
778
  const item: SettingsItem =
933
779
  options.scope === "local"
@@ -973,15 +819,18 @@ function cognitiveRoutingSessionStartItem(options: {
973
819
  return item;
974
820
  }
975
821
 
822
+ function isCognitiveRoutingRuntimeAvailable(pi: any): boolean {
823
+ return isPiFlowHost(pi?.host) || supportsPiSessionModelStateApi(pi);
824
+ }
825
+
976
826
  function freeflowItems(
977
827
  rawConfig: Record<string, unknown>,
978
- modeState?: Awaited<ReturnType<typeof readModeState>>,
979
828
  options: {
980
829
  scope?: ConfigScope;
981
830
  layers?: Awaited<ReturnType<typeof readFreeflowConfigLayers>>;
982
831
  cognitiveRouting?: CognitiveRoutingCapabilityState;
983
832
  ctx?: any;
984
- hostInfo?: unknown;
833
+ runtimeAvailable?: boolean;
985
834
  } = {},
986
835
  ): SettingsItem[] {
987
836
  const scope = options.scope ?? "repository";
@@ -994,36 +843,12 @@ function freeflowItems(
994
843
  localConfig,
995
844
  id: "freeflow.enabled",
996
845
  label: "Freeflow",
997
- description: "Master switch for the Interaction Contract and Freeflow skills in this checkout.",
846
+ description: "Master switch for Freeflow's core guidance, skills, and optional capabilities in this checkout.",
998
847
  path: ["enabled"],
999
848
  effectiveValue: core.enabled,
1000
849
  effectiveSource: sources.enabled,
1001
850
  defaultValue: DEFAULT_FREEFLOW_ENABLED,
1002
851
  });
1003
- const interactionItem = createScopedBooleanItem({
1004
- scope,
1005
- rawConfig,
1006
- localConfig,
1007
- id: "freeflow.interactionContract",
1008
- label: "Interaction Contract",
1009
- description: "Apply Freeflow's compact turn-interpretation and collaboration guidance.",
1010
- path: ["interactionContract"],
1011
- effectiveValue: core.interactionContract,
1012
- effectiveSource: sources.interactionContract,
1013
- defaultValue: DEFAULT_INTERACTION_CONTRACT_ENABLED,
1014
- });
1015
- const skillsItem = createScopedBooleanItem({
1016
- scope,
1017
- rawConfig,
1018
- localConfig,
1019
- id: "freeflow.skills.enabled",
1020
- label: "Skills",
1021
- description: "Expose Freeflow skills and discover Workflow before consequential or mutating work.",
1022
- path: ["skills", "enabled"],
1023
- effectiveValue: core.skills.enabled,
1024
- effectiveSource: sources.skillsEnabled,
1025
- defaultValue: DEFAULT_SKILLS_ENABLED,
1026
- });
1027
852
  const contextVirtualizationItem = createScopedBooleanItem({
1028
853
  scope,
1029
854
  rawConfig,
@@ -1049,55 +874,12 @@ function freeflowItems(
1049
874
  defaultValue: DEFAULT_CONVERSATION_HISTORY_ENABLED,
1050
875
  });
1051
876
 
1052
- const repositoryModeValue = validModeOrUndefined(rawConfig.defaultMode);
1053
- const repositoryDefaultMode = repositoryModeValue ?? "workflow";
1054
- const repositoryDefaultSource: ConfigSource = repositoryModeValue ? "repository" : "builtin";
1055
- const localDefaultMode = validModeOrUndefined(localConfig.defaultMode);
1056
- const defaultModeItem = createScopedDefaultModeItem({
1057
- scope,
1058
- repositoryDefaultMode,
1059
- repositoryDefaultSource,
1060
- localDefaultMode,
1061
- effectiveValue: core.defaultMode,
1062
- effectiveSource: sources.defaultMode,
1063
- });
1064
-
1065
877
  const freeflowInactive = !core.enabled;
1066
- const skillsEnabled = core.skills.enabled;
1067
- interactionItem.inactive = freeflowInactive;
1068
- skillsItem.inactive = freeflowInactive;
1069
- contextVirtualizationItem.inactive = freeflowInactive || !skillsEnabled;
1070
- conversationHistoryItem.inactive = freeflowInactive || !skillsEnabled;
1071
- defaultModeItem.inactive = freeflowInactive;
1072
- defaultModeItem.displaySuffix = coreDisplaySuffix(defaultModeItem, freeflowInactive || !skillsEnabled);
1073
- const sessionMode = modeState?.currentMode ?? "default";
1074
- const sessionModeItem: SettingsItem = {
1075
- id: "freeflow.sessionMode",
1076
- label: "Session mode",
1077
- description:
1078
- "Temporary mode override for this Pi session. Use configured default clears the override without changing either config file.",
1079
- kind: "enum",
1080
- value: sessionMode,
1081
- values: ["default", ...MODE_VALUES],
1082
- valueLabels: {
1083
- ...MODE_LABELS,
1084
- default: "Use configured default",
1085
- },
1086
- valueDescriptions: {
1087
- default: `${core.defaultMode} from ${sources.defaultMode}`,
1088
- ...MODE_DESCRIPTIONS,
1089
- },
1090
- inactive: freeflowInactive || !skillsEnabled,
1091
- displaySuffix: sessionModeDisplaySuffix(
1092
- sessionMode,
1093
- core.defaultMode,
1094
- sources.defaultMode,
1095
- freeflowInactive || !skillsEnabled,
1096
- ),
1097
- };
878
+ contextVirtualizationItem.inactive = freeflowInactive;
879
+ conversationHistoryItem.inactive = freeflowInactive;
1098
880
 
1099
881
  const cognitiveRoutingState = options.cognitiveRouting;
1100
- const cognitiveRoutingRuntimeDisabled = !isPiFlowHost(options.hostInfo);
882
+ const cognitiveRoutingRuntimeDisabled = options.runtimeAvailable !== true;
1101
883
  const cognitiveRoutingGroup = (() => {
1102
884
  const cognitiveRoutingEnabledItem = createScopedBooleanItem({
1103
885
  scope,
@@ -1106,14 +888,14 @@ function freeflowItems(
1106
888
  id: "freeflow.cognitiveRouting.enabled",
1107
889
  label: "Enabled",
1108
890
  description: cognitiveRoutingRuntimeDisabled
1109
- ? "Configured for PiFlow, but disabled in normal Pi."
891
+ ? "Requires a host model-state control API; configuration is read-only on this host."
1110
892
  : "Allow Cognitive Routing to own the session model lease and switch the configured profiles.",
1111
893
  path: ["cognitiveRouting", "enabled"],
1112
894
  effectiveValue: cognitiveRoutingState?.enabled ?? false,
1113
895
  effectiveSource: cognitiveRoutingSettingsSource(cognitiveRoutingState?.enabledSource),
1114
896
  defaultValue: false,
1115
897
  });
1116
- cognitiveRoutingEnabledItem.inactive = freeflowInactive || !skillsEnabled || cognitiveRoutingRuntimeDisabled;
898
+ cognitiveRoutingEnabledItem.inactive = freeflowInactive || cognitiveRoutingRuntimeDisabled;
1117
899
  cognitiveRoutingEnabledItem.runtimeInactive = cognitiveRoutingRuntimeDisabled;
1118
900
 
1119
901
  const cognitiveRoutingProfiles = ["standard", "reasoning"].map((name) =>
@@ -1137,11 +919,11 @@ function freeflowItems(
1137
919
  }),
1138
920
  );
1139
921
  for (const item of [...cognitiveRoutingProfiles, ...cognitiveRoutingSessionStart]) {
1140
- item.inactive ||= freeflowInactive || !skillsEnabled || cognitiveRoutingRuntimeDisabled;
922
+ item.inactive ||= freeflowInactive || cognitiveRoutingRuntimeDisabled;
1141
923
  item.runtimeInactive = cognitiveRoutingRuntimeDisabled;
1142
924
  }
1143
925
  const cognitiveRoutingStatus = cognitiveRoutingRuntimeDisabled
1144
- ? "disabled · PiFlow only"
926
+ ? "unavailable · host unsupported"
1145
927
  : cognitiveRoutingState
1146
928
  ? cognitiveRoutingState.effective
1147
929
  ? "active"
@@ -1153,11 +935,11 @@ function freeflowItems(
1153
935
  id: "freeflow.cognitiveRouting",
1154
936
  label: "Cognitive Routing",
1155
937
  description: cognitiveRoutingRuntimeDisabled
1156
- ? "Cognitive Routing configuration is visible for inspection but can only run in PiFlow."
1157
- : "Configure the automatic standard/reasoning profiles and choose whether Freeflow may manage model state for this repository.",
938
+ ? "Cognitive Routing configuration is visible for inspection but requires a host model-state control API."
939
+ : "Configure the Standard and Reasoning profiles and choose whether Freeflow may manage model state for this repository.",
1158
940
  kind: "group" as const,
1159
941
  value: cognitiveRoutingRuntimeDisabled ? false : (cognitiveRoutingState?.enabled ?? false),
1160
- inactive: freeflowInactive || !skillsEnabled,
942
+ inactive: freeflowInactive,
1161
943
  displaySuffix: cognitiveRoutingStatus,
1162
944
  children: [cognitiveRoutingEnabledItem, ...cognitiveRoutingProfiles, ...cognitiveRoutingSessionStart],
1163
945
  } satisfies SettingsItem;
@@ -1165,10 +947,6 @@ function freeflowItems(
1165
947
 
1166
948
  return [
1167
949
  freeflowItem,
1168
- interactionItem,
1169
- skillsItem,
1170
- sessionModeItem,
1171
- defaultModeItem,
1172
950
  ...(cognitiveRoutingGroup ? [cognitiveRoutingGroup] : []),
1173
951
  {
1174
952
  id: "freeflow.context",
@@ -1185,8 +963,7 @@ function freeflowItems(
1185
963
  function pruneKnownDefaults(config: Record<string, unknown>) {
1186
964
  const defaultPaths: Array<{ path: string[]; value: unknown }> = [
1187
965
  { path: ["enabled"], value: DEFAULT_FREEFLOW_ENABLED },
1188
- { path: ["interactionContract"], value: DEFAULT_INTERACTION_CONTRACT_ENABLED },
1189
- { path: ["skills", "enabled"], value: DEFAULT_SKILLS_ENABLED },
966
+ { path: ["contextVirtualization"], value: DEFAULT_CONTEXT_VIRTUALIZATION_ENABLED },
1190
967
  { path: ["conversationHistory"], value: DEFAULT_CONVERSATION_HISTORY_ENABLED },
1191
968
  ];
1192
969
 
@@ -1316,10 +1093,6 @@ function findSettingsItem(items: SettingsItem[], id: string): SettingsItem | und
1316
1093
  function refreshSettingsDerivedState(items: SettingsItem[]) {
1317
1094
  const freeflowItem = findSettingsItem(items, "freeflow.enabled");
1318
1095
  const freeflowInactive = freeflowItem ? effectiveItemValue(freeflowItem) !== true : false;
1319
- const skillsItem = findSettingsItem(items, "freeflow.skills.enabled");
1320
- const skillsEnabled = skillsItem ? effectiveItemValue(skillsItem) === true : true;
1321
- const sessionModeItem = findSettingsItem(items, "freeflow.sessionMode");
1322
- const defaultModeItem = findSettingsItem(items, "freeflow.defaultMode");
1323
1096
  const cognitiveRoutingGroup = findSettingsItem(items, "freeflow.cognitiveRouting");
1324
1097
  const cognitiveRoutingEnabledItem = findSettingsItem(items, "freeflow.cognitiveRouting.enabled");
1325
1098
  const cognitiveRoutingProfiles = [
@@ -1327,24 +1100,6 @@ function refreshSettingsDerivedState(items: SettingsItem[]) {
1327
1100
  findSettingsItem(items, "freeflow.cognitiveRouting.reasoning"),
1328
1101
  ];
1329
1102
 
1330
- if (sessionModeItem) {
1331
- const defaultMode = String(
1332
- defaultModeItem ? effectiveItemValue(defaultModeItem) : (sessionModeItem.inheritedValue ?? "workflow"),
1333
- );
1334
- const defaultSource = defaultModeItem?.effectiveSource ?? sessionModeItem.inheritedSource ?? "builtin";
1335
- sessionModeItem.inactive = freeflowInactive || !skillsEnabled;
1336
- sessionModeItem.displaySuffix = sessionModeDisplaySuffix(
1337
- String(sessionModeItem.value),
1338
- defaultMode,
1339
- defaultSource,
1340
- freeflowInactive || !skillsEnabled,
1341
- );
1342
- sessionModeItem.valueDescriptions = {
1343
- default: `${defaultMode} from ${defaultSource}`,
1344
- ...MODE_DESCRIPTIONS,
1345
- };
1346
- }
1347
-
1348
1103
  if (cognitiveRoutingGroup && cognitiveRoutingEnabledItem) {
1349
1104
  const enabled = effectiveItemValue(cognitiveRoutingEnabledItem) === true;
1350
1105
  const profilesConfigured = cognitiveRoutingProfiles.every((item) =>
@@ -1358,7 +1113,7 @@ function refreshSettingsDerivedState(items: SettingsItem[]) {
1358
1113
  : "configured"
1359
1114
  : "not configured"
1360
1115
  : "disabled";
1361
- cognitiveRoutingGroup.inactive = freeflowInactive || !skillsEnabled;
1116
+ cognitiveRoutingGroup.inactive = freeflowInactive;
1362
1117
  }
1363
1118
 
1364
1119
  const contextGroup = findSettingsItem(items, "freeflow.context");
@@ -1373,31 +1128,11 @@ function refreshSettingsDerivedState(items: SettingsItem[]) {
1373
1128
  candidate.inactive = false;
1374
1129
  } else if (candidate.configScope) {
1375
1130
  const inactive =
1376
- candidate.id === "freeflow.enabled"
1377
- ? false
1378
- : candidate.runtimeInactive === true ||
1379
- freeflowInactive ||
1380
- (!skillsEnabled &&
1381
- [
1382
- "freeflow.cognitiveRouting",
1383
- "freeflow.cognitiveRouting.enabled",
1384
- "freeflow.cognitiveRouting.standard",
1385
- "freeflow.cognitiveRouting.reasoning",
1386
- "freeflow.cognitiveRouting.sessionStart.control",
1387
- "freeflow.cognitiveRouting.sessionStart.profile",
1388
- "freeflow.contextVirtualization",
1389
- "freeflow.conversationHistory",
1390
- ].includes(candidate.id));
1391
- const displayInactive = candidate.id === "freeflow.defaultMode" ? freeflowInactive || !skillsEnabled : inactive;
1131
+ candidate.id === "freeflow.enabled" ? false : candidate.runtimeInactive === true || freeflowInactive;
1392
1132
  candidate.inactive = inactive;
1393
- candidate.displaySuffix = coreDisplaySuffix(candidate, displayInactive);
1394
- } else if (candidate.id === "freeflow.sessionMode") {
1395
- candidate.inactive = candidate.runtimeInactive === true || freeflowInactive || !skillsEnabled;
1133
+ candidate.displaySuffix = coreDisplaySuffix(candidate, inactive);
1396
1134
  } else {
1397
- candidate.inactive =
1398
- candidate.runtimeInactive === true ||
1399
- freeflowInactive ||
1400
- (!skillsEnabled && candidate.id === "freeflow.cognitiveRouting");
1135
+ candidate.inactive = candidate.runtimeInactive === true || freeflowInactive;
1401
1136
  }
1402
1137
  });
1403
1138
  }
@@ -1517,7 +1252,7 @@ function freeflowStatusText(
1517
1252
  const cognitiveRouting = state.cognitiveRouting;
1518
1253
  const cognitiveRoutingStatus = cognitiveRouting
1519
1254
  ? cognitiveRouting.blockingReason?.code === "runtime_disabled"
1520
- ? "disabled (PiFlow only)"
1255
+ ? "unavailable (host unsupported)"
1521
1256
  : cognitiveRouting.effective
1522
1257
  ? routingState?.effective
1523
1258
  ? `active (${routingState.activeProfile ?? "unknown"}, ${routingState.controlMode})`
@@ -1529,21 +1264,13 @@ function freeflowStatusText(
1529
1264
  const contextEnabled = state.contextVirtualization?.effective || state.conversationHistory?.effective;
1530
1265
  return [
1531
1266
  `Freeflow: ${state.enabled ? "enabled" : "disabled"}${sessionSuffix(state.configSources.enabled as ConfigSource)}`,
1532
- `interaction contract: ${state.interactionContract.effective ? "enabled" : "disabled"}${sessionSuffix(
1533
- state.configSources.interactionContract as ConfigSource,
1534
- )}`,
1535
- `skills: ${state.skills.effective ? "enabled" : "disabled (workflow modes inactive)"}${sessionSuffix(
1536
- state.configSources.skillsEnabled as ConfigSource,
1537
- )}`,
1538
1267
  `context: ${contextEnabled ? "enabled" : "disabled"} (virtualization ${state.contextVirtualization?.effective ? "enabled" : "disabled"}, history ${state.conversationHistory?.effective ? "enabled" : "disabled"})`,
1539
1268
  ...(cognitiveRoutingStatus ? [`cognitive routing: ${cognitiveRoutingStatus}`] : []),
1540
1269
  ].join("; ");
1541
1270
  }
1542
1271
 
1543
1272
  const NON_TUI_SETTINGS_GUIDANCE =
1544
- "Freeflow settings require Pi TUI mode. Use /freeflow status to inspect current state; supported non-TUI changes are /freeflow enable, /freeflow disable, and /freeflow mode <conversation|workflow|strict-workflow|reset>.";
1545
- const NON_TUI_MODE_GUIDANCE =
1546
- "Freeflow mode selector requires Pi TUI mode. Use /freeflow mode conversation, /freeflow mode workflow, /freeflow mode strict-workflow, or /freeflow mode reset.";
1273
+ "Freeflow settings require Pi TUI mode. Use /freeflow status to inspect current state; supported non-TUI changes are /freeflow enable and /freeflow disable.";
1547
1274
 
1548
1275
  function ensureSettingsIdle(ctx: any): boolean {
1549
1276
  if (typeof ctx?.isIdle !== "function" || ctx.isIdle()) return true;
@@ -1611,9 +1338,6 @@ export async function handleFreeflowCommand(
1611
1338
  const [action, ...rest] = input.split(/\s+/);
1612
1339
  const actionValue = rest.join(" ");
1613
1340
  const nonTui = ctx?.mode && ctx.mode !== "tui";
1614
- if (nonTui && action === "mode" && !actionValue) {
1615
- return nonTuiGuidance(ctx, NON_TUI_MODE_GUIDANCE);
1616
- }
1617
1341
  const settingsSelector =
1618
1342
  action === "settings" &&
1619
1343
  (!actionValue || ["session", "local", "personal", "repo", "repository", "shared"].includes(actionValue));
@@ -1621,10 +1345,9 @@ export async function handleFreeflowCommand(
1621
1345
  return nonTuiGuidance(ctx, NON_TUI_SETTINGS_GUIDANCE);
1622
1346
  }
1623
1347
 
1624
- const [layers, state, modeState] = await Promise.all([
1348
+ const [layers, state] = await Promise.all([
1625
1349
  readFreeflowConfigLayers(ctx.cwd),
1626
1350
  readCapabilityState(ctx.cwd, ctx, pi?.host),
1627
- readModeState(ctx.cwd),
1628
1351
  ]);
1629
1352
  const configState = layers.repository;
1630
1353
  const raw = configState.valid ? configState.parsed : {};
@@ -1646,50 +1369,15 @@ export async function handleFreeflowCommand(
1646
1369
  return { changed: false, reloaded: false, error: "invalid_local_config" };
1647
1370
  }
1648
1371
 
1649
- if (action === "mode") {
1650
- if (!ensureSettingsIdle(ctx)) return { changed: false, reloaded: false, error: "busy" };
1651
- if (actionValue) {
1652
- const result = await handleModeCommand(actionValue, ctx, pi);
1653
- return { changed: result.changed, reloaded: false, error: result.error };
1654
- }
1655
- if (!state.enabled || !state.skills.effective) {
1656
- const result = await handleModeCommand(undefined, ctx, pi);
1657
- return { changed: false, reloaded: false, error: result.error };
1658
- }
1659
- if (typeof ctx?.ui?.custom !== "function") {
1660
- const result = await handleModeCommand(undefined, ctx, pi);
1661
- return { changed: false, reloaded: false, error: result.error };
1662
- }
1663
-
1664
- const item = freeflowItems(raw, modeState, {
1665
- scope: "local",
1666
- layers,
1667
- cognitiveRouting: state.cognitiveRouting as CognitiveRoutingCapabilityState,
1668
- ctx,
1669
- hostInfo: pi?.host,
1670
- }).find((candidate) => candidate.id === "freeflow.sessionMode")!;
1671
- const session = await openSettings({
1672
- title: "Freeflow Mode",
1673
- items: [item],
1674
- initialChoice: item,
1675
- ctx,
1676
- onChange: async (_item, value) => {
1677
- const result = await handleModeCommand(String(value), ctx, pi);
1678
- return { changed: result.changed, reloadRequired: false };
1679
- },
1680
- });
1681
- return { changed: session.changed, reloaded: false, error: session.failed ? "write_failed" : undefined };
1682
- }
1683
-
1684
1372
  if (["enable", "on", "true", "disable", "off", "false"].includes(action)) {
1685
1373
  if (!ensureSettingsIdle(ctx)) return { changed: false, reloaded: false, error: "busy" };
1686
1374
  const enabled = ["enable", "on", "true"].includes(action);
1687
- const item = freeflowItems(raw, modeState, {
1375
+ const item = freeflowItems(raw, {
1688
1376
  scope: "repository",
1689
1377
  layers,
1690
1378
  cognitiveRouting: state.cognitiveRouting as CognitiveRoutingCapabilityState,
1691
1379
  ctx,
1692
- hostInfo: pi?.host,
1380
+ runtimeAvailable: isCognitiveRoutingRuntimeAvailable(pi),
1693
1381
  }).find((candidate) => candidate.id === "freeflow.enabled")!;
1694
1382
  await updateConfig(ctx.cwd, item, enabled, "repository");
1695
1383
  await afterChange(true);
@@ -1704,7 +1392,7 @@ export async function handleFreeflowCommand(
1704
1392
 
1705
1393
  if (action && action !== "settings") {
1706
1394
  ctx.ui.notify(
1707
- "Usage: /freeflow, /freeflow settings [local|repo], /freeflow status, /freeflow mode [conversation|workflow|strict-workflow|reset], /freeflow enable, or /freeflow disable",
1395
+ "Usage: /freeflow, /freeflow settings [local|repo], /freeflow status, /freeflow enable, or /freeflow disable",
1708
1396
  "warning",
1709
1397
  );
1710
1398
  return { changed: false, reloaded: false, error: "invalid_action" };
@@ -1728,13 +1416,13 @@ export async function handleFreeflowCommand(
1728
1416
  let reconcileCognitiveRouting = settingsScope === "session";
1729
1417
  const items =
1730
1418
  settingsScope === "session"
1731
- ? sessionFreeflowItems(state, modeState, cognitiveRoutingController)
1732
- : freeflowItems(raw, modeState, {
1419
+ ? sessionFreeflowItems(state, cognitiveRoutingController)
1420
+ : freeflowItems(raw, {
1733
1421
  scope: settingsScope,
1734
1422
  layers,
1735
1423
  cognitiveRouting: state.cognitiveRouting as CognitiveRoutingCapabilityState,
1736
1424
  ctx,
1737
- hostInfo: pi?.host,
1425
+ runtimeAvailable: isCognitiveRoutingRuntimeAvailable(pi),
1738
1426
  });
1739
1427
  const session = await openSettings({
1740
1428
  title:
@@ -1747,14 +1435,10 @@ export async function handleFreeflowCommand(
1747
1435
  ctx,
1748
1436
  onChange: async (item, value) => {
1749
1437
  if (!ensureSettingsIdle(ctx)) return { changed: false, reloadRequired: false };
1750
- if (!isPiFlowHost(pi?.host) && item.id.startsWith("freeflow.cognitiveRouting.")) {
1751
- ctx.ui.notify("Cognitive Routing is available only in PiFlow.", "warning");
1438
+ if (!isCognitiveRoutingRuntimeAvailable(pi) && item.id.startsWith("freeflow.cognitiveRouting.")) {
1439
+ ctx.ui.notify("Cognitive Routing is unavailable because this host lacks model-state controls.", "warning");
1752
1440
  return { changed: false, reloadRequired: false };
1753
1441
  }
1754
- if (item.id === "freeflow.sessionMode") {
1755
- const result = await handleModeCommand(String(value), ctx, pi);
1756
- return { changed: result.changed, reloadRequired: false };
1757
- }
1758
1442
  if (item.id === "freeflow.cognitiveRouting.profile") {
1759
1443
  if (!cognitiveRoutingController) {
1760
1444
  ctx.ui.notify("Cognitive Routing is unavailable for this session.", "warning");
@@ -1781,8 +1465,6 @@ export async function handleFreeflowCommand(
1781
1465
  if (item.configScope === "session") {
1782
1466
  const keyById = {
1783
1467
  "freeflow.enabled": "enabled",
1784
- "freeflow.interactionContract": "interactionContract",
1785
- "freeflow.skills.enabled": "skillsEnabled",
1786
1468
  "freeflow.contextVirtualization": "contextVirtualization",
1787
1469
  "freeflow.conversationHistory": "conversationHistory",
1788
1470
  } as const;