@hassangameryt/freeflow 0.1.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 (56) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +22 -0
  3. package/LICENSE +21 -0
  4. package/README.md +217 -0
  5. package/package.json +53 -0
  6. package/plugins/freeflow/.claude-plugin/plugin.json +20 -0
  7. package/plugins/freeflow/.codex-plugin/plugin.json +44 -0
  8. package/plugins/freeflow/assets/freeflow-plugin-icon-transparent.png +0 -0
  9. package/plugins/freeflow/command-surface.json +85 -0
  10. package/plugins/freeflow/docs/README.md +39 -0
  11. package/plugins/freeflow/docs/adr/0001-three-modes.md +27 -0
  12. package/plugins/freeflow/docs/adr/0002-evals-before-hooks.md +17 -0
  13. package/plugins/freeflow/docs/adr/0003-release-boundary.md +21 -0
  14. package/plugins/freeflow/docs/adr/README.md +7 -0
  15. package/plugins/freeflow/docs/architecture.md +86 -0
  16. package/plugins/freeflow/docs/release-evidence.md +49 -0
  17. package/plugins/freeflow/docs/skills.md +44 -0
  18. package/plugins/freeflow/docs/workflow.md +57 -0
  19. package/plugins/freeflow/hooks/freeflow-runtime-context.mjs +240 -0
  20. package/plugins/freeflow/hooks/hooks.json +18 -0
  21. package/plugins/freeflow/pi-extension/index.js +250 -0
  22. package/plugins/freeflow/skills/bypass/SKILL.md +68 -0
  23. package/plugins/freeflow/skills/capture-decisions/SKILL.md +95 -0
  24. package/plugins/freeflow/skills/capture-decisions/references/destination-guide.md +65 -0
  25. package/plugins/freeflow/skills/commit-work/SKILL.md +97 -0
  26. package/plugins/freeflow/skills/commit-work/references/staging-decisions.md +51 -0
  27. package/plugins/freeflow/skills/diagnose-failure/SKILL.md +95 -0
  28. package/plugins/freeflow/skills/diagnose-failure/references/feedback-loop-catalog.md +25 -0
  29. package/plugins/freeflow/skills/diagnose-failure/references/flaky-and-performance.md +31 -0
  30. package/plugins/freeflow/skills/evaluate-skill/SKILL.md +96 -0
  31. package/plugins/freeflow/skills/evaluate-skill/references/eval-patterns.md +41 -0
  32. package/plugins/freeflow/skills/evaluate-skill/references/grading-priority.md +33 -0
  33. package/plugins/freeflow/skills/execute-plan/SKILL.md +67 -0
  34. package/plugins/freeflow/skills/grill-context/SKILL.md +79 -0
  35. package/plugins/freeflow/skills/grill-context/references/approach-framing.md +52 -0
  36. package/plugins/freeflow/skills/handoff/SKILL.md +66 -0
  37. package/plugins/freeflow/skills/handoff/references/templates.md +64 -0
  38. package/plugins/freeflow/skills/interview-gate/SKILL.md +90 -0
  39. package/plugins/freeflow/skills/mode-contract/SKILL.md +79 -0
  40. package/plugins/freeflow/skills/research-brief/SKILL.md +69 -0
  41. package/plugins/freeflow/skills/review-artifact/SKILL.md +82 -0
  42. package/plugins/freeflow/skills/review-artifact/references/reviewer-prompt.md +45 -0
  43. package/plugins/freeflow/skills/review-work/SKILL.md +73 -0
  44. package/plugins/freeflow/skills/review-work/references/reviewer-prompt.md +89 -0
  45. package/plugins/freeflow/skills/setup-freeflow/SKILL.md +84 -0
  46. package/plugins/freeflow/skills/setup-freeflow/references/activation-contract.md +94 -0
  47. package/plugins/freeflow/skills/setup-freeflow/references/host-setup.md +33 -0
  48. package/plugins/freeflow/skills/verify-work/SKILL.md +62 -0
  49. package/plugins/freeflow/skills/workflow/SKILL.md +87 -0
  50. package/plugins/freeflow/skills/workflow/references/workflow-map.md +103 -0
  51. package/plugins/freeflow/skills/write-plan/SKILL.md +88 -0
  52. package/plugins/freeflow/skills/write-plan/references/plan-shapes.md +70 -0
  53. package/plugins/freeflow/skills/write-skill/SKILL.md +88 -0
  54. package/plugins/freeflow/skills/write-spec/SKILL.md +90 -0
  55. package/plugins/freeflow/skills/write-spec/references/artifact-standards.md +67 -0
  56. package/plugins/freeflow/skills/write-spec/references/spec-shapes.md +69 -0
