coaiajs 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 (162) hide show
  1. package/CLAUDE.md +56 -0
  2. package/KINSHIP.md +63 -0
  3. package/README.md +148 -0
  4. package/articles/academic/creative-orientation-vs-problem-solving.md +177 -0
  5. package/articles/academic/jsonl-knowledge-graphs-agent-memory.md +142 -0
  6. package/articles/academic/langfuse-observability-llm-pipelines.md +144 -0
  7. package/articles/academic/medicine-wheel-software-architecture.md +163 -0
  8. package/articles/academic/mmot-autonomous-agents.md +156 -0
  9. package/articles/academic/model-context-protocol-interagent.md +161 -0
  10. package/articles/academic/pde-prompt-decomposition.md +186 -0
  11. package/articles/academic/structural-tension-in-ai-agents.md +134 -0
  12. package/articles/reviews/mcp-protocol-design-review.md +170 -0
  13. package/articles/reviews/observability-ai-systems-review.md +176 -0
  14. package/articles/reviews/prompt-engineering-decomposition-review.md +184 -0
  15. package/articles/surveys/agent-orchestration-survey.md +186 -0
  16. package/articles/surveys/knowledge-graph-storage-survey.md +204 -0
  17. package/articles/surveys/structural-tension-methodology-survey.md +154 -0
  18. package/articles/technical/aws-sdk-v3-polly.md +270 -0
  19. package/articles/technical/commander-cli-framework.md +262 -0
  20. package/articles/technical/dotenv-config-patterns.md +360 -0
  21. package/articles/technical/ioredis-vs-redis.md +142 -0
  22. package/articles/technical/langfuse-js-sdk-vs-rest.md +191 -0
  23. package/articles/technical/mcp-sdk-typescript.md +291 -0
  24. package/articles/technical/octokit-github-api.md +293 -0
  25. package/articles/technical/openai-sdk-modern.md +231 -0
  26. package/articles/technical/yaml-parsing-node.md +266 -0
  27. package/articles/technical/zod-runtime-validation.md +212 -0
  28. package/dist/mcp/config.d.ts +14 -0
  29. package/dist/mcp/config.js +185 -0
  30. package/dist/mcp/server.d.ts +3 -0
  31. package/dist/mcp/server.js +324 -0
  32. package/dist/mcp/tools/coaiapy-tools.d.ts +8 -0
  33. package/dist/mcp/tools/coaiapy-tools.js +326 -0
  34. package/dist/mcp/tools/index.d.ts +3 -0
  35. package/dist/mcp/tools/index.js +3 -0
  36. package/dist/src/audio.d.ts +12 -0
  37. package/dist/src/audio.js +57 -0
  38. package/dist/src/cli-helpers.d.ts +9 -0
  39. package/dist/src/cli-helpers.js +78 -0
  40. package/dist/src/cli.d.ts +3 -0
  41. package/dist/src/cli.js +1086 -0
  42. package/dist/src/config.d.ts +15 -0
  43. package/dist/src/config.js +145 -0
  44. package/dist/src/environment.d.ts +44 -0
  45. package/dist/src/environment.js +146 -0
  46. package/dist/src/github.d.ts +47 -0
  47. package/dist/src/github.js +79 -0
  48. package/dist/src/langfuse/client.d.ts +30 -0
  49. package/dist/src/langfuse/client.js +75 -0
  50. package/dist/src/langfuse/comments.d.ts +16 -0
  51. package/dist/src/langfuse/comments.js +36 -0
  52. package/dist/src/langfuse/datasets.d.ts +19 -0
  53. package/dist/src/langfuse/datasets.js +140 -0
  54. package/dist/src/langfuse/index.d.ts +13 -0
  55. package/dist/src/langfuse/index.js +10 -0
  56. package/dist/src/langfuse/media.d.ts +11 -0
  57. package/dist/src/langfuse/media.js +167 -0
  58. package/dist/src/langfuse/observations.d.ts +18 -0
  59. package/dist/src/langfuse/observations.js +113 -0
  60. package/dist/src/langfuse/prompts.d.ts +14 -0
  61. package/dist/src/langfuse/prompts.js +127 -0
  62. package/dist/src/langfuse/scores.d.ts +54 -0
  63. package/dist/src/langfuse/scores.js +366 -0
  64. package/dist/src/langfuse/traces.d.ts +29 -0
  65. package/dist/src/langfuse/traces.js +225 -0
  66. package/dist/src/llm.d.ts +23 -0
  67. package/dist/src/llm.js +76 -0
  68. package/dist/src/narrative/graph-manager.d.ts +106 -0
  69. package/dist/src/narrative/graph-manager.js +915 -0
  70. package/dist/src/narrative/index.d.ts +9 -0
  71. package/dist/src/narrative/index.js +7 -0
  72. package/dist/src/narrative/markdown-export.d.ts +21 -0
  73. package/dist/src/narrative/markdown-export.js +383 -0
  74. package/dist/src/narrative/tool-definitions.d.ts +21 -0
  75. package/dist/src/narrative/tool-definitions.js +588 -0
  76. package/dist/src/narrative/tool-handlers.d.ts +11 -0
  77. package/dist/src/narrative/tool-handlers.js +462 -0
  78. package/dist/src/narrative/types.d.ts +2 -0
  79. package/dist/src/narrative/types.js +2 -0
  80. package/dist/src/narrative/validation.d.ts +29 -0
  81. package/dist/src/narrative/validation.js +144 -0
  82. package/dist/src/pde/index.d.ts +8 -0
  83. package/dist/src/pde/index.js +8 -0
  84. package/dist/src/pde/mcp-handlers.d.ts +7 -0
  85. package/dist/src/pde/mcp-handlers.js +300 -0
  86. package/dist/src/pde/mcp-tools.d.ts +15 -0
  87. package/dist/src/pde/mcp-tools.js +191 -0
  88. package/dist/src/pde/session-manager.d.ts +32 -0
  89. package/dist/src/pde/session-manager.js +205 -0
  90. package/dist/src/pde/stc-mapper.d.ts +26 -0
  91. package/dist/src/pde/stc-mapper.js +234 -0
  92. package/dist/src/pipeline/index.d.ts +2 -0
  93. package/dist/src/pipeline/index.js +3 -0
  94. package/dist/src/pipeline/template-engine.d.ts +20 -0
  95. package/dist/src/pipeline/template-engine.js +361 -0
  96. package/dist/src/planning/index.d.ts +7 -0
  97. package/dist/src/planning/index.js +7 -0
  98. package/dist/src/planning/mcp-handlers.d.ts +7 -0
  99. package/dist/src/planning/mcp-handlers.js +310 -0
  100. package/dist/src/planning/mcp-tools.d.ts +15 -0
  101. package/dist/src/planning/mcp-tools.js +145 -0
  102. package/dist/src/planning/plan-parser.d.ts +35 -0
  103. package/dist/src/planning/plan-parser.js +506 -0
  104. package/dist/src/redis.d.ts +21 -0
  105. package/dist/src/redis.js +78 -0
  106. package/dist/src/types.d.ts +244 -0
  107. package/dist/src/types.js +8 -0
  108. package/mcp/config.ts +196 -0
  109. package/mcp/server.ts +402 -0
  110. package/mcp/tools/coaiapy-tools.ts +364 -0
  111. package/mcp/tools/index.ts +4 -0
  112. package/package.json +52 -0
  113. package/rispecs/00-coaiajs-platform.spec.md +102 -0
  114. package/rispecs/01-core-config.spec.md +89 -0
  115. package/rispecs/02-redis-module.spec.md +62 -0
  116. package/rispecs/03-langfuse-module.spec.md +101 -0
  117. package/rispecs/04-narrative-engine.spec.md +185 -0
  118. package/rispecs/05-pde-engine.spec.md +112 -0
  119. package/rispecs/06-planning-engine.spec.md +128 -0
  120. package/rispecs/07-pipeline-templates.spec.md +97 -0
  121. package/rispecs/08-cli-interface.spec.md +134 -0
  122. package/rispecs/09-mcp-server.spec.md +140 -0
  123. package/rispecs/10-audio-module.spec.md +63 -0
  124. package/rispecs/KINSHIP.md +56 -0
  125. package/rispecs/README.md +100 -0
  126. package/src/audio.ts +76 -0
  127. package/src/cli-helpers.ts +86 -0
  128. package/src/cli.ts +1223 -0
  129. package/src/config.ts +172 -0
  130. package/src/environment.ts +171 -0
  131. package/src/github.ts +143 -0
  132. package/src/langfuse/client.ts +105 -0
  133. package/src/langfuse/comments.ts +52 -0
  134. package/src/langfuse/datasets.ts +178 -0
  135. package/src/langfuse/index.ts +33 -0
  136. package/src/langfuse/media.ts +193 -0
  137. package/src/langfuse/observations.ts +131 -0
  138. package/src/langfuse/prompts.ts +157 -0
  139. package/src/langfuse/scores.ts +456 -0
  140. package/src/langfuse/traces.ts +276 -0
  141. package/src/llm.ts +106 -0
  142. package/src/narrative/graph-manager.ts +1358 -0
  143. package/src/narrative/index.ts +32 -0
  144. package/src/narrative/markdown-export.ts +535 -0
  145. package/src/narrative/tool-definitions.ts +635 -0
  146. package/src/narrative/tool-handlers.ts +528 -0
  147. package/src/narrative/types.ts +9 -0
  148. package/src/narrative/validation.ts +179 -0
  149. package/src/pde/index.ts +8 -0
  150. package/src/pde/mcp-handlers.ts +359 -0
  151. package/src/pde/mcp-tools.ts +201 -0
  152. package/src/pde/session-manager.ts +248 -0
  153. package/src/pde/stc-mapper.ts +298 -0
  154. package/src/pipeline/index.ts +7 -0
  155. package/src/pipeline/template-engine.ts +398 -0
  156. package/src/planning/index.ts +13 -0
  157. package/src/planning/mcp-handlers.ts +369 -0
  158. package/src/planning/mcp-tools.ts +155 -0
  159. package/src/planning/plan-parser.ts +587 -0
  160. package/src/redis.ts +97 -0
  161. package/src/types.ts +280 -0
  162. package/tsconfig.json +26 -0
