gru-ai 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 (143) hide show
  1. package/.claude/skills/brainstorm/SKILL.md +340 -0
  2. package/.claude/skills/code-review-excellence/SKILL.md +198 -0
  3. package/.claude/skills/directive/SKILL.md +121 -0
  4. package/.claude/skills/directive/docs/pipeline/00-delegation-and-triage.md +181 -0
  5. package/.claude/skills/directive/docs/pipeline/01-checkpoint.md +34 -0
  6. package/.claude/skills/directive/docs/pipeline/02-read-directive.md +38 -0
  7. package/.claude/skills/directive/docs/pipeline/03-read-context.md +15 -0
  8. package/.claude/skills/directive/docs/pipeline/04-challenge.md +38 -0
  9. package/.claude/skills/directive/docs/pipeline/05-planning.md +64 -0
  10. package/.claude/skills/directive/docs/pipeline/06-technical-audit.md +88 -0
  11. package/.claude/skills/directive/docs/pipeline/07-plan-approval.md +145 -0
  12. package/.claude/skills/directive/docs/pipeline/07b-project-brainstorm.md +85 -0
  13. package/.claude/skills/directive/docs/pipeline/08-worktree-and-state.md +50 -0
  14. package/.claude/skills/directive/docs/pipeline/09-execute-projects.md +709 -0
  15. package/.claude/skills/directive/docs/pipeline/10-wrapup.md +242 -0
  16. package/.claude/skills/directive/docs/pipeline/11-completion-gate.md +75 -0
  17. package/.claude/skills/directive/docs/reference/rules/casting-rules.md +78 -0
  18. package/.claude/skills/directive/docs/reference/rules/failure-handling.md +20 -0
  19. package/.claude/skills/directive/docs/reference/rules/phase-definitions.md +42 -0
  20. package/.claude/skills/directive/docs/reference/rules/scope-and-dod.md +30 -0
  21. package/.claude/skills/directive/docs/reference/schemas/audit-output.md +44 -0
  22. package/.claude/skills/directive/docs/reference/schemas/brainstorm-output.md +52 -0
  23. package/.claude/skills/directive/docs/reference/schemas/challenger-output.md +13 -0
  24. package/.claude/skills/directive/docs/reference/schemas/checkpoint.md +18 -0
  25. package/.claude/skills/directive/docs/reference/schemas/current-json.md +5 -0
  26. package/.claude/skills/directive/docs/reference/schemas/directive-json.md +143 -0
  27. package/.claude/skills/directive/docs/reference/schemas/investigation-output.md +37 -0
  28. package/.claude/skills/directive/docs/reference/schemas/plan-schema.md +103 -0
  29. package/.claude/skills/directive/docs/reference/templates/architect-prompt.md +66 -0
  30. package/.claude/skills/directive/docs/reference/templates/auditor-prompt.md +53 -0
  31. package/.claude/skills/directive/docs/reference/templates/brainstorm-prompt.md +68 -0
  32. package/.claude/skills/directive/docs/reference/templates/challenger-prompt.md +35 -0
  33. package/.claude/skills/directive/docs/reference/templates/digest.md +134 -0
  34. package/.claude/skills/directive/docs/reference/templates/investigator-prompt.md +51 -0
  35. package/.claude/skills/directive/docs/reference/templates/planner-prompt.md +130 -0
  36. package/.claude/skills/frontend-design/SKILL.md +42 -0
  37. package/.claude/skills/gruai-agents/SKILL.md +161 -0
  38. package/.claude/skills/gruai-config/SKILL.md +61 -0
  39. package/.claude/skills/healthcheck/SKILL.md +216 -0
  40. package/.claude/skills/report/SKILL.md +380 -0
  41. package/.claude/skills/scout/SKILL.md +452 -0
  42. package/.claude/skills/seo-audit/SKILL.md +107 -0
  43. package/.claude/skills/walkthrough/SKILL.md +274 -0
  44. package/.claude/skills/webapp-testing/SKILL.md +96 -0
  45. package/LICENSE +21 -0
  46. package/README.md +206 -0
  47. package/cli/templates/CLAUDE.md.template +57 -0
  48. package/cli/templates/agent-roles/backend.md +47 -0
  49. package/cli/templates/agent-roles/cmo.md +52 -0
  50. package/cli/templates/agent-roles/content.md +48 -0
  51. package/cli/templates/agent-roles/coo.md +66 -0
  52. package/cli/templates/agent-roles/cpo.md +52 -0
  53. package/cli/templates/agent-roles/cto.md +63 -0
  54. package/cli/templates/agent-roles/data.md +46 -0
  55. package/cli/templates/agent-roles/design.md +46 -0
  56. package/cli/templates/agent-roles/frontend.md +47 -0
  57. package/cli/templates/agent-roles/fullstack.md +47 -0
  58. package/cli/templates/agent-roles/qa.md +46 -0
  59. package/cli/templates/backlog.json.template +3 -0
  60. package/cli/templates/directive.json.template +9 -0
  61. package/cli/templates/directive.md.template +23 -0
  62. package/cli/templates/goals-index.md +21 -0
  63. package/cli/templates/gruai.config.json.template +12 -0
  64. package/cli/templates/lessons.md +16 -0
  65. package/cli/templates/vision.md +35 -0
  66. package/cli/templates/welcome-directive/directive.json +9 -0
  67. package/cli/templates/welcome-directive/directive.md +53 -0
  68. package/dist/assets/GamePage-C5XQQOQH.js +49 -0
  69. package/dist/assets/README.md +17 -0
  70. package/dist/assets/characters/char_0.png +0 -0
  71. package/dist/assets/characters/char_1.png +0 -0
  72. package/dist/assets/characters/char_10.png +0 -0
  73. package/dist/assets/characters/char_11.png +0 -0
  74. package/dist/assets/characters/char_2.png +0 -0
  75. package/dist/assets/characters/char_3.png +0 -0
  76. package/dist/assets/characters/char_4.png +0 -0
  77. package/dist/assets/characters/char_5.png +0 -0
  78. package/dist/assets/characters/char_6.png +0 -0
  79. package/dist/assets/characters/char_7.png +0 -0
  80. package/dist/assets/characters/char_8.png +0 -0
  81. package/dist/assets/characters/char_9.png +0 -0
  82. package/dist/assets/index-CnTPDqpP.js +12 -0
  83. package/dist/assets/index-gR5q7ikB.css +1 -0
  84. package/dist/assets/office/furniture.png +0 -0
  85. package/dist/assets/office/room-builder.png +0 -0
  86. package/dist/index.html +16 -0
  87. package/dist-server/scripts/intelligence-trends.d.ts +100 -0
  88. package/dist-server/scripts/intelligence-trends.js +365 -0
  89. package/dist-server/server/actions/cleanup.d.ts +4 -0
  90. package/dist-server/server/actions/cleanup.js +30 -0
  91. package/dist-server/server/actions/send-input.d.ts +6 -0
  92. package/dist-server/server/actions/send-input.js +147 -0
  93. package/dist-server/server/actions/terminal.d.ts +4 -0
  94. package/dist-server/server/actions/terminal.js +427 -0
  95. package/dist-server/server/config.d.ts +9 -0
  96. package/dist-server/server/config.js +217 -0
  97. package/dist-server/server/db.d.ts +7 -0
  98. package/dist-server/server/db.js +79 -0
  99. package/dist-server/server/hooks/event-receiver.d.ts +11 -0
  100. package/dist-server/server/hooks/event-receiver.js +36 -0
  101. package/dist-server/server/index.d.ts +1 -0
  102. package/dist-server/server/index.js +552 -0
  103. package/dist-server/server/notifications/macos.d.ts +5 -0
  104. package/dist-server/server/notifications/macos.js +22 -0
  105. package/dist-server/server/notifications/notifier.d.ts +17 -0
  106. package/dist-server/server/notifications/notifier.js +110 -0
  107. package/dist-server/server/parsers/process-discovery.d.ts +39 -0
  108. package/dist-server/server/parsers/process-discovery.js +776 -0
  109. package/dist-server/server/parsers/session-scanner.d.ts +56 -0
  110. package/dist-server/server/parsers/session-scanner.js +390 -0
  111. package/dist-server/server/parsers/session-state.d.ts +68 -0
  112. package/dist-server/server/parsers/session-state.js +696 -0
  113. package/dist-server/server/parsers/session-state.test.d.ts +1 -0
  114. package/dist-server/server/parsers/session-state.test.js +950 -0
  115. package/dist-server/server/parsers/task-parser.d.ts +10 -0
  116. package/dist-server/server/parsers/task-parser.js +97 -0
  117. package/dist-server/server/parsers/team-parser.d.ts +3 -0
  118. package/dist-server/server/parsers/team-parser.js +67 -0
  119. package/dist-server/server/platform/__tests__/claude-code.test.d.ts +1 -0
  120. package/dist-server/server/platform/__tests__/claude-code.test.js +311 -0
  121. package/dist-server/server/platform/claude-code.d.ts +34 -0
  122. package/dist-server/server/platform/claude-code.js +94 -0
  123. package/dist-server/server/platform/index.d.ts +5 -0
  124. package/dist-server/server/platform/index.js +1 -0
  125. package/dist-server/server/platform/types.d.ts +190 -0
  126. package/dist-server/server/platform/types.js +9 -0
  127. package/dist-server/server/state/aggregator.d.ts +42 -0
  128. package/dist-server/server/state/aggregator.js +1080 -0
  129. package/dist-server/server/state/work-item-types.d.ts +555 -0
  130. package/dist-server/server/state/work-item-types.js +168 -0
  131. package/dist-server/server/types.d.ts +237 -0
  132. package/dist-server/server/types.js +1 -0
  133. package/dist-server/server/watchers/claude-watcher.d.ts +17 -0
  134. package/dist-server/server/watchers/claude-watcher.js +130 -0
  135. package/dist-server/server/watchers/context-watcher.d.ts +22 -0
  136. package/dist-server/server/watchers/context-watcher.js +125 -0
  137. package/dist-server/server/watchers/directive-watcher.d.ts +46 -0
  138. package/dist-server/server/watchers/directive-watcher.js +497 -0
  139. package/dist-server/server/watchers/session-watcher.d.ts +18 -0
  140. package/dist-server/server/watchers/session-watcher.js +126 -0
  141. package/dist-server/server/watchers/state-watcher.d.ts +36 -0
  142. package/dist-server/server/watchers/state-watcher.js +369 -0
  143. package/package.json +68 -0