@@ -0,0 +1,86 @@
1
+ # Architecture
2
+
3
+ Freeflow is a portable skill pack for coding agents.
4
+
5
+ ## Runtime Boundary
6
+
7
+ Freeflow ships Markdown skills, bundled references, lightweight context-loading hooks, and a Pi extension. It does not ship a CLI, Codex/Claude native slash handlers, enforcement hooks, or a new agent runtime in v0.1.
8
+
9
+ Host runtimes still control tools, sandboxing, approvals, and permissions. Freeflow controls workflow pressure:
10
+
11
+ - how much clarification is needed
12
+ - when artifacts are useful
13
+ - when source-truth conflicts stop edits
14
+ - when review and verification are required
15
+ - when a handoff or durable decision is useful
16
+
17
+ ## Package Layout
18
+
19
+ ```text
20
+ freeflow/
21
+ package.json
22
+ .agents/plugins/marketplace.json
23
+ .claude-plugin/marketplace.json
24
+ README.md
25
+ LICENSE
26
+ CHANGELOG.md
27
+ docs/
28
+ plugins/freeflow/
29
+ .codex-plugin/plugin.json
30
+ .claude-plugin/plugin.json
31
+ command-surface.json
32
+ hooks/
33
+ pi-extension/
34
+ skills/
35
+ docs/
36
+ evals/
37
+ ```
38
+
39
+ The repository root is the marketplace and package-facing shell. Codex uses `.agents/plugins/marketplace.json`; Claude uses `.claude-plugin/marketplace.json`. Both point at `plugins/freeflow/`. Pi uses the root `package.json` `pi` manifest to load `plugins/freeflow/skills/` and `plugins/freeflow/pi-extension/index.js`.
40
+
41
+ `plugins/freeflow/` is the single runtime source of truth. Skill edits, bundled references, eval metadata, and command-surface metadata live there to avoid generated package drift.
42
+
43
+ ## Progressive Disclosure
44
+
45
+ Each skill keeps its active `SKILL.md` short. Stable details move into `references/` files only when they prevent bloat, reduce repeated work, or address measured failures.
46
+
47
+ This keeps the model's first-loaded instructions focused on behavior:
48
+
49
+ - trigger
50
+ - loop
51
+ - stop condition
52
+ - failure prevention
53
+
54
+ ## Host Setup
55
+
56
+ `setup-freeflow` installs a compact always-on contract into the host repo.
57
+
58
+ The canonical setup contract lives in `skills/setup-freeflow/references/activation-contract.md`; setup docs, fixtures, and eval assertions should reference it or be checked against it.
59
+
60
+ Codex setup targets `AGENTS.md` and `.freeflow/config.json`.
61
+
62
+ Claude setup targets `CLAUDE.md`, `.claude/rules/freeflow-core.md`, and `.freeflow/config.json` when Claude is the selected host.
63
+
64
+ Setup should not silently update both hosts or overwrite stronger repo-specific rules. Existing repo instructions are source truth.
65
+
66
+ ## Runtime Context Hooks
67
+
68
+ The installed plugin owns `hooks/hooks.json`. Setup does not copy hook files into target repos.
69
+
70
+ The hooks load the existing `workflow` skill, workflow map, and `interview-gate` skill:
71
+
72
+ - at session start, including startup, resume, clear, and compact
73
+
74
+ They also report whether the current repo appears set up, partially set up, or missing setup. They do not run after edit/write tools, block tools, grant permissions, enforce mode policy, or replace repo instructions.
75
+
76
+ Setup handles the same-session case directly: after successful setup verification, it reads the workflow skill, workflow map, and interview-gate skill before its final response and only then says workflow and interview-gate context is loaded.
77
+
78
+ Host runtimes may require plugin hooks to be reviewed and trusted after install. If the host skips untrusted hooks, setup still writes activation/config files, but future session-start runtime context will not load until hooks are trusted and the session is restarted, resumed, cleared, or compacted.
79
+
80
+ Pi uses an extension instead of `hooks/hooks.json`. The Pi extension registers direct commands, reads `workflow/SKILL.md`, `workflow/references/workflow-map.md`, and `interview-gate/SKILL.md`, refreshes that context on `session_start` and `session_compact`, and injects it during Pi's `before_agent_start` lifecycle event. Pi `/workflow` commands set a session-scoped current-mode override, while `.freeflow/config.json` remains the default-mode source. It follows the same boundary as the Codex/Claude hooks: context loading only, no enforcement.
81
+
82
+ ## Deferred Enforcement
83
+
84
+ Enforcement hooks and CLI checks are intentionally deferred. They are useful only after skill wording and evals prove a repeated behavior needs mechanical enforcement.
85
+
86
+ For v0.1, commands are model-routed language such as `/write-spec` or `/verify-work`; they are not native registered slash handlers.
@@ -0,0 +1,49 @@
1
+ # Release Evidence
2
+
3
+ Freeflow v0.1 is based on local fixture evals and release acceptance runs from the development repository.
4
+
5
+ ## Acceptance Summary
6
+
7
+ The local v0.1 acceptance suite passed after measured fixes and was rerun during prepublish verification on 2026-05-26.
8
+
9
+ High-signal behaviors covered:
10
+
11
+ - Source-truth conflicts stop before edits.
12
+ - Strict public API specs ask for owner decisions.
13
+ - Execution stops when verification reveals a bad plan.
14
+ - Commit flow refuses mixed staged sensitive changes.
15
+ - Decision capture asks before inventing memory conventions.
16
+ - Bypass skips ceremony, not judgment.
17
+
18
+ ## Command Surface
19
+
20
+ The development registry covers:
21
+
22
+ - 4 mode commands.
23
+ - 13 direct workflow skill calls.
24
+ - 2 contributor skill calls.
25
+
26
+ Codex/Claude native slash handlers are not shipped in v0.1. In those hosts, commands are model-routed through natural language and skill activation. Pi registers direct Freeflow commands through its extension.
27
+
28
+ ## Runtime Context
29
+
30
+ Freeflow ships plugin-bundled context hooks that load the existing `workflow` skill, workflow map, and `interview-gate` skill at session start. These hooks do not run after edit/write tools, enforce behavior, block tools, or create repo-local hook files.
31
+
32
+ For the same session that runs setup, `setup-freeflow` reads the workflow skill, workflow map, and interview-gate skill after successful setup verification before saying workflow and interview-gate context is loaded.
33
+
34
+ Host trust prompts for plugin hooks are expected host behavior. Local metadata validation checks hook packaging and deterministic output, not end-to-end host trust UI.
35
+
36
+ ## Release Metadata
37
+
38
+ Run `plugins/freeflow/evals/scripts/validate-release-metadata.sh` for local prepublish checks across marketplace metadata, host manifests, command-surface routing, release-boundary docs, package cleanliness, and deferred install-smoke status.
39
+
40
+ Run `plugins/freeflow/evals/scripts/check-runtime-context-hook.sh` after changing lifecycle context hooks.
41
+
42
+ ## Known Deferred Work
43
+
44
+ - Live Claude smoke evals after Hassan confirms Claude testing is available again.
45
+ - GitHub-install smoke tests in separate Codex, Claude, and fresh Pi environments.
46
+ - Enforcement hooks or CLI checks only after repeated behavior failures justify them.
47
+ - Public marketplace submission only after GitHub install works for required hosts.
48
+
49
+ Full eval reports are development evidence and are not included in the runtime package.
@@ -0,0 +1,44 @@
1
+ # Skills
2
+
3
+ Freeflow ships a small workflow skill pack. Natural language is the preferred interface. In Codex/Claude, slash-style phrases work as model-routed skill hints in v0.1; in Pi, the extension registers direct Freeflow commands.
4
+
5
+ ## Core
6
+
7
+ | Skill | Use When |
8
+ | --- | --- |
9
+ | `workflow` | Choosing the next workflow entry point or explaining the full flow. |
10
+ | `mode-contract` | Inferring or switching `conversation`, `workflow`, or `strict-workflow`. |
11
+ | `interview-gate` | Ambiguity or a user-owned decision would change the next action. |
12
+ | `bypass` | Skipping unnecessary ceremony without skipping judgment. |
13
+
14
+ ## Discovery And Artifacts
15
+
16
+ | Skill | Use When |
17
+ | --- | --- |
18
+ | `research-brief` | Repo, domain, evidence, or current facts are unknown. |
19
+ | `grill-context` | Direction is vague and a decision tree needs clarification. |
20
+ | `write-spec` | Agreed requirements or decisions need a durable spec. |
21
+ | `review-artifact` | A spec, plan, handoff, research brief, or decision note must guide future work. |
22
+ | `write-plan` | An approved spec or explicit task context needs executable slices. |
23
+
24
+ ## Execution And Closeout
25
+
26
+ | Skill | Use When |
27
+ | --- | --- |
28
+ | `execute-plan` | An approved plan exists and should be implemented in checked slices. |
29
+ | `diagnose-failure` | Behavior is broken, failing, flaky, slow, or unclear. |
30
+ | `review-work` | A completed diff or review feedback needs bug/risk-focused review. |
31
+ | `verify-work` | Fresh evidence is needed before claiming completion. |
32
+ | `commit-work` | Reviewed, verified, intended work is ready to commit. |
33
+ | `handoff` | Pausing, compacting, transferring context, or preserving continuation memory. |
34
+ | `capture-decisions` | Stable decisions, glossary terms, rejected approaches, or ADR-worthy tradeoffs should be recorded. |
35
+
36
+ ## Contributor Skills
37
+
38
+ | Skill | Use When |
39
+ | --- | --- |
40
+ | `setup-freeflow` | Installing the compact always-on Freeflow contract into a repo. |
41
+ | `write-skill` | Creating or revising concise behavior-shaping skills. |
42
+ | `evaluate-skill` | Turning failures into baseline-vs-with-skill evals and revising from evidence. |
43
+
44
+ These contributor skills are shipped because teams may use Freeflow to install or adapt workflow behavior, but they are not normal workflow states for ordinary feature work.
@@ -0,0 +1,57 @@
1
+ # Workflow
2
+
3
+ Freeflow is a workflow layer, not a new agent. It helps the agent choose the right amount of process for the task.
4
+
5
+ ## Modes
6
+
7
+ - `conversation`: answer, explain, critique, or explore without workflow pressure.
8
+ - `workflow`: default for consequential work; use the workflow spine and scale detail to risk.
9
+ - `strict-workflow`: high-risk or hard-to-reverse work with stronger gates.
10
+
11
+ Use strict-workflow for security, privacy, billing, public APIs, migrations, data loss, compatibility, permissions, deployment, or irreversible architecture.
12
+
13
+ ## Map
14
+
15
+ ```mermaid
16
+ flowchart LR
17
+ Request{request}
18
+ Talk[conversation<br/>answer directly]
19
+ Discover[discover<br/>research / grill]
20
+ Spec[spec]
21
+ Plan[plan]
22
+ Build[build<br/>execute / diagnose]
23
+ Check[review + verify]
24
+ Close[commit / handoff]
25
+
26
+ Request -->|question| Talk
27
+ Request -->|work| Discover
28
+ Discover --> Spec --> Plan --> Build --> Check --> Close
29
+ Check -. new evidence or failed check .-> Discover
30
+ ```
31
+
32
+ The map is orienting, not mandatory. Small reversible work can skip unnecessary artifacts and gates.
33
+
34
+ ## Backward Edge
35
+
36
+ Loop back when new evidence changes the path:
37
+
38
+ ```mermaid
39
+ flowchart LR
40
+ Trigger{new evidence<br/>conflict<br/>failed check<br/>owner decision}
41
+ Decide{changes<br/>next action?}
42
+ Continue[continue]
43
+ Reenter[clarify / research<br/>revise spec or plan<br/>diagnose / split / stop]
44
+
45
+ Trigger --> Decide
46
+ Decide -->|no| Continue
47
+ Decide -->|yes| Reenter
48
+ Reenter -. resume .-> Decide
49
+ ```
50
+
51
+ The agent should not silently choose the backward destination when the choice changes product behavior, scope, compatibility, public APIs, security, privacy, billing, data loss, permissions, or irreversible architecture.
52
+
53
+ ## Bypass
54
+
55
+ Bypass skips ceremony, not judgment.
56
+
57
+ Use `bypass` only to skip an unnecessary gate. It does not skip user-owned decisions, source-truth conflicts, risky checks, or fresh verification before completion claims.
@@ -0,0 +1,240 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import process from "node:process";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
9
+ const PLUGIN_ROOT = path.resolve(SCRIPT_DIR, "..");
10
+ const VALID_MODES = new Set(["conversation", "workflow", "strict-workflow"]);
11
+
12
+ function readStdinJson() {
13
+ const raw = fs.readFileSync(0, "utf8").trim();
14
+ if (!raw) {
15
+ return { input: {}, raw: "" };
16
+ }
17
+
18
+ try {
19
+ return { input: JSON.parse(raw), raw };
20
+ } catch {
21
+ return { input: {}, raw };
22
+ }
23
+ }
24
+
25
+ function readText(filePath) {
26
+ try {
27
+ return fs.readFileSync(filePath, "utf8");
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ function findWorkspaceRoot(cwd) {
34
+ let current = path.resolve(cwd || process.cwd());
35
+
36
+ while (true) {
37
+ if (fs.existsSync(path.join(current, ".git"))) {
38
+ return current;
39
+ }
40
+
41
+ const parent = path.dirname(current);
42
+ if (parent === current) {
43
+ return path.resolve(cwd || process.cwd());
44
+ }
45
+ current = parent;
46
+ }
47
+ }
48
+
49
+ function loadRuntimeContext() {
50
+ const workflowSkill = readText(path.join(PLUGIN_ROOT, "skills", "workflow", "SKILL.md"));
51
+ const workflowMap = readText(
52
+ path.join(PLUGIN_ROOT, "skills", "workflow", "references", "workflow-map.md")
53
+ );
54
+ const interviewGateSkill = readText(
55
+ path.join(PLUGIN_ROOT, "skills", "interview-gate", "SKILL.md")
56
+ );
57
+
58
+ if (!workflowSkill || !workflowMap || !interviewGateSkill) {
59
+ throw new Error("Freeflow runtime context files are missing.");
60
+ }
61
+
62
+ return { workflowSkill, workflowMap, interviewGateSkill };
63
+ }
64
+
65
+ function readConfig(root) {
66
+ const configPath = path.join(root, ".freeflow", "config.json");
67
+ const body = readText(configPath);
68
+ if (!body) {
69
+ return { exists: false, valid: false, defaultMode: null };
70
+ }
71
+
72
+ try {
73
+ const parsed = JSON.parse(body);
74
+ const keys = Object.keys(parsed);
75
+ const valid =
76
+ keys.length === 1 &&
77
+ Object.prototype.hasOwnProperty.call(parsed, "defaultMode") &&
78
+ VALID_MODES.has(parsed.defaultMode);
79
+ return { exists: true, valid, defaultMode: parsed.defaultMode ?? null };
80
+ } catch {
81
+ return { exists: true, valid: false, defaultMode: null };
82
+ }
83
+ }
84
+
85
+ function inspectSetup(root) {
86
+ const config = readConfig(root);
87
+ const agents = readText(path.join(root, "AGENTS.md")) || "";
88
+ const claude = readText(path.join(root, "CLAUDE.md")) || "";
89
+ const claudeRule = readText(path.join(root, ".claude", "rules", "freeflow-core.md")) || "";
90
+
91
+ const codexActive =
92
+ agents.includes("## Freeflow") && agents.includes("Use Freeflow for consequential work");
93
+ const claudeActive =
94
+ claude.includes("@.claude/rules/freeflow-core.md") &&
95
+ claudeRule.includes("Use Freeflow for consequential work");
96
+ const activeHosts = [
97
+ codexActive ? "Codex AGENTS.md" : null,
98
+ claudeActive ? "Claude CLAUDE.md import" : null
99
+ ].filter(Boolean);
100
+
101
+ return { config, activeHosts };
102
+ }
103
+
104
+ function configStatus(config) {
105
+ if (config.valid) {
106
+ return `defaultMode \`${config.defaultMode}\``;
107
+ }
108
+ if (config.exists) {
109
+ return "invalid `.freeflow/config.json`; effective default mode falls back to `workflow`";
110
+ }
111
+ return "missing `.freeflow/config.json`; effective default mode falls back to `workflow`";
112
+ }
113
+
114
+ function modeGuidance(mode) {
115
+ return [
116
+ `Current Freeflow default mode: \`${mode}\`.`,
117
+ "Treat this as the repo default at session start, resume, clear, and compact.",
118
+ "For mode changes or mode interpretation, use `mode-contract`.",
119
+ "Do not announce the current mode on every reply. Mention it when the user asks, setup/config is discussed, or the mode changes the next action."
120
+ ];
121
+ }
122
+
123
+ function buildSetupStatus(root) {
124
+ const setup = inspectSetup(root);
125
+ const parts = [];
126
+ const modeStatus = configStatus(setup.config);
127
+
128
+ if (setup.config.valid && setup.activeHosts.length > 0) {
129
+ parts.push(
130
+ `Setup status: configured for ${setup.activeHosts.join(" and ")} with ${modeStatus}.`
131
+ );
132
+ parts.push(...modeGuidance(setup.config.defaultMode));
133
+ } else if (setup.config.exists || setup.activeHosts.length > 0) {
134
+ const issues = [];
135
+ if (!setup.config.valid) {
136
+ issues.push("valid `.freeflow/config.json` is missing");
137
+ }
138
+ if (setup.activeHosts.length === 0) {
139
+ issues.push("no Freeflow activation block/import was found");
140
+ }
141
+ parts.push(`Setup status: partial setup; ${issues.join(" and ")}.`);
142
+ parts.push(`Repo default mode: ${modeStatus}.`);
143
+ parts.push(
144
+ "Required user-facing notice: in the next assistant reply, tell the user Freeflow setup is incomplete and recommend `/setup-freeflow` or completing the missing host/config setup. Do this even if the user's prompt is casual, such as a greeting."
145
+ );
146
+ parts.push(
147
+ "Before consequential work in this repo, complete setup or ask which host setup to complete unless the user explicitly bypasses setup."
148
+ );
149
+ } else {
150
+ parts.push("Setup status: this repo does not appear to be set up for Freeflow yet.");
151
+ parts.push(`Repo default mode: ${modeStatus}.`);
152
+ parts.push(
153
+ "Required user-facing notice: in the next assistant reply, tell the user Freeflow is installed but this repo is not set up yet, and recommend `/setup-freeflow`. Do this even if the user's prompt is casual, such as a greeting."
154
+ );
155
+ parts.push(
156
+ "Before consequential work in this repo, use `/setup-freeflow` or ask whether to set up Freeflow for Codex, Claude, or both. Do not start implementation solely because the plugin is installed."
157
+ );
158
+ }
159
+
160
+ return parts.join("\n");
161
+ }
162
+
163
+ function shouldInject(eventName) {
164
+ if (process.env.FREEFLOW_DISABLE_RUNTIME_CONTEXT === "1") {
165
+ return false;
166
+ }
167
+
168
+ return eventName === "SessionStart";
169
+ }
170
+
171
+ function buildContext(input) {
172
+ const root = findWorkspaceRoot(input.cwd || process.cwd());
173
+ const { workflowSkill, workflowMap, interviewGateSkill } = loadRuntimeContext();
174
+
175
+ return [
176
+ "# Freeflow Runtime Context",
177
+ "",
178
+ "Freeflow plugin lifecycle hook loaded this at session start.",
179
+ "These instructions are context-loading only. They do not override user instructions, repo instructions, or host safety and approval policy.",
180
+ "",
181
+ "## Repo Setup",
182
+ buildSetupStatus(root),
183
+ "",
184
+ "## Loaded Workflow Skill",
185
+ "```md",
186
+ workflowSkill.trim(),
187
+ "```",
188
+ "",
189
+ "## Loaded Interview Gate Skill",
190
+ "```md",
191
+ interviewGateSkill.trim(),
192
+ "```",
193
+ "",
194
+ "## Loaded Workflow Map",
195
+ "```md",
196
+ workflowMap.trim(),
197
+ "```"
198
+ ].join("\n");
199
+ }
200
+
201
+ function isCodexHookInput(input) {
202
+ return typeof input.model === "string" && input.model.length > 0;
203
+ }
204
+
205
+ function emitAdditionalContext(eventName, input, additionalContext) {
206
+ if (isCodexHookInput(input)) {
207
+ process.stdout.write(`${additionalContext}\n`);
208
+ return;
209
+ }
210
+
211
+ process.stdout.write(
212
+ `${JSON.stringify({
213
+ hookSpecificOutput: {
214
+ hookEventName: eventName,
215
+ additionalContext
216
+ }
217
+ })}\n`
218
+ );
219
+ }
220
+
221
+ function main() {
222
+ const { input, raw } = readStdinJson();
223
+ const eventName = process.argv[2] || input.hook_event_name || "";
224
+
225
+ if (!raw && !eventName) {
226
+ return;
227
+ }
228
+
229
+ if (!shouldInject(eventName)) {
230
+ return;
231
+ }
232
+
233
+ emitAdditionalContext(eventName, input, buildContext(input));
234
+ }
235
+
236
+ try {
237
+ main();
238
+ } catch (error) {
239
+ process.stderr.write(`Freeflow runtime context hook skipped: ${error.message}\n`);
240
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "description": "Load Freeflow runtime context at session start.",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "matcher": "startup|resume|clear|compact",
7
+ "hooks": [
8
+ {
9
+ "type": "command",
10
+ "command": "node \"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT}}/hooks/freeflow-runtime-context.mjs\" SessionStart",
11
+ "timeout": 5,
12
+ "statusMessage": "Loading Freeflow context"
13
+ }
14
+ ]
15
+ }
16
+ ]
17
+ }
18
+ }