@@ -0,0 +1,134 @@
1
+ # 08 — CLI Interface
2
+
3
+ > Unified `coaia` command with subcommands for all modules.
4
+
5
+ ## Desired Outcome
6
+
7
+ A single `coaia` CLI binary that provides subcommands for every CoAiA module — replacing the separate CLIs in coaiapy (argparse-based) and coaia-narrative (minimist-based) with a unified commander-based interface.
8
+
9
+ ## Structural Tension
10
+
11
+ **Current Reality:**
12
+ - CLI entry point defined in `package.json` as `"coaia": "./dist/src/cli.js"` but no implementation exists
13
+ - commander dependency is installed
14
+ - coaiapy has an argparse-based CLI covering: tash, fetch, env, pipeline, transcribe, synthesize, fuse, gh
15
+ - coaia-narrative has a minimist-based CLI covering: chart visualization, markdown export, progress display
16
+ - coaia-pde has no CLI
17
+ - coaia-planning has no CLI
18
+
19
+ **Desired Outcome:**
20
+ Unified CLI at `src/cli.ts` using commander, with subcommands:
21
+
22
+ ```
23
+ coaia tash <key> <value> [--ttl N]
24
+ coaia fetch <key>
25
+ coaia env [list|get|set|unset|init]
26
+ coaia fuse [traces|trace|prompts|scores|datasets]
27
+ coaia pipeline [list|render|execute] <template>
28
+ coaia transcribe <audio-file>
29
+ coaia synthesize <text> --output <file>
30
+ coaia gh [issues|issue|comments]
31
+ coaia narrative [charts|chart|progress|export]
32
+ coaia pde [decompose|list|get|export|to-stc]
33
+ coaia plan [parse|to-stc|from-stc|sync|diff]
34
+ coaia mcp [start|tools]
35
+ ```
36
+
37
+ ## Core Structure
38
+
39
+ ```typescript
40
+ import { Command } from 'commander';
41
+
42
+ const program = new Command()
43
+ .name('coaia')
44
+ .version(pkg.version)
45
+ .description('CoAiA unified CLI');
46
+
47
+ // Register subcommands
48
+ program.addCommand(redisCommands());
49
+ program.addCommand(envCommands());
50
+ program.addCommand(fuseCommands());
51
+ program.addCommand(pipelineCommands());
52
+ program.addCommand(audioCommands());
53
+ program.addCommand(ghCommands());
54
+ program.addCommand(narrativeCommands());
55
+ program.addCommand(pdeCommands());
56
+ program.addCommand(planCommands());
57
+ program.addCommand(mcpCommands());
58
+ ```
59
+
60
+ ## Command Details
61
+
62
+ ### Redis Commands
63
+ ```
64
+ coaia tash <key> <value> [--ttl N] # Set key with optional TTL
65
+ coaia fetch <key> # Get value by key
66
+ coaia del <key> # Delete key
67
+ coaia keys [pattern] # List keys matching pattern
68
+ ```
69
+
70
+ ### Environment Commands
71
+ ```
72
+ coaia env init # Create .coaia-env file
73
+ coaia env list # Show all env vars
74
+ coaia env get <key> # Get specific var
75
+ coaia env set <key> <value> # Set env var
76
+ coaia env unset <key> # Remove env var
77
+ ```
78
+
79
+ ### Langfuse Commands
80
+ ```
81
+ coaia fuse traces [--limit N] # List traces
82
+ coaia fuse trace <id> # Get trace details
83
+ coaia fuse prompts [--name X] # List prompts
84
+ coaia fuse scores [--trace-id X] # List scores
85
+ coaia fuse datasets # List datasets
86
+ ```
87
+
88
+ ### Narrative Commands
89
+ ```
90
+ coaia narrative charts # List all active charts
91
+ coaia narrative chart <id> # Show chart details
92
+ coaia narrative progress <id> # Show chart progress
93
+ coaia narrative export <id> [--format md|json] # Export chart
94
+ ```
95
+
96
+ ### PDE Commands
97
+ ```
98
+ coaia pde decompose <prompt> # Decompose a prompt
99
+ coaia pde list # List decompositions
100
+ coaia pde get <id> # Get decomposition
101
+ coaia pde export <id> # Export as markdown
102
+ coaia pde to-stc <id> # Transform to STC
103
+ ```
104
+
105
+ ### Plan Commands
106
+ ```
107
+ coaia plan parse <file> # Parse plan markdown
108
+ coaia plan to-stc <file> # Convert plan to STC
109
+ coaia plan from-stc <chart-id> # Generate plan from STC
110
+ coaia plan sync <file> <chart-id> # Bidirectional sync
111
+ coaia plan diff <file> <chart-id> # Show differences
112
+ ```
113
+
114
+ ### MCP Commands
115
+ ```
116
+ coaia mcp start [--mode MINIMAL|STANDARD|FULL] # Start MCP server
117
+ coaia mcp tools [--mode X] # List available tools
118
+ ```
119
+
120
+ ## Output Formatting
121
+
122
+ - Use `chalk` for colored terminal output
123
+ - JSON output available via `--json` global flag
124
+ - Quiet mode via `--quiet` global flag (exit code only)
125
+ - Error output to stderr, data to stdout
126
+
127
+ ## Quality Criteria
128
+
129
+ - ✅ Every coaiapy CLI command has an equivalent subcommand
130
+ - ✅ `coaia --help` shows all subcommands with descriptions
131
+ - ✅ `coaia <subcommand> --help` shows subcommand-specific help
132
+ - ✅ Exit code 0 on success, 1 on error
133
+ - ✅ `--json` flag produces machine-parseable output for every command
134
+ - ✅ Works in pipe context (no TTY-dependent formatting when piped)
@@ -0,0 +1,140 @@
1
+ # 09 — MCP Server
2
+
3
+ > Unified MCP server exposing 64+ tools from all modules with feature gating.
4
+
5
+ ## Desired Outcome
6
+
7
+ A single MCP server (`coaiajs-mcp`) that consolidates the 44 tools from coaia-narrative (27), coaia-pde (12), and coaia-planning (5) into one server, adds 20 new tools for Redis, Langfuse, pipeline, and audio, and supports feature gating so resource-constrained environments can load only what they need.
8
+
9
+ ## Structural Tension
10
+
11
+ **Current Reality:**
12
+ - MCP server entry defined in `package.json` as `"coaiajs-mcp": "./dist/mcp/server.js"` but `mcp/` directory is empty (only a `tools/` subdirectory stub)
13
+ - `@modelcontextprotocol/sdk` v1.25.0 is installed as a dependency
14
+ - Four separate MCP servers exist in parent projects:
15
+ - coaia-narrative: 27 tools (STC lifecycle, knowledge graph, narrative beats, MMOT)
16
+ - coaia-pde: 12 tools (decomposition, session management, STC transformation)
17
+ - coaia-planning: 5 tools (plan parsing, plan↔STC sync, PDE bridge)
18
+ - coaiapy: 0 MCP tools (Python library only, no MCP)
19
+ - Each parent server has its own startup, tool registration, and transport handling
20
+ - Users currently need 3 MCP server entries in their config to access all tools
21
+
22
+ **Desired Outcome:**
23
+ Single MCP server at `mcp/server.ts` providing:
24
+ - All 44 parent tools with identical schemas and behavior
25
+ - 20 new tools for previously-CLI-only functionality
26
+ - Feature gating via `COAIAJS_MCP_MODE` environment variable
27
+ - Single server entry in MCP client config
28
+
29
+ ## Feature Gating
30
+
31
+ ```typescript
32
+ type McpMode = 'MINIMAL' | 'STANDARD' | 'FULL';
33
+ ```
34
+
35
+ | Mode | Tools loaded | Use case |
36
+ |------|-------------|----------|
37
+ | **MINIMAL** | STC tools (11), KG tools (9), MMOT (2), narrative beats (3) = **25** | Memory-constrained agents, basic STC workflow |
38
+ | **STANDARD** | MINIMAL + PDE (12) + planning (6) + Redis (5) = **48** | Standard development sessions |
39
+ | **FULL** | STANDARD + Langfuse (8) + pipeline (3) + audio (2) + guidance (3) = **64** | Full-featured agent sessions |
40
+
41
+ Default mode: `STANDARD`.
42
+
43
+ ## Server Architecture
44
+
45
+ ```typescript
46
+ // mcp/server.ts
47
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
48
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
49
+
50
+ const server = new McpServer({
51
+ name: 'coaiajs-mcp',
52
+ version: pkg.version
53
+ });
54
+
55
+ // Register tools based on mode
56
+ const mode = (process.env.COAIAJS_MCP_MODE ?? 'STANDARD') as McpMode;
57
+ registerNarrativeTools(server); // always
58
+ if (mode !== 'MINIMAL') {
59
+ registerPdeTools(server);
60
+ registerPlanningTools(server);
61
+ registerRedisTools(server);
62
+ }
63
+ if (mode === 'FULL') {
64
+ registerLangfuseTools(server);
65
+ registerPipelineTools(server);
66
+ registerAudioTools(server);
67
+ }
68
+
69
+ const transport = new StdioServerTransport();
70
+ await server.connect(transport);
71
+ ```
72
+
73
+ ## Tool Registry
74
+
75
+ ### Narrative Engine (28 tools — always loaded)
76
+
77
+ STC: `create_structural_tension_chart`, `list_active_charts`, `get_chart`, `get_chart_progress`, `manage_action_step`, `mark_action_complete`, `update_action_progress`, `update_current_reality`, `update_desired_outcome`, `get_action_step`, `remove_action_step`
78
+
79
+ Knowledge Graph: `create_entities`, `create_relations`, `add_observations`, `search_nodes`, `open_nodes`, `read_graph`, `delete_entities`, `delete_relations`, `delete_observations`
80
+
81
+ Narrative Beats: `create_narrative_beat`, `telescope_narrative_beat`, `list_narrative_beats`
82
+
83
+ MMOT: `perform_mmot_evaluation`, `init_llm_guidance`
84
+
85
+ ### PDE Engine (12 tools — STANDARD+)
86
+
87
+ `pde_decompose`, `pde_parse_response`, `pde_get`, `pde_list`, `pde_export_markdown`, `pde_to_stc`, `pde_preview_stc`, `pde_create_session`, `pde_get_session`, `pde_list_sessions`, `pde_session_status`, `pde_bridge_plan`
88
+
89
+ ### Planning Engine (6 tools — STANDARD+)
90
+
91
+ `plan_parse`, `plan_to_stc`, `plan_from_stc`, `plan_sync`, `plan_diff`, `plan_bridge_pde`
92
+
93
+ ### Redis (5 tools — STANDARD+)
94
+
95
+ `redis_tash`, `redis_fetch`, `redis_del`, `redis_keys`, `redis_exists`
96
+
97
+ ### Langfuse (8 tools — FULL only)
98
+
99
+ `langfuse_list_traces`, `langfuse_get_trace`, `langfuse_list_prompts`, `langfuse_get_prompt`, `langfuse_list_datasets`, `langfuse_list_scores`, `langfuse_create_score`, `langfuse_list_score_configs`
100
+
101
+ ### Pipeline (3 tools — FULL only)
102
+
103
+ `pipeline_list`, `pipeline_render`, `pipeline_execute`
104
+
105
+ ### Audio (2 tools — FULL only)
106
+
107
+ `audio_transcribe`, `audio_synthesize`
108
+
109
+ ## Tool Registration Pattern
110
+
111
+ Each module provides a `registerXxxTools(server: McpServer)` function:
112
+
113
+ ```typescript
114
+ // mcp/tools/redis.ts
115
+ export function registerRedisTools(server: McpServer) {
116
+ server.tool('redis_tash', 'Store a value in Redis with optional TTL', {
117
+ key: z.string().describe('Redis key'),
118
+ value: z.string().describe('Value to store'),
119
+ ttl: z.number().optional().describe('TTL in seconds'),
120
+ }, async ({ key, value, ttl }) => {
121
+ await tash(key, value, ttl);
122
+ return { content: [{ type: 'text', text: `Stored ${key}` }] };
123
+ });
124
+ // ... more tools
125
+ }
126
+ ```
127
+
128
+ ## Transport
129
+
130
+ stdio transport only (standard MCP pattern). Server reads JSON-RPC from stdin, writes to stdout. This is compatible with all MCP clients (Claude Code, Cursor, VS Code Copilot, etc.).
131
+
132
+ ## Quality Criteria
133
+
134
+ - ✅ Single MCP config entry replaces three separate servers
135
+ - ✅ All 44 parent tools produce identical results to their parent implementations
136
+ - ✅ Feature gating reduces tool count without breaking functionality
137
+ - ✅ `COAIAJS_MCP_MODE=MINIMAL` loads ≤25 tools
138
+ - ✅ Server starts in <500ms for MINIMAL mode
139
+ - ✅ Tool descriptions are self-documenting (LLMs understand usage without external docs)
140
+ - ✅ Error responses include actionable information
@@ -0,0 +1,63 @@
1
+ # 10 — Audio Module
2
+
3
+ > Audio transcription (OpenAI Whisper) and synthesis (AWS Polly).
4
+
5
+ ## Desired Outcome
6
+
7
+ An audio module providing speech-to-text transcription via OpenAI Whisper and text-to-speech synthesis via AWS Polly — enabling voice-driven agent interactions and audio content generation.
8
+
9
+ ## Structural Tension
10
+
11
+ **Current Reality:**
12
+ - `src/audio.ts` is fully implemented (76 lines) with `synthesize()` function using AWS Polly
13
+ - `src/llm.ts` includes `transcribeAudio()` using OpenAI Whisper
14
+ - Both use lazy client initialization
15
+ - coaiapy's `syntation.py` provides the same functionality via boto3 and openai Python packages
16
+ - No MCP tools exist for audio in any parent project
17
+
18
+ **Desired Outcome:**
19
+ Audio module consolidating transcription and synthesis in one place:
20
+ - `transcribe(audioPath)` — OpenAI Whisper speech-to-text
21
+ - `synthesize(text, outputPath, options?)` — AWS Polly text-to-speech
22
+ - 2 MCP tools for interactive audio operations
23
+ - Support for multiple voices, engines, and output formats
24
+
25
+ ## Core API
26
+
27
+ ```typescript
28
+ // Transcription (via OpenAI Whisper)
29
+ transcribe(audioPath: string, options?: {
30
+ model?: string; // default: 'whisper-1'
31
+ language?: string; // ISO 639-1 code
32
+ prompt?: string; // context hint
33
+ }): Promise<string> // returns transcribed text
34
+
35
+ // Synthesis (via AWS Polly)
36
+ synthesize(text: string, outputPath: string, options?: {
37
+ voice?: string; // default: 'Joanna' (from config)
38
+ engine?: 'neural' | 'standard'; // default: 'neural'
39
+ format?: 'mp3' | 'ogg_vorbis' | 'pcm'; // default: 'mp3'
40
+ }): Promise<string> // returns output file path
41
+ ```
42
+
43
+ ## MCP Tools (2)
44
+
45
+ | Tool | Purpose |
46
+ |------|---------|
47
+ | `audio_transcribe` | Transcribe audio file to text |
48
+ | `audio_synthesize` | Synthesize text to audio file |
49
+
50
+ ## Configuration
51
+
52
+ Uses config keys from `src/config.ts`:
53
+ - `openai_api_key` — for Whisper transcription
54
+ - `aws_access_key_id`, `aws_secret_access_key`, `aws_region` — for Polly synthesis
55
+ - `aws_polly_voice` — default voice (fallback: `Joanna`)
56
+
57
+ ## Quality Criteria
58
+
59
+ - ✅ `transcribe()` accepts wav, mp3, m4a, webm, mp4 audio files
60
+ - ✅ `synthesize()` produces valid MP3 output playable in standard players
61
+ - ✅ Missing credentials produce clear error at call time, not import time
62
+ - ✅ Parity with coaiapy's transcription and synthesis behavior
63
+ - ✅ `resetClient()` clears cached clients for test isolation
@@ -0,0 +1,56 @@
1
+ # KINSHIP.md — coaiajs/rispecs
2
+
3
+ ## Identity
4
+
5
+ **Name:** coaiajs rispecs
6
+ **Role:** RISE-based structural specifications for the coaiajs platform
7
+ **Status:** Genesis (2026-03-11)
8
+
9
+ ## Lineage
10
+
11
+ These specifications synthesize the creative intent, structural patterns, and behavioral requirements from four parent projects into a unified specification set.
12
+
13
+ ### Parent Rispecs
14
+
15
+ | Source | Location | What was inherited |
16
+ |--------|----------|-------------------|
17
+ | **coaia-narrative rispecs** | `/src/coaia-narrative/rispecs/` | 15 specs — STC creation, telescoping, advancing patterns, JSONL storage, MCP tools, MMOT, narrative beats, input validation, educational guidance, CLI visualization |
18
+ | **coaia-pde rispecs** | `/src/coaia-pde/rispecs/` | 1 spec — PDE→STC transformation mapping (Four Directions → STC components) |
19
+ | **RISE Framework** | `/src/llms/llms-rise-framework.txt` | Methodology: creative orientation, structural tension dynamics, variable detail levels, spec-as-source-of-truth |
20
+
21
+ ### No Prior Rispecs Existed For
22
+
23
+ | Module | First specified here |
24
+ |--------|---------------------|
25
+ | Core config | `01-core-config.spec.md` |
26
+ | Redis | `02-redis-module.spec.md` |
27
+ | Langfuse | `03-langfuse-module.spec.md` |
28
+ | Planning | `06-planning-engine.spec.md` |
29
+ | Pipeline | `07-pipeline-templates.spec.md` |
30
+ | CLI | `08-cli-interface.spec.md` |
31
+ | MCP server (unified) | `09-mcp-server.spec.md` |
32
+ | Audio | `10-audio-module.spec.md` |
33
+
34
+ ## Accountabilities
35
+
36
+ 1. **Completeness** — These specs are sufficient for another LLM to re-implement the entire coaiajs platform from scratch
37
+ 2. **Accuracy** — Current reality assessments are honest and factual, reflecting actual implementation state as of 2026-03-11
38
+ 3. **Creative orientation** — All desired outcomes use creation language, not problem-solving language
39
+ 4. **Backward compatibility** — Specs preserve behavioral compatibility with parent projects
40
+ 5. **Independence** — Specs are codebase-agnostic; they describe behavior, not implementation
41
+
42
+ ## Consumers
43
+
44
+ | Consumer | How they use these specs |
45
+ |----------|------------------------|
46
+ | **coaiajs implementors** | Build each module from its spec |
47
+ | **coaia-narrative maintainers** | Verify their rispecs are preserved in consolidation |
48
+ | **coaia-pde maintainers** | Verify PDE→STC mapping is preserved |
49
+ | **MMOT evaluations** | Elements of Performance derived from quality criteria sections |
50
+ | **mia-code / miaco** | Reference for PDE and narrative integration patterns |
51
+
52
+ ## Structural Tension
53
+
54
+ **Desired Outcome:** These rispecs serve as the single source of truth for what coaiajs should become — complete enough for autonomous re-implementation, accurate enough for MMOT self-evaluation.
55
+
56
+ **Current Reality:** 13 spec files covering the full platform. Parent project rispecs remain authoritative for deep behavioral details (especially coaia-narrative's 15 specs). These specs provide the consolidation vision and module boundaries.
@@ -0,0 +1,100 @@
1
+ # CoAiA.js — RISE Specifications
2
+
3
+ > Complete RISE-based specifications for rebuilding CoAiA.js from scratch.
4
+ > Another LLM or developer reading these specs alone should be able to re-implement the entire system.
5
+
6
+ ## Purpose
7
+
8
+ These rispecs define the structural specifications for **coaiajs** — the unified TypeScript platform that consolidates `coaiapy`, `coaia-narrative`, `coaia-pde`, and `coaia-planning` into a single modern Node.js package.
9
+
10
+ ## Specification Index
11
+
12
+ ### Platform
13
+
14
+ | # | Spec | Scope |
15
+ |---|------|-------|
16
+ | 00 | [coaiajs-platform](./00-coaiajs-platform.spec.md) | Master platform spec — vision, lineage, component map |
17
+
18
+ ### Core Modules
19
+
20
+ | # | Spec | Scope | Lineage |
21
+ |---|------|-------|---------|
22
+ | 01 | [core-config](./01-core-config.spec.md) | Config loading, env vars, deep merge | coaiapy `read_config()` |
23
+ | 02 | [redis-module](./02-redis-module.spec.md) | Redis tash/fetch, lazy connection, Upstash | coaiapy `tash/fetch` |
24
+ | 03 | [langfuse-module](./03-langfuse-module.spec.md) | Langfuse observability REST client | coaiapy `cofuse.py` |
25
+
26
+ ### Engine Modules
27
+
28
+ | # | Spec | Scope | Lineage |
29
+ |---|------|-------|---------|
30
+ | 04 | [narrative-engine](./04-narrative-engine.spec.md) | JSONL knowledge graph, STC, beats, MMOT | coaia-narrative `graph-manager.ts` |
31
+ | 05 | [pde-engine](./05-pde-engine.spec.md) | PDE→STC transformation, session management | coaia-pde `stc-mapper.ts` |
32
+ | 06 | [planning-engine](./06-planning-engine.spec.md) | Plan parsing, plan↔STC sync | coaia-planning `plan-parser.ts` |
33
+
34
+ ### Support Modules
35
+
36
+ | # | Spec | Scope | Lineage |
37
+ |---|------|-------|---------|
38
+ | 07 | [pipeline-templates](./07-pipeline-templates.spec.md) | Template rendering, variable substitution | coaiapy `pipeline.py` |
39
+ | 10 | [audio-module](./10-audio-module.spec.md) | Whisper transcription, Polly synthesis | coaiapy `syntation.py` |
40
+
41
+ ### Interface Layers
42
+
43
+ | # | Spec | Scope | Lineage |
44
+ |---|------|-------|---------|
45
+ | 08 | [cli-interface](./08-cli-interface.spec.md) | Unified `coaia` CLI with all subcommands | coaiapy argparse + coaia-narrative minimist |
46
+ | 09 | [mcp-server](./09-mcp-server.spec.md) | Unified MCP server with 64+ tools | 4 separate MCP servers |
47
+
48
+ ## How Specs Relate
49
+
50
+ ```
51
+ ┌─────────────────────────────────────────────────────┐
52
+ │ 00-coaiajs-platform (master) │
53
+ │ │
54
+ │ ┌─────────┐ ┌──────────┐ ┌───────────────────┐ │
55
+ │ │01 config │→ │02 redis │ │03 langfuse │ │
56
+ │ └────┬─────┘ └─────┬────┘ └────────┬──────────┘ │
57
+ │ │ │ │ │
58
+ │ ┌────▼──────────────▼───────────────▼──────────┐ │
59
+ │ │ 04 narrative-engine (JSONL, STC, MMOT) │ │
60
+ │ └────────┬──────────────────────┬──────────────┘ │
61
+ │ │ │ │
62
+ │ ┌────────▼──────┐ ┌───────────▼──────────────┐ │
63
+ │ │05 pde-engine │ │06 planning-engine │ │
64
+ │ └───────────────┘ └──────────────────────────┘ │
65
+ │ │
66
+ │ ┌───────────────┐ ┌──────────────────────────┐ │
67
+ │ │07 pipeline │ │10 audio │ │
68
+ │ └───────────────┘ └──────────────────────────┘ │
69
+ │ │
70
+ │ ┌──────────────────────────────────────────────┐ │
71
+ │ │ 08 cli-interface 09 mcp-server │ │
72
+ │ └──────────────────────────────────────────────┘ │
73
+ └─────────────────────────────────────────────────────┘
74
+ ```
75
+
76
+ ## Conventions
77
+
78
+ - **Creative orientation**: Desired Outcome describes what IS CREATED, not what is fixed
79
+ - **Honest current reality**: Factual assessment of where things stand today
80
+ - **Structural tension**: The gap between current and desired that drives advancement
81
+ - **Variable detail**: Broad for obvious patterns, precise for critical behavior
82
+ - **Naming**: `NN-kebab-case.spec.md`
83
+ - **Codebase-agnostic**: Specs describe behavior, not implementation details
84
+
85
+ ## Relationship to Parent Rispecs
86
+
87
+ | Project | Rispecs location | Status |
88
+ |---------|-----------------|--------|
89
+ | coaia-narrative | `/src/coaia-narrative/rispecs/` | 15 specs — most mature, patterns inherited here |
90
+ | coaia-pde | `/src/coaia-pde/rispecs/` | 1 spec — PDE→STC transformation |
91
+ | coaia-planning | — | No rispecs yet — spec 06 here is the first |
92
+ | coaiapy | — | No rispecs — specs 01-03, 07, 10 here are the first |
93
+
94
+ ## RISE Framework Reference
95
+
96
+ These specs follow the RISE Framework (`/src/llms/llms-rise-framework.txt`):
97
+ - **R**everse-engineer: Extract creative intent from parent projects
98
+ - **I**ntent-extract: Identify what each module enables users to create
99
+ - **S**pecify: Define structural tension between current and desired
100
+ - **E**xport: Produce specs sufficient for autonomous re-implementation
package/src/audio.ts ADDED
@@ -0,0 +1,76 @@
1
+ // coaiajs/src/audio.ts — Audio synthesis module
2
+ // Parity with coaiapy's syntation.py using AWS Polly
3
+
4
+ import {
5
+ PollyClient,
6
+ SynthesizeSpeechCommand,
7
+ type SynthesizeSpeechCommandInput,
8
+ } from '@aws-sdk/client-polly';
9
+ import { writeFileSync } from 'node:fs';
10
+ import { resolve } from 'node:path';
11
+ import { getConfig } from './config.js';
12
+
13
+ let _client: PollyClient | null = null;
14
+
15
+ function getPollyClient(): PollyClient {
16
+ if (!_client) {
17
+ const cfg = getConfig();
18
+ _client = new PollyClient({
19
+ region: cfg.aws?.region ?? process.env['AWS_REGION'] ?? 'us-east-1',
20
+ credentials:
21
+ cfg.aws?.accessKeyId
22
+ ? {
23
+ accessKeyId: cfg.aws.accessKeyId,
24
+ secretAccessKey: cfg.aws.secretAccessKey ?? '',
25
+ }
26
+ : undefined,
27
+ });
28
+ }
29
+ return _client;
30
+ }
31
+
32
+ /** Reset client (testing). */
33
+ export function resetClient(): void {
34
+ _client = null;
35
+ }
36
+
37
+ /**
38
+ * Synthesize text to speech using AWS Polly.
39
+ * Returns the path to the output audio file.
40
+ *
41
+ * @param text - Text to synthesize
42
+ * @param voiceId - Polly voice ID (default: "Joanna")
43
+ * @param outFile - Output file path (default: "./output.mp3")
44
+ */
45
+ export async function synthesize(
46
+ text: string,
47
+ voiceId?: string,
48
+ outFile?: string,
49
+ ): Promise<string> {
50
+ const client = getPollyClient();
51
+ const outputPath = resolve(outFile ?? './output.mp3');
52
+
53
+ const params: SynthesizeSpeechCommandInput = {
54
+ Text: text,
55
+ OutputFormat: 'mp3',
56
+ VoiceId: (voiceId ?? 'Joanna') as SynthesizeSpeechCommandInput['VoiceId'],
57
+ Engine: 'neural',
58
+ };
59
+
60
+ const result = await client.send(new SynthesizeSpeechCommand(params));
61
+
62
+ if (result.AudioStream) {
63
+ // AudioStream is a Readable or Uint8Array depending on environment
64
+ const chunks: Uint8Array[] = [];
65
+ const stream = result.AudioStream as AsyncIterable<Uint8Array>;
66
+
67
+ for await (const chunk of stream) {
68
+ chunks.push(chunk);
69
+ }
70
+
71
+ const buffer = Buffer.concat(chunks);
72
+ writeFileSync(outputPath, buffer);
73
+ }
74
+
75
+ return outputPath;
76
+ }
@@ -0,0 +1,86 @@
1
+ import chalk from 'chalk';
2
+
3
+ let colorEnabled = true;
4
+
5
+ export function setColorEnabled(enabled: boolean): void {
6
+ colorEnabled = enabled;
7
+ if (!enabled) {
8
+ chalk.level = 0;
9
+ }
10
+ }
11
+
12
+ export function formatTable(headers: string[], rows: string[][]): string {
13
+ if (rows.length === 0) return '(no data)';
14
+
15
+ const widths = headers.map((h, i) =>
16
+ Math.max(h.length, ...rows.map(r => (r[i] ?? '').length))
17
+ );
18
+
19
+ const headerLine = headers
20
+ .map((h, i) => h.padEnd(widths[i]!))
21
+ .join(' ');
22
+ const separator = widths.map(w => '─'.repeat(w)).join('──');
23
+ const dataLines = rows.map(row =>
24
+ row.map((cell, i) => (cell ?? '').padEnd(widths[i]!)).join(' ')
25
+ );
26
+
27
+ return [
28
+ colorEnabled ? chalk.bold(headerLine) : headerLine,
29
+ separator,
30
+ ...dataLines,
31
+ ].join('\n');
32
+ }
33
+
34
+ export function formatJson(data: unknown): string {
35
+ return JSON.stringify(data, null, 2);
36
+ }
37
+
38
+ export function formatError(message: string): string {
39
+ const sym = colorEnabled ? chalk.red('✗') : '✗';
40
+ const txt = colorEnabled ? chalk.red(message) : message;
41
+ return `${sym} ${txt}`;
42
+ }
43
+
44
+ export function formatSuccess(message: string): string {
45
+ const sym = colorEnabled ? chalk.green('✓') : '✓';
46
+ const txt = colorEnabled ? chalk.green(message) : message;
47
+ return `${sym} ${txt}`;
48
+ }
49
+
50
+ export function truncate(text: string, maxLength: number): string {
51
+ if (text.length <= maxLength) return text;
52
+ return text.slice(0, maxLength - 1) + '…';
53
+ }
54
+
55
+ export function formatDate(iso: string): string {
56
+ const date = new Date(iso);
57
+ if (isNaN(date.getTime())) return iso;
58
+ const now = new Date();
59
+ const diffMs = now.getTime() - date.getTime();
60
+ const diffMins = Math.floor(diffMs / 60_000);
61
+ const diffHours = Math.floor(diffMins / 60);
62
+ const diffDays = Math.floor(diffHours / 24);
63
+
64
+ if (diffMins < 1) return 'just now';
65
+ if (diffMins < 60) return `${diffMins}m ago`;
66
+ if (diffHours < 24) return `${diffHours}h ago`;
67
+ if (diffDays < 7) return `${diffDays}d ago`;
68
+ return date.toISOString().slice(0, 10);
69
+ }
70
+
71
+ export function formatProgress(completed: number, total: number): string {
72
+ if (total === 0) return '[░░░░░░░░░░] 0% (0/0)';
73
+ const ratio = Math.min(completed / total, 1);
74
+ const pct = Math.round(ratio * 100);
75
+ const filled = Math.round(ratio * 10);
76
+ const empty = 10 - filled;
77
+ const bar = '█'.repeat(filled) + '░'.repeat(empty);
78
+ const colored = colorEnabled
79
+ ? ratio >= 1
80
+ ? chalk.green(bar)
81
+ : ratio >= 0.5
82
+ ? chalk.yellow(bar)
83
+ : chalk.red(bar)
84
+ : bar;
85
+ return `[${colored}] ${pct}% (${completed}/${total})`;
86
+ }