@esotech/contextuate 2.0.0 → 2.1.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 (103) hide show
  1. package/README.md +169 -1
  2. package/dist/commands/claude.d.ts +21 -0
  3. package/dist/commands/claude.js +213 -0
  4. package/dist/commands/context.d.ts +1 -0
  5. package/dist/commands/create.d.ts +3 -0
  6. package/dist/commands/index.d.ts +4 -0
  7. package/dist/commands/init.d.ts +7 -0
  8. package/dist/commands/init.js +67 -6
  9. package/dist/commands/install.d.ts +28 -0
  10. package/dist/commands/install.js +100 -11
  11. package/dist/commands/monitor.d.ts +55 -0
  12. package/dist/commands/monitor.js +1007 -0
  13. package/dist/commands/remove.d.ts +3 -0
  14. package/dist/commands/run.d.ts +6 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +113 -1
  17. package/dist/monitor/daemon/circuit-breaker.d.ts +121 -0
  18. package/dist/monitor/daemon/circuit-breaker.js +552 -0
  19. package/dist/monitor/daemon/cli.d.ts +8 -0
  20. package/dist/monitor/daemon/cli.js +82 -0
  21. package/dist/monitor/daemon/index.d.ts +137 -0
  22. package/dist/monitor/daemon/index.js +695 -0
  23. package/dist/monitor/daemon/notifier.d.ts +25 -0
  24. package/dist/monitor/daemon/notifier.js +98 -0
  25. package/dist/monitor/daemon/processor.d.ts +89 -0
  26. package/dist/monitor/daemon/processor.js +455 -0
  27. package/dist/monitor/daemon/state.d.ts +80 -0
  28. package/dist/monitor/daemon/state.js +162 -0
  29. package/dist/monitor/daemon/watcher.d.ts +47 -0
  30. package/dist/monitor/daemon/watcher.js +171 -0
  31. package/dist/monitor/daemon/wrapper-manager.d.ts +106 -0
  32. package/dist/monitor/daemon/wrapper-manager.js +374 -0
  33. package/dist/monitor/hooks/emit-event.js +652 -0
  34. package/dist/monitor/persistence/file-store.d.ts +88 -0
  35. package/dist/monitor/persistence/file-store.js +335 -0
  36. package/dist/monitor/persistence/index.d.ts +7 -0
  37. package/dist/monitor/persistence/index.js +10 -0
  38. package/dist/monitor/server/adapters/redis.d.ts +38 -0
  39. package/dist/monitor/server/adapters/redis.js +213 -0
  40. package/dist/monitor/server/adapters/unix-socket.d.ts +33 -0
  41. package/dist/monitor/server/adapters/unix-socket.js +182 -0
  42. package/dist/monitor/server/broker.d.ts +135 -0
  43. package/dist/monitor/server/broker.js +475 -0
  44. package/dist/monitor/server/cli.d.ts +8 -0
  45. package/dist/monitor/server/cli.js +98 -0
  46. package/dist/monitor/server/fastify.d.ts +16 -0
  47. package/dist/monitor/server/fastify.js +184 -0
  48. package/dist/monitor/server/index.d.ts +36 -0
  49. package/dist/monitor/server/index.js +153 -0
  50. package/dist/monitor/server/websocket.d.ts +80 -0
  51. package/dist/monitor/server/websocket.js +453 -0
  52. package/dist/monitor/ui/assets/index-4IssW9On.js +59 -0
  53. package/dist/monitor/ui/assets/index-vo9hLe5R.css +32 -0
  54. package/dist/monitor/ui/favicon.png +0 -0
  55. package/dist/monitor/ui/index.html +14 -0
  56. package/dist/monitor/ui/logo.png +0 -0
  57. package/dist/monitor/ui/logo.svg +1 -0
  58. package/dist/runtime/driver.d.ts +16 -0
  59. package/dist/runtime/tools.d.ts +10 -0
  60. package/dist/templates/README.md +33 -7
  61. package/dist/templates/agents/aegis.md +4 -0
  62. package/dist/templates/agents/archon.md +13 -22
  63. package/dist/templates/agents/atlas.md +4 -0
  64. package/dist/templates/agents/canvas.md +4 -0
  65. package/dist/templates/agents/chronicle.md +4 -0
  66. package/dist/templates/agents/chronos.md +4 -0
  67. package/dist/templates/agents/cipher.md +4 -0
  68. package/dist/templates/agents/crucible.md +4 -0
  69. package/dist/templates/agents/echo.md +4 -0
  70. package/dist/templates/agents/forge.md +4 -0
  71. package/dist/templates/agents/ledger.md +4 -0
  72. package/dist/templates/agents/meridian.md +4 -0
  73. package/dist/templates/agents/nexus.md +4 -0
  74. package/dist/templates/agents/pythia.md +217 -0
  75. package/dist/templates/agents/scribe.md +4 -0
  76. package/dist/templates/agents/sentinel.md +4 -0
  77. package/dist/templates/agents/{oracle.md → thoth.md} +11 -7
  78. package/dist/templates/agents/unity.md +4 -0
  79. package/dist/templates/agents/vox.md +4 -0
  80. package/dist/templates/agents/weaver.md +4 -0
  81. package/dist/templates/commands/consult.md +138 -0
  82. package/dist/templates/commands/orchestrate.md +173 -0
  83. package/dist/templates/framework-agents/documentation-expert.md +3 -3
  84. package/dist/templates/framework-agents/tools-expert.md +8 -8
  85. package/dist/templates/standards/agent-roles.md +68 -21
  86. package/dist/templates/standards/coding-standards.md +9 -26
  87. package/dist/templates/templates/context.md +17 -2
  88. package/dist/templates/templates/contextuate.md +21 -28
  89. package/dist/templates/tools/{agent-creator.tool.md → agent-creator.md} +3 -3
  90. package/dist/types/monitor.d.ts +660 -0
  91. package/dist/types/monitor.js +75 -0
  92. package/dist/utils/git.d.ts +9 -0
  93. package/dist/utils/tokens.d.ts +10 -0
  94. package/package.json +18 -5
  95. package/dist/templates/version.json +0 -8
  96. /package/dist/templates/templates/standards/{go.standards.md → go.md} +0 -0
  97. /package/dist/templates/templates/standards/{java.standards.md → java.md} +0 -0
  98. /package/dist/templates/templates/standards/{javascript.standards.md → javascript.md} +0 -0
  99. /package/dist/templates/templates/standards/{php.standards.md → php.md} +0 -0
  100. /package/dist/templates/templates/standards/{python.standards.md → python.md} +0 -0
  101. /package/dist/templates/tools/{quickref.tool.md → quickref.md} +0 -0
  102. /package/dist/templates/tools/{spawn.tool.md → spawn.md} +0 -0
  103. /package/dist/templates/tools/{standards-detector.tool.md → standards-detector.md} +0 -0
