@sriinnu/harmon-flow 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 (61) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +79 -0
  3. package/SKILL.md +44 -0
  4. package/dist/graph/index.d.ts +116 -0
  5. package/dist/graph/index.d.ts.map +1 -0
  6. package/dist/graph/index.js +484 -0
  7. package/dist/graph/index.js.map +1 -0
  8. package/dist/index.d.ts +9 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +10 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/mcp/app-server.d.ts +66 -0
  13. package/dist/mcp/app-server.d.ts.map +1 -0
  14. package/dist/mcp/app-server.js +682 -0
  15. package/dist/mcp/app-server.js.map +1 -0
  16. package/dist/mcp/auth.d.ts +37 -0
  17. package/dist/mcp/auth.d.ts.map +1 -0
  18. package/dist/mcp/auth.js +156 -0
  19. package/dist/mcp/auth.js.map +1 -0
  20. package/dist/mcp/cli.d.ts +8 -0
  21. package/dist/mcp/cli.d.ts.map +1 -0
  22. package/dist/mcp/cli.js +84 -0
  23. package/dist/mcp/cli.js.map +1 -0
  24. package/dist/mcp/daemon-client.d.ts +89 -0
  25. package/dist/mcp/daemon-client.d.ts.map +1 -0
  26. package/dist/mcp/daemon-client.js +400 -0
  27. package/dist/mcp/daemon-client.js.map +1 -0
  28. package/dist/mcp/http-utils.d.ts +13 -0
  29. package/dist/mcp/http-utils.d.ts.map +1 -0
  30. package/dist/mcp/http-utils.js +23 -0
  31. package/dist/mcp/http-utils.js.map +1 -0
  32. package/dist/mcp/index.d.ts +90 -0
  33. package/dist/mcp/index.d.ts.map +1 -0
  34. package/dist/mcp/index.js +602 -0
  35. package/dist/mcp/index.js.map +1 -0
  36. package/dist/mcp/journal-search.d.ts +31 -0
  37. package/dist/mcp/journal-search.d.ts.map +1 -0
  38. package/dist/mcp/journal-search.js +90 -0
  39. package/dist/mcp/journal-search.js.map +1 -0
  40. package/dist/mcp/tool-auth.d.ts +14 -0
  41. package/dist/mcp/tool-auth.d.ts.map +1 -0
  42. package/dist/mcp/tool-auth.js +25 -0
  43. package/dist/mcp/tool-auth.js.map +1 -0
  44. package/dist/parser/frontmatter.d.ts +11 -0
  45. package/dist/parser/frontmatter.d.ts.map +1 -0
  46. package/dist/parser/frontmatter.js +28 -0
  47. package/dist/parser/frontmatter.js.map +1 -0
  48. package/dist/parser/index.d.ts +53 -0
  49. package/dist/parser/index.d.ts.map +1 -0
  50. package/dist/parser/index.js +178 -0
  51. package/dist/parser/index.js.map +1 -0
  52. package/dist/types.d.ts +197 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/dist/types.js +38 -0
  55. package/dist/types.js.map +1 -0
  56. package/dist/version.d.ts +8 -0
  57. package/dist/version.d.ts.map +1 -0
  58. package/dist/version.js +21 -0
  59. package/dist/version.js.map +1 -0
  60. package/logo.svg +13 -0
  61. package/package.json +65 -0
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # @sriinnu/harmon-flow
2
+
3
+ ![logo](./logo.svg)
4
+
5
+ > Graph-based journal analysis plus MCP servers for local tooling and remote OpenAI/ChatGPT app integration.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @sriinnu/harmon-flow
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import {
17
+ createFlowParser,
18
+ PatternGraphBuilder,
19
+ PatternDetector,
20
+ SuggestionEngine,
21
+ } from '@sriinnu/harmon-flow';
22
+
23
+ const parser = createFlowParser('./journal');
24
+ const entries = parser.scanDirectory();
25
+ const graph = new PatternGraphBuilder(entries).build();
26
+ const patterns = new PatternDetector(graph, entries).getAllPatterns();
27
+ const suggestions = new SuggestionEngine(graph, entries).suggest(
28
+ ['focused'],
29
+ 'medium',
30
+ 'morning',
31
+ );
32
+ ```
33
+
34
+ ## API
35
+
36
+ | Export | Description |
37
+ |---|---|
38
+ | `createFlowParser()` | Markdown journal parser |
39
+ | `MarkdownParser` | Parser class for journal files with schema-validated frontmatter |
40
+ | `PatternGraphBuilder` | Build a pattern graph from journal entries |
41
+ | `PatternDetector` | Detect recurring patterns (time, mood, policy) |
42
+ | `SuggestionEngine` | Generate session suggestions from patterns |
43
+ | `createMCPServer()` | Start an MCP stdio server for flow analysis |
44
+ | `createAppMCPServer()` | Start a remote streamable HTTP MCP server for OpenAI/ChatGPT app use |
45
+ | `HarmonAppMCPServer` | Remote MCP app server class with daemon-backed runtime tools |
46
+ | `JournalEntry` | Parsed journal entry type |
47
+ | `PatternGraph` / `GraphNode` / `GraphEdge` | Graph structure types |
48
+ | `Suggestion` | Generated suggestion type |
49
+
50
+ ## Server Modes
51
+
52
+ From a fresh repo checkout, run `pnpm build` once before you start either server.
53
+
54
+ ```bash
55
+ # Local stdio MCP server
56
+ pnpm --filter @sriinnu/harmon-flow start
57
+
58
+ # Remote streamable HTTP MCP server
59
+ pnpm --filter @sriinnu/harmon-flow start:http
60
+ ```
61
+
62
+ The remote MCP server exposes:
63
+
64
+ - `search` and `fetch` for ChatGPT-compatible journal retrieval
65
+ - `get_status`, `search_music`, `get_library_tracks`, `list_playlists`, `get_playlist_tracks`, and `get_now_playing` for daemon/runtime reads
66
+ - `play_music`, `pause_music`, `next_track`, and `previous_track` for direct provider playback control
67
+ - `start_session`, `nudge_session`, and `stop_session` for session orchestration
68
+
69
+ Set `HARMON_ENDPOINT` to point at the daemon. If the daemon is protected, also set `HARMON_API_TOKEN` so the MCP server can authenticate upstream. Set `HARMON_MCP_BEARER_TOKEN` if you want bearer auth on the remote MCP endpoint. Without MCP auth, the remote server stays read-only by default. The default remote URL is `http://127.0.0.1:17400/mcp`.
70
+ If you need bearer-backed write tools, either set `HARMON_MCP_BEARER_TOKEN_SCOPES="harmon.read harmon.write"` or use OAuth JWT auth. `HARMON_MCP_ALLOW_UNAUTHENTICATED_WRITES=1` is available only for local development on loopback binds like `127.0.0.1`.
71
+ For OAuth-capable protected deployments, set `HARMON_MCP_OAUTH_ISSUER_URL`, `HARMON_MCP_OAUTH_AUTHORIZATION_ENDPOINT`, `HARMON_MCP_OAUTH_TOKEN_ENDPOINT`, `HARMON_MCP_OAUTH_JWKS_URL`, and `HARMON_MCP_PUBLIC_URL`. I fail fast without `HARMON_MCP_PUBLIC_URL` so the protected-resource metadata cannot accidentally advertise a local bind URL.
72
+
73
+ ## Architecture
74
+
75
+ harmon-flow reads markdown journal entries, validates frontmatter metadata (mood, energy, context) against its declared schema, and builds an in-memory graph of patterns. The `SuggestionEngine` traverses this graph to recommend session policies based on time-of-day, mood history, and past listening behavior. It now exposes two MCP surfaces: a local stdio server for journal-analysis tools, and a remote streamable HTTP server that combines journal `search`/`fetch` tools with daemon-backed multi-provider runtime control for OpenAI/ChatGPT app use.
76
+
77
+ ## License
78
+
79
+ GNU Affero General Public License v3.0 only. See [LICENSE](../../LICENSE).
package/SKILL.md ADDED
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: harmon-flow
3
+ description: Journal pattern detection, graph analysis, and MCP server for music session insights
4
+ capabilities:
5
+ - Parse markdown journal entries with frontmatter into structured data
6
+ - Build pattern graphs from journal entries and detect time, mood, and policy patterns
7
+ - Expose pattern analysis as an MCP server with tool definitions for LLM integration
8
+ tags:
9
+ - patterns
10
+ - journal
11
+ - mcp
12
+ - analysis
13
+ provider: harmon
14
+ version: 0.1.0
15
+ ---
16
+
17
+ # Harmon Flow
18
+
19
+ ## What this does
20
+ harmon-flow turns markdown journal entries into a queryable pattern graph. The MarkdownParser extracts and validates frontmatter (mood tags, energy level, session context, policy) from journal files. The PatternGraphBuilder constructs a directed graph of nodes and edges representing relationships between moods, energy levels, times, and policies. A PatternDetector finds recurring patterns, and the SuggestionEngine recommends session policies. The whole system is exposed as an MCP server for LLM tool use.
21
+
22
+ ## When to use
23
+ - Analyzing journal history to find recurring mood-energy-time patterns
24
+ - Generating session policy suggestions based on past listening behavior
25
+ - Exposing harmon insights as MCP tools for Claude or other LLM agents
26
+
27
+ ## Key exports
28
+ - `MarkdownParser` — parses markdown files with YAML frontmatter into JournalEntry objects
29
+ - `PatternGraphBuilder` — builds a graph of mood, energy, time, and policy nodes with weighted edges
30
+ - `HarmonFlowMCPServer` — MCP server that exposes pattern analysis as callable tools
31
+
32
+ ## Example
33
+ ```typescript
34
+ import {
35
+ MarkdownParser,
36
+ PatternGraphBuilder,
37
+ createMCPServer,
38
+ } from '@sriinnu/harmon-flow';
39
+
40
+ const parser = new MarkdownParser({ path: './journals' });
41
+ const entries = parser.scanDirectory();
42
+ const graph = new PatternGraphBuilder(entries).build();
43
+ const server = await createMCPServer({ flowDir: './journals' });
44
+ ```
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Pattern Graph - Build and query graph-based patterns from journal entries
3
+ */
4
+ import type { JournalEntry, PatternGraph, TimePattern, MoodEnergyPattern, PolicyPattern, Suggestion } from '../types.js';
5
+ export declare class PatternGraphBuilder {
6
+ private graph;
7
+ private entries;
8
+ constructor(entries: JournalEntry[]);
9
+ /**
10
+ * Build the complete pattern graph from entries
11
+ */
12
+ build(): PatternGraph;
13
+ /**
14
+ * Add nodes for an entry
15
+ */
16
+ private addEntryNodes;
17
+ /**
18
+ * Add edges for an entry (temporal relationships)
19
+ */
20
+ private addEntryEdges;
21
+ /**
22
+ * Add a node to the graph
23
+ */
24
+ private addNode;
25
+ /**
26
+ * Add an edge to the graph
27
+ */
28
+ private addEdge;
29
+ /**
30
+ * Normalize edge weights by max count
31
+ */
32
+ private normalizeEdgeWeights;
33
+ /**
34
+ * Find the previous entry in chronological order
35
+ */
36
+ private findPreviousEntry;
37
+ private getNodeKey;
38
+ /**
39
+ * Get the built graph
40
+ */
41
+ getGraph(): PatternGraph;
42
+ }
43
+ /**
44
+ * Pattern Detector - Extract high-level patterns from the graph
45
+ */
46
+ export declare class PatternDetector {
47
+ private graph;
48
+ private entries;
49
+ constructor(graph: PatternGraph, entries: JournalEntry[]);
50
+ /**
51
+ * Detect time-based patterns
52
+ */
53
+ detectTimePatterns(): TimePattern[];
54
+ /**
55
+ * Detect mood-energy transition patterns
56
+ */
57
+ detectMoodEnergyPatterns(): MoodEnergyPattern[];
58
+ /**
59
+ * Cluster similar policies to find patterns
60
+ */
61
+ detectPolicyPatterns(): PolicyPattern[];
62
+ /**
63
+ * Simple hash function for policy objects
64
+ */
65
+ private hashPolicy;
66
+ /**
67
+ * Get all detected patterns
68
+ */
69
+ getAllPatterns(): {
70
+ timePatterns: TimePattern[];
71
+ moodEnergyPatterns: MoodEnergyPattern[];
72
+ policyPatterns: PolicyPattern[];
73
+ };
74
+ }
75
+ /**
76
+ * Suggestion Engine - Generate suggestions based on patterns
77
+ */
78
+ export declare class SuggestionEngine {
79
+ private graph;
80
+ private entries;
81
+ private timePatterns;
82
+ private moodEnergyPatterns;
83
+ private policyPatterns;
84
+ constructor(graph: PatternGraph, entries: JournalEntry[]);
85
+ /**
86
+ * Generate suggestions based on current context
87
+ */
88
+ suggest(currentMood: string[], energy: 'low' | 'medium' | 'high', timeOfDay?: string): Suggestion[];
89
+ /**
90
+ * Get similar historical entries
91
+ */
92
+ findSimilarEntries(mood: string[], energy?: 'low' | 'medium' | 'high', limit?: number): Array<{
93
+ entry: JournalEntry;
94
+ similarity: number;
95
+ }>;
96
+ /**
97
+ * Get pattern statistics
98
+ */
99
+ getStats(): {
100
+ totalEntries: number;
101
+ timePatterns: number;
102
+ moodEnergyPatterns: number;
103
+ policyPatterns: number;
104
+ topMoodTags: {
105
+ mood: string;
106
+ count: number;
107
+ }[];
108
+ topEnergyLevels: {
109
+ level: string;
110
+ count: number;
111
+ }[];
112
+ };
113
+ private getTopMoodTags;
114
+ private getTopEnergyLevels;
115
+ }
116
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EAGZ,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,UAAU,EACX,MAAM,aAAa,CAAC;AAuBrB,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;gBAEpB,OAAO,EAAE,YAAY,EAAE;IASnC;;OAEG;IACH,KAAK,IAAI,YAAY;IAsBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IA2DrB;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,OAAO;IAqBf;;OAEG;IACH,OAAO,CAAC,OAAO;IAkBf;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACH,QAAQ,IAAI,YAAY;CAGzB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;gBAEpB,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE;IAKxD;;OAEG;IACH,kBAAkB,IAAI,WAAW,EAAE;IA+CnC;;OAEG;IACH,wBAAwB,IAAI,iBAAiB,EAAE;IA2C/C;;OAEG;IACH,oBAAoB,IAAI,aAAa,EAAE;IAyCvC;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB;;OAEG;IACH,cAAc;;;;;CAOf;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,kBAAkB,CAAsB;IAChD,OAAO,CAAC,cAAc,CAAkB;gBAE5B,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE;IAUxD;;OAEG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAiEnG;;OAEG;IACH,kBAAkB,CAChB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,EAClC,KAAK,SAAI,GACR,KAAK,CAAC;QAAE,KAAK,EAAE,YAAY,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAsBrD;;OAEG;IACH,QAAQ;;;;;;kBAWgC,MAAM;mBAAS,MAAM;;;mBAahB,MAAM;mBAAS,MAAM;;;IAblE,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,kBAAkB;CAW3B"}