@@ -0,0 +1,110 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { sendMacNotification } from './macos.js';
3
+ const DEDUP_WINDOW_MS = 30_000;
4
+ const CLEANUP_INTERVAL_MS = 60_000;
5
+ const NOTIFIABLE_STATUSES = new Set([
6
+ 'done',
7
+ 'waiting-input',
8
+ 'waiting-approval',
9
+ 'error',
10
+ ]);
11
+ export class Notifier extends EventEmitter {
12
+ dedup;
13
+ config;
14
+ aggregator;
15
+ prevSessions;
16
+ cleanupInterval;
17
+ constructor(aggregator, config) {
18
+ super();
19
+ this.aggregator = aggregator;
20
+ this.config = config;
21
+ this.dedup = new Map();
22
+ this.prevSessions = [];
23
+ this.cleanupInterval = null;
24
+ }
25
+ start() {
26
+ // Snapshot current sessions so we only notify on NEW transitions, not existing state
27
+ this.prevSessions = [...this.aggregator.getState().sessions];
28
+ this.aggregator.on('change', this.handleChange);
29
+ this.cleanupInterval = setInterval(() => {
30
+ const now = Date.now();
31
+ for (const [sessionId, lastNotifiedMs] of this.dedup) {
32
+ if (now - lastNotifiedMs > DEDUP_WINDOW_MS) {
33
+ this.dedup.delete(sessionId);
34
+ }
35
+ }
36
+ }, CLEANUP_INTERVAL_MS);
37
+ }
38
+ handleChange = (type) => {
39
+ if (type !== 'sessions_updated' && type !== 'event_added')
40
+ return;
41
+ const currentSessions = this.aggregator.getState().sessions;
42
+ const staleTeamSessionIds = this.getStaleTeamSessionIds();
43
+ for (const session of currentSessions) {
44
+ if (!NOTIFIABLE_STATUSES.has(session.status))
45
+ continue;
46
+ // Skip sessions belonging to stale teams
47
+ if (staleTeamSessionIds.has(session.id))
48
+ continue;
49
+ // Only notify on transitions INTO the notifiable status
50
+ const prev = this.prevSessions.find((s) => s.id === session.id);
51
+ if (prev?.status === session.status)
52
+ continue;
53
+ console.log(`[notifier] Transition: ${session.id.slice(0, 8)}… ${prev?.status ?? 'new'} → ${session.status}`);
54
+ this.notify(session);
55
+ }
56
+ this.prevSessions = [...currentSessions];
57
+ };
58
+ getStaleTeamSessionIds() {
59
+ const staleIds = new Set();
60
+ const { teams } = this.aggregator.getState();
61
+ for (const team of teams) {
62
+ if (!team.stale)
63
+ continue;
64
+ if (team.leadSessionId)
65
+ staleIds.add(team.leadSessionId);
66
+ for (const member of team.members) {
67
+ if (member.agentId)
68
+ staleIds.add(member.agentId);
69
+ }
70
+ }
71
+ return staleIds;
72
+ }
73
+ notify(session) {
74
+ const now = Date.now();
75
+ // Dedup: skip if notified within the window
76
+ const lastNotified = this.dedup.get(session.id);
77
+ if (lastNotified !== undefined && now - lastNotified < DEDUP_WINDOW_MS) {
78
+ console.log(`[notifier] Dedup skip: ${session.id.slice(0, 8)}… (${session.status})`);
79
+ return;
80
+ }
81
+ this.dedup.set(session.id, now);
82
+ const statusLabel = session.status === 'done'
83
+ ? 'Done'
84
+ : session.status === 'waiting-input'
85
+ ? 'Needs input'
86
+ : session.status === 'waiting-approval'
87
+ ? 'Needs approval'
88
+ : 'Error';
89
+ console.log(`[notifier] Sending: ${statusLabel} for ${session.id.slice(0, 8)}… (macOS: ${this.config.macOS}, browser: ${this.config.browser})`);
90
+ if (this.config.macOS) {
91
+ sendMacNotification(`Conductor: ${statusLabel}`, `Session ${session.id.slice(0, 8)}… in ${session.project}`);
92
+ }
93
+ const payload = {
94
+ sessionId: session.id,
95
+ suppressBrowser: this.config.macOS,
96
+ };
97
+ this.emit('notification_fired', payload);
98
+ }
99
+ updateConfig(config) {
100
+ this.config = config;
101
+ }
102
+ stop() {
103
+ this.aggregator.removeListener('change', this.handleChange);
104
+ if (this.cleanupInterval !== null) {
105
+ clearInterval(this.cleanupInterval);
106
+ this.cleanupInterval = null;
107
+ }
108
+ this.dedup.clear();
109
+ }
110
+ }
@@ -0,0 +1,39 @@
1
+ export interface ItermSessionInfo {
2
+ itermId: string;
3
+ tty: string;
4
+ name: string;
5
+ cwd?: string;
6
+ sessionId?: string;
7
+ }
8
+ export interface ClaudePaneMapping {
9
+ /** Map of tasks dir name (UUID or named) → pane ID (tmux "%N" or "iterm:{uniqueId}") */
10
+ byTasksDir: Map<string, string>;
11
+ /** Map of claude PID → tmux pane ID */
12
+ byPid: Map<number, string>;
13
+ /** Map of session UUID → pane ID (from project dir paths in lsof) */
14
+ bySessionId: Map<string, string>;
15
+ /** Map of normalized pane title → pane ID (for fuzzy matching with initialPrompt) */
16
+ byPaneTitle: Map<string, string>;
17
+ /** Map of pane ID → array of user prompt strings captured from scrollback */
18
+ panePrompts: Map<string, string[]>;
19
+ /** Map of claude PID → iTerm2 session info (non-tmux sessions) */
20
+ byItermSession: Map<number, ItermSessionInfo>;
21
+ /** iTerm sessions with no matching claude process (for CWD-based matching) */
22
+ orphanItermSessions: Array<{
23
+ itermId: string;
24
+ tty: string;
25
+ name: string;
26
+ cwd?: string;
27
+ candidateSessionIds: string[];
28
+ }>;
29
+ }
30
+ /**
31
+ * Discover all running claude processes and map them to tmux panes.
32
+ *
33
+ * Strategy:
34
+ * 1. Get all tmux pane PIDs
35
+ * 2. Find all `claude` processes via `pgrep`
36
+ * 3. Walk each claude process's parent chain to find its tmux pane
37
+ * 4. Extract tasks dir + session IDs from lsof (open files under ~/.claude/)
38
+ */
39
+ export declare function discoverClaudePanes(): Promise<ClaudePaneMapping>;