package/README.md CHANGED
@@ -68,6 +68,7 @@ Contextuate is a directory structure and set of conventions that helps AI agents
68
68
  - **`docs/ai/standards/`**: Explicit coding standards and behavioral guidelines.
69
69
  - **`docs/ai/quickrefs/`**: Condensed documentation optimized for AI token limits.
70
70
  - **`docs/ai/tasks/`**: A workflow for managing multi-session AI tasks.
71
+ - **`docs/ai/skills/`**: Slash commands that activate special behaviors (e.g., `/orchestrate`).
71
72
 
72
73
  ## How LLMs Use Contextuate
73
74
 
@@ -119,6 +120,7 @@ contextuate -V # Short form for version
119
120
  | `index` | Generate a project file tree |
120
121
  | `add-context` | Interactively add files to context |
121
122
  | `remove` | Clean up framework files |
123
+ | `monitor` | Real-time Claude Code session monitoring |
122
124
 
123
125
  ---
124
126
 
@@ -168,6 +170,7 @@ contextuate install --all
168
170
  contextuate install --agents archon base canvas
169
171
  contextuate install --standards php javascript
170
172
  contextuate install --tools quickref
173
+ contextuate install --skills orchestrate
171
174
 
172
175
  # Subcommand style
173
176
  contextuate install agents archon base
@@ -175,6 +178,7 @@ contextuate install agents --all
175
178
  contextuate install standards php javascript python
176
179
  contextuate install standards --all
177
180
  contextuate install tools --all
181
+ contextuate install skills --all
178
182
 
179
183
  # Force overwrite
180
184
  contextuate install agents --all --force
@@ -184,14 +188,16 @@ contextuate install agents --all --force
184
188
  - `-a, --agents <names...>` - Install specific agents
185
189
  - `-s, --standards <names...>` - Install language standards
186
190
  - `-t, --tools <names...>` - Install tools
191
+ - `-k, --skills <names...>` - Install skills (slash commands)
187
192
  - `--all` - Install all available templates
188
193
  - `-l, --list` - List available templates
189
194
  - `-f, --force` - Overwrite existing files
190
195
 
191
196
  **Subcommands:**
192
- - `install agents [names...]` - Install agent templates
197
+ - `install agents [names...]` - Install agent templates (also installs skills by default)
193
198
  - `install standards [names...]` - Install language standard templates
194
199
  - `install tools [names...]` - Install tool templates
200
+ - `install skills [names...]` - Install skill templates (slash commands like `/orchestrate`)
195
201
 
196
202
  ---
197
203
 
@@ -269,6 +275,168 @@ Remove unmodified platform jump files.
269
275
  contextuate remove
270
276
  ```
271
277
 
278
+ ---
279
+
280
+ ### `contextuate monitor`
281
+
282
+ Real-time monitoring dashboard for Claude Code sessions. Tracks tool usage, events, and session activity.
283
+
284
+ #### Architecture
285
+
286
+ The monitor uses a 3-layer architecture:
287
+
288
+ 1. **Hooks** - Claude Code hooks emit events to the daemon
289
+ 2. **Daemon** - Background process that collects and processes events (runs independently)
290
+ 3. **UI Server** - Web dashboard and WebSocket server for real-time updates
291
+
292
+ ```
293
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
294
+ │ Claude Code │────▶│ Daemon │────▶│ UI Server │
295
+ │ (Hooks) │ │ (Background) │ │ (Dashboard) │
296
+ └─────────────────┘ └─────────────────┘ └─────────────────┘
297
+ ```
298
+
299
+ **Important:** The daemon runs independently of the UI server. Starting the monitor will spawn the daemon, but stopping the monitor will NOT stop the daemon (so it can continue collecting events). Use `--all` to stop both.
300
+
301
+ #### Commands
302
+
303
+ ```bash
304
+ # Initial setup (interactive)
305
+ contextuate monitor init
306
+ contextuate monitor init --global # Install hooks at user level (~/.claude/)
307
+ contextuate monitor init --project # Install hooks at project level (.claude/)
308
+
309
+ # Start the monitor (auto-starts daemon if not running)
310
+ contextuate monitor
311
+ contextuate monitor start
312
+ contextuate monitor start --port 8080 # Custom HTTP port
313
+ contextuate monitor start --ws-port 8081 # Custom WebSocket port
314
+ contextuate monitor start --no-open # Don't open browser
315
+ contextuate monitor start --foreground # Run in foreground (blocking)
316
+
317
+ # Stop the monitor
318
+ contextuate monitor stop # Stop UI server only (daemon keeps running)
319
+ contextuate monitor stop --all # Stop both UI server and daemon
320
+
321
+ # Check status
322
+ contextuate monitor status
323
+
324
+ # Daemon management (advanced)
325
+ contextuate monitor daemon start # Start daemon only
326
+ contextuate monitor daemon start --detach # Start daemon in background
327
+ contextuate monitor daemon stop # Stop daemon
328
+ contextuate monitor daemon status # Check daemon status
329
+ contextuate monitor daemon logs # View daemon logs
330
+ contextuate monitor daemon logs -f # Follow daemon logs
331
+ contextuate monitor daemon logs -n 100 # Show last 100 lines
332
+ ```
333
+
334
+ #### Configuration
335
+
336
+ Configuration is stored in `~/.contextuate/monitor/config.json`. Run `contextuate monitor init` for interactive setup, or edit the file directly.
337
+
338
+ ##### Full Configuration Example
339
+
340
+ ```json
341
+ {
342
+ "mode": "local",
343
+ "server": {
344
+ "host": "0.0.0.0",
345
+ "port": 3847,
346
+ "wsPort": 3848
347
+ },
348
+ "redis": {
349
+ "host": "localhost",
350
+ "port": 6379,
351
+ "password": null,
352
+ "channel": "contextuate:events"
353
+ },
354
+ "persistence": {
355
+ "enabled": true,
356
+ "type": "file",
357
+ "database": {
358
+ "host": "localhost",
359
+ "port": 3306,
360
+ "database": "contextuate",
361
+ "user": "contextuate",
362
+ "password": "secret"
363
+ }
364
+ },
365
+ "socketPath": "/tmp/contextuate-monitor.sock"
366
+ }
367
+ ```
368
+
369
+ ##### Configuration Parameters
370
+
371
+ | Parameter | Type | Default | Description |
372
+ |:----------|:-----|:--------|:------------|
373
+ | `mode` | `"local"` \| `"redis"` | `"local"` | Communication mode between components |
374
+ | `socketPath` | string | `"/tmp/contextuate-monitor.sock"` | Unix socket path (local mode only) |
375
+
376
+ **Server Settings** (`server`):
377
+
378
+ | Parameter | Type | Default | Description |
379
+ |:----------|:-----|:--------|:------------|
380
+ | `host` | string | `"0.0.0.0"` | Host to bind the HTTP server |
381
+ | `port` | number | `3847` | HTTP port for the dashboard |
382
+ | `wsPort` | number | `3848` | WebSocket port for real-time updates |
383
+
384
+ **Redis Settings** (`redis`) - for distributed/multi-machine setups:
385
+
386
+ | Parameter | Type | Default | Description |
387
+ |:----------|:-----|:--------|:------------|
388
+ | `host` | string | `"localhost"` | Redis server host |
389
+ | `port` | number | `6379` | Redis server port |
390
+ | `password` | string \| null | `null` | Redis password (optional) |
391
+ | `channel` | string | `"contextuate:events"` | Redis pub/sub channel name |
392
+
393
+ **Persistence Settings** (`persistence`):
394
+
395
+ | Parameter | Type | Default | Description |
396
+ |:----------|:-----|:--------|:------------|
397
+ | `enabled` | boolean | `true` | Enable session persistence |
398
+ | `type` | `"file"` \| `"mysql"` \| `"postgresql"` | `"file"` | Storage backend |
399
+ | `database` | object | - | Database connection settings (required for mysql/postgresql) |
400
+
401
+ **Database Settings** (`persistence.database`) - for MySQL/PostgreSQL:
402
+
403
+ | Parameter | Type | Description |
404
+ |:----------|:-----|:------------|
405
+ | `host` | string | Database server host |
406
+ | `port` | number | Database server port (3306 for MySQL, 5432 for PostgreSQL) |
407
+ | `database` | string | Database name |
408
+ | `user` | string | Database username |
409
+ | `password` | string | Database password |
410
+
411
+ > **Note:** MySQL and PostgreSQL persistence are planned features. Currently only file-based persistence is fully implemented.
412
+
413
+ ##### Mode Comparison
414
+
415
+ | Feature | Local Mode | Redis Mode |
416
+ |:--------|:-----------|:-----------|
417
+ | Setup complexity | Simple | Requires Redis server |
418
+ | Multi-machine support | No | Yes |
419
+ | Single machine | Recommended | Overkill |
420
+ | Event delivery | Unix socket | Redis pub/sub |
421
+ | Use case | Personal development | Team/distributed environments |
422
+
423
+ #### Files and Directories
424
+
425
+ ```
426
+ ~/.contextuate/monitor/
427
+ ├── config.json # Monitor configuration
428
+ ├── sessions/ # Persisted session data
429
+ ├── raw/ # Raw event files from hooks
430
+ ├── processed/ # Processed event files
431
+ ├── hooks/ # Hook scripts
432
+ ├── daemon.pid # Daemon process ID
433
+ ├── daemon.log # Daemon logs
434
+ ├── server.pid # UI server process ID
435
+ └── server.log # UI server logs
436
+ ```
437
+
438
+ ---
439
+
272
440
  ## Documentation
273
441
 
274
442
  For full documentation, see [contextuate.md](https://contextuate.md) or browse the `docs/ai/.contextuate/` directory.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Claude Wrapper Command
3
+ *
4
+ * Spawns a Claude session managed by the daemon.
5
+ * The daemon handles PTY management, so the session persists
6
+ * even after this command exits.
7
+ *
8
+ * Usage: contextuate claude [claude-args...]
9
+ */
10
+ /**
11
+ * Main command entry point
12
+ */
13
+ export declare function claudeCommand(args: string[]): Promise<void>;
14
+ /**
15
+ * List active wrappers
16
+ */
17
+ export declare function listWrappersCommand(): Promise<void>;
18
+ /**
19
+ * Kill a wrapper session
20
+ */
21
+ export declare function killWrapperCommand(wrapperId: string): Promise<void>;
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /**
3
+ * Claude Wrapper Command
4
+ *
5
+ * Spawns a Claude session managed by the daemon.
6
+ * The daemon handles PTY management, so the session persists
7
+ * even after this command exits.
8
+ *
9
+ * Usage: contextuate claude [claude-args...]
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.claudeCommand = claudeCommand;
46
+ exports.listWrappersCommand = listWrappersCommand;
47
+ exports.killWrapperCommand = killWrapperCommand;
48
+ const net = __importStar(require("net"));
49
+ const fs = __importStar(require("fs"));
50
+ // Daemon socket path
51
+ const DAEMON_SOCKET = '/tmp/contextuate-daemon.sock';
52
+ /**
53
+ * Connect to daemon and spawn a wrapper
54
+ */
55
+ async function spawnWrapper(args, cwd) {
56
+ return new Promise((resolve) => {
57
+ // Check if daemon socket exists
58
+ if (!fs.existsSync(DAEMON_SOCKET)) {
59
+ resolve({ success: false, error: 'Daemon not running. Start with: contextuate monitor' });
60
+ return;
61
+ }
62
+ const socket = new net.Socket();
63
+ let responseReceived = false;
64
+ socket.connect(DAEMON_SOCKET, () => {
65
+ // Send spawn request
66
+ const message = {
67
+ type: 'spawn_wrapper',
68
+ args,
69
+ cwd,
70
+ cols: process.stdout.columns || 120,
71
+ rows: process.stdout.rows || 40,
72
+ };
73
+ socket.write(JSON.stringify(message) + '\n');
74
+ });
75
+ socket.on('data', (data) => {
76
+ try {
77
+ const lines = data.toString().split('\n').filter(l => l.trim());
78
+ for (const line of lines) {
79
+ const response = JSON.parse(line);
80
+ if (response.type === 'wrapper_spawned') {
81
+ responseReceived = true;
82
+ socket.end();
83
+ resolve({
84
+ success: response.success,
85
+ wrapperId: response.wrapperId,
86
+ error: response.error,
87
+ });
88
+ }
89
+ }
90
+ }
91
+ catch (err) {
92
+ // Ignore parse errors
93
+ }
94
+ });
95
+ socket.on('error', (err) => {
96
+ if (!responseReceived) {
97
+ resolve({ success: false, error: `Connection error: ${err.message}` });
98
+ }
99
+ });
100
+ socket.on('close', () => {
101
+ if (!responseReceived) {
102
+ resolve({ success: false, error: 'Connection closed without response' });
103
+ }
104
+ });
105
+ // Timeout after 10 seconds
106
+ setTimeout(() => {
107
+ if (!responseReceived) {
108
+ socket.destroy();
109
+ resolve({ success: false, error: 'Spawn request timed out' });
110
+ }
111
+ }, 10000);
112
+ });
113
+ }
114
+ /**
115
+ * Main command entry point
116
+ */
117
+ async function claudeCommand(args) {
118
+ const cwd = process.cwd();
119
+ console.log('Spawning Claude session via daemon...');
120
+ const result = await spawnWrapper(args, cwd);
121
+ if (result.success) {
122
+ console.log(`\nClaude session started: ${result.wrapperId}`);
123
+ console.log('\nThe session is now running in the background, managed by the daemon.');
124
+ console.log('Access it via the monitor UI at http://localhost:3456');
125
+ console.log('\nTo view active wrappers: contextuate wrapper list');
126
+ console.log('To kill a wrapper: contextuate wrapper kill <wrapper-id>');
127
+ }
128
+ else {
129
+ console.error(`\nFailed to spawn Claude session: ${result.error}`);
130
+ process.exit(1);
131
+ }
132
+ }
133
+ /**
134
+ * List active wrappers
135
+ */
136
+ async function listWrappersCommand() {
137
+ return new Promise((resolve) => {
138
+ if (!fs.existsSync(DAEMON_SOCKET)) {
139
+ console.error('Daemon not running. Start with: contextuate monitor');
140
+ process.exit(1);
141
+ }
142
+ const socket = new net.Socket();
143
+ socket.connect(DAEMON_SOCKET, () => {
144
+ socket.write(JSON.stringify({ type: 'get_wrappers' }) + '\n');
145
+ });
146
+ socket.on('data', (data) => {
147
+ try {
148
+ const lines = data.toString().split('\n').filter(l => l.trim());
149
+ for (const line of lines) {
150
+ const response = JSON.parse(line);
151
+ if (response.type === 'wrappers_list') {
152
+ socket.end();
153
+ if (response.wrappers.length === 0) {
154
+ console.log('No active wrapper sessions.');
155
+ }
156
+ else {
157
+ console.log('Active wrapper sessions:\n');
158
+ for (const wrapper of response.wrappers) {
159
+ const type = wrapper.managed ? 'managed' : 'legacy';
160
+ console.log(` ${wrapper.wrapperId} [${type}]`);
161
+ console.log(` State: ${wrapper.state}`);
162
+ console.log(` PID: ${wrapper.pid}`);
163
+ console.log(` CWD: ${wrapper.cwd}`);
164
+ if (wrapper.claudeSessionId) {
165
+ console.log(` Claude Session: ${wrapper.claudeSessionId.slice(0, 8)}...`);
166
+ }
167
+ console.log();
168
+ }
169
+ }
170
+ resolve();
171
+ }
172
+ }
173
+ }
174
+ catch (err) {
175
+ // Ignore parse errors
176
+ }
177
+ });
178
+ socket.on('error', (err) => {
179
+ console.error(`Connection error: ${err.message}`);
180
+ process.exit(1);
181
+ });
182
+ setTimeout(() => {
183
+ socket.destroy();
184
+ console.error('Request timed out');
185
+ process.exit(1);
186
+ }, 5000);
187
+ });
188
+ }
189
+ /**
190
+ * Kill a wrapper session
191
+ */
192
+ async function killWrapperCommand(wrapperId) {
193
+ return new Promise((resolve) => {
194
+ if (!fs.existsSync(DAEMON_SOCKET)) {
195
+ console.error('Daemon not running. Start with: contextuate monitor');
196
+ process.exit(1);
197
+ }
198
+ const socket = new net.Socket();
199
+ socket.connect(DAEMON_SOCKET, () => {
200
+ socket.write(JSON.stringify({ type: 'kill_wrapper', wrapperId }) + '\n');
201
+ // Give daemon time to process, then close
202
+ setTimeout(() => {
203
+ socket.end();
204
+ console.log(`Kill request sent for wrapper ${wrapperId}`);
205
+ resolve();
206
+ }, 500);
207
+ });
208
+ socket.on('error', (err) => {
209
+ console.error(`Connection error: ${err.message}`);
210
+ process.exit(1);
211
+ });
212
+ });
213
+ }
@@ -0,0 +1 @@
1
+ export declare function addContextCommand(): Promise<void>;
@@ -0,0 +1,3 @@
1
+ export declare function createAgentCommand(name: string, options: {
2
+ description?: string;
3
+ }): Promise<void>;
@@ -0,0 +1,4 @@
1
+ export declare function indexCommand(options: {
2
+ depth?: string;
3
+ force?: boolean;
4
+ }): Promise<void>;
@@ -0,0 +1,7 @@
1
+ export declare function initCommand(platformArgs: string[] | {
2
+ force?: boolean;
3
+ agents?: string[];
4
+ }, options?: {
5
+ force?: boolean;
6
+ agents?: string[];
7
+ }): Promise<void>;
@@ -8,6 +8,37 @@ const inquirer_1 = __importDefault(require("inquirer"));
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const fs_extra_1 = __importDefault(require("fs-extra"));
10
10
  const path_1 = __importDefault(require("path"));
11
+ const fs_1 = require("fs");
12
+ // Get package version dynamically
13
+ function getPackageVersion() {
14
+ try {
15
+ const packageJson = JSON.parse((0, fs_1.readFileSync)(path_1.default.join(__dirname, '../../package.json'), 'utf-8'));
16
+ return packageJson.version;
17
+ }
18
+ catch {
19
+ return '0.0.0';
20
+ }
21
+ }
22
+ // Get package info for version.json
23
+ function getPackageInfo() {
24
+ try {
25
+ const packageJson = JSON.parse((0, fs_1.readFileSync)(path_1.default.join(__dirname, '../../package.json'), 'utf-8'));
26
+ return {
27
+ name: packageJson.name || 'contextuate',
28
+ version: packageJson.version || '0.0.0',
29
+ description: packageJson.description || 'AI Context Framework',
30
+ repository: packageJson.repository?.url?.replace('git+', '').replace('.git', '') || 'https://github.com/esotech/contextuate'
31
+ };
32
+ }
33
+ catch {
34
+ return {
35
+ name: 'contextuate',
36
+ version: '0.0.0',
37
+ description: 'AI Context Framework',
38
+ repository: 'https://github.com/esotech/contextuate'
39
+ };
40
+ }
41
+ }
11
42
  // Platform definitions with metadata
12
43
  const PLATFORMS = [
13
44
  { id: 'agents', name: 'Agents.ai', src: 'templates/platforms/AGENTS.md', dest: 'AGENTS.md' },
@@ -57,7 +88,7 @@ async function initCommand(platformArgs, options) {
57
88
  console.log(chalk_1.default.blue('╔════════════════════════════════════════╗'));
58
89
  console.log(chalk_1.default.blue('║ Contextuate Installer ║'));
59
90
  console.log(chalk_1.default.blue('║ AI Context Framework ║'));
60
- console.log(chalk_1.default.blue('║ Powered by Esotech ║'));
91
+ console.log(chalk_1.default.blue('║ ║'));
61
92
  console.log(chalk_1.default.blue('╚════════════════════════════════════════╝'));
62
93
  console.log('');
63
94
  try {
@@ -168,7 +199,11 @@ async function initCommand(platformArgs, options) {
168
199
  }
169
200
  if (opts.agents && opts.agents.length > 0) {
170
201
  // Non-interactive agent selection via --agents flag
171
- if (opts.agents.includes('all')) {
202
+ if (opts.agents.includes('none')) {
203
+ // Explicitly skip agent installation
204
+ console.log(chalk_1.default.blue('[INFO] Skipping agent installation (--agents none)'));
205
+ }
206
+ else if (opts.agents.includes('all')) {
172
207
  selectedAgents = availableAgents;
173
208
  console.log(chalk_1.default.blue('[INFO] Installing all agents'));
174
209
  }
@@ -185,7 +220,7 @@ async function initCommand(platformArgs, options) {
185
220
  console.log(chalk_1.default.yellow(`[WARN] Could not match agent "${agentArg}" - skipping`));
186
221
  }
187
222
  }
188
- if (selectedAgents.length === 0 && opts.agents.length > 0 && !opts.agents.includes('all')) {
223
+ if (selectedAgents.length === 0 && opts.agents.length > 0) {
189
224
  console.log(chalk_1.default.yellow('[WARN] No valid agents matched. Available agents:'));
190
225
  availableAgents.forEach(a => console.log(` - ${a}`));
191
226
  }
@@ -226,6 +261,11 @@ async function initCommand(platformArgs, options) {
226
261
  }
227
262
  }
228
263
  }
264
+ else {
265
+ // Non-interactive mode without --agents flag: default to all agents
266
+ selectedAgents = availableAgents;
267
+ console.log(chalk_1.default.blue('[INFO] Installing all agents (default in non-interactive mode)'));
268
+ }
229
269
  console.log('');
230
270
  console.log(chalk_1.default.blue('[INFO] Installing Contextuate framework...'));
231
271
  console.log('');
@@ -301,7 +341,18 @@ async function initCommand(platformArgs, options) {
301
341
  console.log(chalk_1.default.green(`[OK] Created: ${dest}`));
302
342
  };
303
343
  // Copy core engine files only to .contextuate
304
- await copyFile(path_1.default.join(templateSource, 'version.json'), path_1.default.join(installDir, 'version.json'));
344
+ // Generate version.json dynamically from package.json
345
+ const pkgInfo = getPackageInfo();
346
+ const versionData = {
347
+ name: pkgInfo.name,
348
+ version: pkgInfo.version,
349
+ description: pkgInfo.description,
350
+ repository: pkgInfo.repository,
351
+ installed: new Date().toISOString(),
352
+ updated: new Date().toISOString()
353
+ };
354
+ await fs_extra_1.default.writeFile(path_1.default.join(installDir, 'version.json'), JSON.stringify(versionData, null, 2));
355
+ console.log(chalk_1.default.green(`[OK] Created: ${path_1.default.join(installDir, 'version.json')}`));
305
356
  await copyFile(path_1.default.join(templateSource, 'README.md'), path_1.default.join(installDir, 'README.md'));
306
357
  // Copy directories - only core framework files
307
358
  const copyDirContents = async (srcSubDir, destDir) => {
@@ -337,7 +388,14 @@ async function initCommand(platformArgs, options) {
337
388
  // Copy contextuate.md (main entry point) directly from templates to docs/ai/.contextuate/ (protected)
338
389
  await copyFile(path_1.default.join(templateSource, 'templates/contextuate.md'), 'docs/ai/.contextuate/contextuate.md');
339
390
  // Copy context.md (user customizable) directly from templates to docs/ai/
340
- await copyFile(path_1.default.join(templateSource, 'templates/context.md'), 'docs/ai/context.md');
391
+ // IMPORTANT: Never overwrite context.md even with --force, as it contains project-specific context
392
+ const contextMdPath = 'docs/ai/context.md';
393
+ if (fs_extra_1.default.existsSync(contextMdPath)) {
394
+ console.log(chalk_1.default.yellow(`[WARN] Preserved (project context): ${contextMdPath}`));
395
+ }
396
+ else {
397
+ await copyFile(path_1.default.join(templateSource, 'templates/context.md'), contextMdPath);
398
+ }
341
399
  console.log('');
342
400
  // 5. Generate jump files for selected platforms
343
401
  console.log(chalk_1.default.blue('[INFO] Generating platform jump files...'));
@@ -391,6 +449,9 @@ async function initCommand(platformArgs, options) {
391
449
  { target: 'docs/ai/agents', link: '.claude/agents' },
392
450
  { target: 'docs/ai/hooks', link: '.claude/hooks' },
393
451
  { target: 'docs/ai/skills', link: '.claude/skills' },
452
+ // Link .contextuate so relative paths from agents work correctly
453
+ // (e.g., ../.contextuate/agents/base.md resolves properly)
454
+ { target: 'docs/ai/.contextuate', link: '.claude/.contextuate' },
394
455
  ];
395
456
  for (const symlink of symlinks) {
396
457
  await createSymlink(symlink.target, symlink.link);
@@ -429,7 +490,7 @@ async function initCommand(platformArgs, options) {
429
490
  console.log('');
430
491
  console.log('Documentation: https://contextuate.md');
431
492
  console.log('');
432
- console.log(chalk_1.default.gray('Powered by Esotech.'));
493
+ console.log(chalk_1.default.gray('Contextuate Framework'));
433
494
  console.log(chalk_1.default.gray('Created by Alexander Conroy (@geilt)'));
434
495
  console.log('');
435
496
  }
@@ -0,0 +1,28 @@
1
+ interface InstallOptions {
2
+ agents?: string[];
3
+ standards?: string[];
4
+ tools?: string[];
5
+ skills?: string[];
6
+ all?: boolean;
7
+ list?: boolean;
8
+ force?: boolean;
9
+ }
10
+ export declare function installAgentsCommand(names: string[], options: {
11
+ all?: boolean;
12
+ force?: boolean;
13
+ includeSkills?: boolean;
14
+ }): Promise<void>;
15
+ export declare function installStandardsCommand(names: string[], options: {
16
+ all?: boolean;
17
+ force?: boolean;
18
+ }): Promise<void>;
19
+ export declare function installToolsCommand(names: string[], options: {
20
+ all?: boolean;
21
+ force?: boolean;
22
+ }): Promise<void>;
23
+ export declare function installSkillsCommand(names: string[], options: {
24
+ all?: boolean;
25
+ force?: boolean;
26
+ }): Promise<void>;
27
+ export declare function installCommand(options: InstallOptions): Promise<void>;
28
+ export {};