aios-core 4.2.3 → 4.2.4
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.
- package/.aios-core/core/registry/service-registry.json +6466 -6586
- package/.aios-core/core-config.yaml +10 -5
- package/.aios-core/data/aios-kb.md +19 -25
- package/.aios-core/data/entity-registry.yaml +311 -204
- package/.aios-core/data/registry-update-log.jsonl +8 -0
- package/.aios-core/development/tasks/db-squad-integration.md +3 -3
- package/.aios-core/development/tasks/dev-develop-story.md +1 -1
- package/.aios-core/development/tasks/integrate-squad.md +1 -1
- package/.aios-core/development/tasks/pr-automation.md +3 -3
- package/.aios-core/development/tasks/squad-creator-migrate.md +1 -1
- package/.aios-core/development/tasks/squad-creator-sync-ide-command.md +0 -2
- package/.aios-core/development/tasks/update-aios.md +2 -2
- package/.aios-core/development/tasks/validate-next-story.md +2 -99
- package/.aios-core/development/workflows/README.md +0 -4
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-V2.1.md +0 -1
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +3 -3
- package/.aios-core/docs/standards/QUALITY-GATES-SPECIFICATION.md +1 -1
- package/.aios-core/docs/standards/STANDARDS-INDEX.md +4 -4
- package/.aios-core/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +2 -2
- package/.aios-core/framework-config.yaml +8 -4
- package/.aios-core/infrastructure/scripts/ide-sync/README.md +29 -5
- package/.aios-core/infrastructure/scripts/ide-sync/gemini-commands.js +205 -0
- package/.aios-core/infrastructure/scripts/ide-sync/index.js +48 -11
- package/.aios-core/infrastructure/scripts/ide-sync/redirect-generator.js +1 -1
- package/.aios-core/infrastructure/scripts/test-utilities.js +1 -1
- package/.aios-core/infrastructure/scripts/tool-resolver.js +2 -2
- package/.aios-core/infrastructure/scripts/validate-claude-integration.js +101 -0
- package/.aios-core/infrastructure/scripts/validate-codex-integration.js +141 -0
- package/.aios-core/infrastructure/scripts/validate-gemini-integration.js +151 -0
- package/.aios-core/infrastructure/scripts/validate-parity.js +119 -0
- package/.aios-core/infrastructure/templates/aios-sync.yaml.template +0 -11
- package/.aios-core/install-manifest.yaml +83 -71
- package/.aios-core/local-config.yaml.template +2 -1
- package/.aios-core/presets/README.md +0 -1
- package/.aios-core/product/data/integration-patterns.md +1 -1
- package/.aios-core/product/templates/ide-rules/gemini-rules.md +87 -233
- package/.aios-core/product/templates/statusline/statusline-script.js +188 -0
- package/.aios-core/product/templates/statusline/track-agent.sh +68 -0
- package/.aios-core/user-guide.md +14 -19
- package/LICENSE +0 -27
- package/README.md +42 -6
- package/bin/aios-init.js +98 -54
- package/bin/modules/env-config.js +0 -1
- package/package.json +18 -5
- package/packages/gemini-aios-extension/README.md +13 -8
- package/packages/gemini-aios-extension/commands/aios-agent.js +7 -0
- package/packages/gemini-aios-extension/commands/aios-agents.js +2 -1
- package/packages/gemini-aios-extension/commands/aios-analyst.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-architect.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-data-engineer.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-dev.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-devops.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-master.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-menu.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-pm.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-po.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-qa.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-sm.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-squad-creator.js +6 -0
- package/packages/gemini-aios-extension/commands/aios-ux-design-expert.js +6 -0
- package/packages/gemini-aios-extension/commands/lib/agent-launcher.js +138 -0
- package/packages/gemini-aios-extension/extension.json +70 -0
- package/packages/gemini-aios-extension/gemini-extension.json +147 -0
- package/packages/gemini-aios-extension/hooks/hooks.json +67 -65
- package/packages/installer/src/config/ide-configs.js +10 -10
- package/packages/installer/src/config/templates/core-config-template.js +6 -3
- package/packages/installer/src/wizard/ide-config-generator.js +373 -2
- package/packages/installer/src/wizard/ide-selector.js +1 -1
- package/scripts/code-intel-health-check.js +125 -125
- package/scripts/ensure-manifest.js +58 -0
- package/.aios-core/infrastructure/scripts/ide-sync/transformers/windsurf.js +0 -106
- package/.aios-core/product/templates/ide-rules/cline-rules.md +0 -84
- package/.aios-core/product/templates/ide-rules/roo-rules.md +0 -86
- package/.aios-core/product/templates/ide-rules/windsurf-rules.md +0 -80
|
@@ -1,233 +1,87 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
##
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Hooks Configuration
|
|
91
|
-
AIOS can integrate with Gemini CLI hooks for enhanced context injection.
|
|
92
|
-
|
|
93
|
-
Configure in `.gemini/settings.json`:
|
|
94
|
-
```json
|
|
95
|
-
{
|
|
96
|
-
"hooks": {
|
|
97
|
-
"BeforeAgent": [{
|
|
98
|
-
"matcher": "*",
|
|
99
|
-
"hooks": [{
|
|
100
|
-
"name": "aios-context",
|
|
101
|
-
"type": "command",
|
|
102
|
-
"command": "node .aios-core/hooks/gemini/before-agent.js"
|
|
103
|
-
}]
|
|
104
|
-
}]
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Gemini CLI Lifecycle Events
|
|
110
|
-
Hooks can intercept these events:
|
|
111
|
-
- `SessionStart` - Load AIOS context
|
|
112
|
-
- `BeforeAgent` - Inject gotchas and patterns
|
|
113
|
-
- `BeforeTool` - Security validation
|
|
114
|
-
- `AfterTool` - Audit logging
|
|
115
|
-
- `SessionEnd` - Persist state
|
|
116
|
-
|
|
117
|
-
### Extensions
|
|
118
|
-
AIOS can be packaged as a Gemini CLI extension for easy installation:
|
|
119
|
-
```bash
|
|
120
|
-
gemini extensions install github.com/synkra/aios-gemini-extension
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Workflow Execution
|
|
124
|
-
|
|
125
|
-
### Task Execution Pattern
|
|
126
|
-
1. Read the complete task/workflow definition
|
|
127
|
-
2. Understand all elicitation points
|
|
128
|
-
3. Execute steps sequentially
|
|
129
|
-
4. Handle errors gracefully
|
|
130
|
-
5. Provide clear feedback
|
|
131
|
-
|
|
132
|
-
### Interactive Workflows
|
|
133
|
-
- Workflows with `elicit: true` require user input
|
|
134
|
-
- Present options clearly
|
|
135
|
-
- Validate user responses
|
|
136
|
-
- Provide helpful defaults
|
|
137
|
-
|
|
138
|
-
## Best Practices
|
|
139
|
-
|
|
140
|
-
### When implementing features:
|
|
141
|
-
- Check existing patterns first
|
|
142
|
-
- Reuse components and utilities
|
|
143
|
-
- Follow naming conventions
|
|
144
|
-
- Keep functions focused and testable
|
|
145
|
-
- Document complex logic
|
|
146
|
-
|
|
147
|
-
### When working with agents:
|
|
148
|
-
- Respect agent boundaries
|
|
149
|
-
- Use appropriate agent for each task
|
|
150
|
-
- Follow agent communication patterns
|
|
151
|
-
- Maintain agent context
|
|
152
|
-
|
|
153
|
-
### When handling errors:
|
|
154
|
-
```javascript
|
|
155
|
-
try {
|
|
156
|
-
// Operation
|
|
157
|
-
} catch (error) {
|
|
158
|
-
console.error(`Error in ${operation}:`, error);
|
|
159
|
-
throw new Error(`Failed to ${operation}: ${error.message}`);
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Git & GitHub Integration
|
|
164
|
-
|
|
165
|
-
### Commit Conventions
|
|
166
|
-
- Use conventional commits: `feat:`, `fix:`, `docs:`, `chore:`, etc.
|
|
167
|
-
- Reference story ID: `feat: implement feature [Story 2.1]`
|
|
168
|
-
- Keep commits atomic and focused
|
|
169
|
-
|
|
170
|
-
### Push Authority
|
|
171
|
-
**Only @devops agent can push to remote.** Other agents should prepare changes and hand off to @devops.
|
|
172
|
-
|
|
173
|
-
## Gemini CLI Commands
|
|
174
|
-
|
|
175
|
-
### AIOS Agent Commands
|
|
176
|
-
- `*help` - Show available commands
|
|
177
|
-
- `*create-story` - Create new story
|
|
178
|
-
- `*task {name}` - Execute specific task
|
|
179
|
-
- `*workflow {name}` - Run workflow
|
|
180
|
-
- `*exit` - Exit agent mode
|
|
181
|
-
|
|
182
|
-
### Useful Gemini CLI Commands
|
|
183
|
-
- `/settings` - Configure Gemini CLI
|
|
184
|
-
- `/hooks panel` - View active hooks
|
|
185
|
-
- `/extensions list` - List installed extensions
|
|
186
|
-
- `/rewind` - Revert to previous state
|
|
187
|
-
|
|
188
|
-
## Model Selection
|
|
189
|
-
|
|
190
|
-
Gemini CLI supports multiple models:
|
|
191
|
-
- **Gemini 3 Flash** - Fast, cost-effective for simple tasks
|
|
192
|
-
- **Gemini 3 Pro** - High quality for complex reasoning
|
|
193
|
-
|
|
194
|
-
Enable preview features in `/settings` to access latest models.
|
|
195
|
-
|
|
196
|
-
## Development Commands
|
|
197
|
-
|
|
198
|
-
```bash
|
|
199
|
-
npm run dev # Start development
|
|
200
|
-
npm test # Run tests
|
|
201
|
-
npm run lint # Check code style
|
|
202
|
-
npm run typecheck # Verify types
|
|
203
|
-
npm run build # Build project
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Debugging
|
|
207
|
-
|
|
208
|
-
### Enable Debug Mode
|
|
209
|
-
```bash
|
|
210
|
-
export AIOS_DEBUG=true
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
### View Agent Logs
|
|
214
|
-
```bash
|
|
215
|
-
tail -f .aios/logs/agent.log
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
## Performance Optimization
|
|
219
|
-
|
|
220
|
-
- Use parallel tool execution when possible
|
|
221
|
-
- Leverage Gemini's JSON output mode for structured responses
|
|
222
|
-
- Cache frequently accessed data during sessions
|
|
223
|
-
- Use `--output-format json` for programmatic integration
|
|
224
|
-
|
|
225
|
-
## Error Recovery
|
|
226
|
-
|
|
227
|
-
- Use `/rewind` to revert mistakes
|
|
228
|
-
- Always provide recovery suggestions for failures
|
|
229
|
-
- Include error context in messages
|
|
230
|
-
- Document any manual fixes required
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
*Synkra AIOS Gemini CLI Configuration v1.0*
|
|
1
|
+
# Gemini Rules - Synkra AIOS
|
|
2
|
+
|
|
3
|
+
Este arquivo define as instrucoes do projeto para Gemini CLI neste repositorio.
|
|
4
|
+
|
|
5
|
+
<!-- AIOS-MANAGED-START: core -->
|
|
6
|
+
## Core Rules
|
|
7
|
+
|
|
8
|
+
1. Siga a Constitution em `.aios-core/constitution.md`
|
|
9
|
+
2. Priorize `CLI First -> Observability Second -> UI Third`
|
|
10
|
+
3. Trabalhe por stories em `docs/stories/`
|
|
11
|
+
4. Nao invente requisitos fora dos artefatos existentes
|
|
12
|
+
<!-- AIOS-MANAGED-END: core -->
|
|
13
|
+
|
|
14
|
+
<!-- AIOS-MANAGED-START: quality -->
|
|
15
|
+
## Quality Gates
|
|
16
|
+
|
|
17
|
+
- Rode `npm run lint`
|
|
18
|
+
- Rode `npm run typecheck`
|
|
19
|
+
- Rode `npm test`
|
|
20
|
+
- Atualize checklist e file list da story antes de concluir
|
|
21
|
+
<!-- AIOS-MANAGED-END: quality -->
|
|
22
|
+
|
|
23
|
+
<!-- AIOS-MANAGED-START: codebase -->
|
|
24
|
+
## Project Map
|
|
25
|
+
|
|
26
|
+
- Core framework: `.aios-core/`
|
|
27
|
+
- CLI entrypoints: `bin/`
|
|
28
|
+
- Shared packages: `packages/`
|
|
29
|
+
- Tests: `tests/`
|
|
30
|
+
- Docs: `docs/`
|
|
31
|
+
<!-- AIOS-MANAGED-END: codebase -->
|
|
32
|
+
|
|
33
|
+
<!-- AIOS-MANAGED-START: gemini-integration -->
|
|
34
|
+
## Gemini Integration
|
|
35
|
+
|
|
36
|
+
Fonte de verdade de agentes:
|
|
37
|
+
- Canonico: `.aios-core/development/agents/*.md`
|
|
38
|
+
- Espelhado para Gemini: `.gemini/rules/AIOS/agents/*.md`
|
|
39
|
+
|
|
40
|
+
Hooks e settings:
|
|
41
|
+
- Hooks locais: `.gemini/hooks/`
|
|
42
|
+
- Settings locais: `.gemini/settings.json`
|
|
43
|
+
|
|
44
|
+
Sempre que houver drift, execute:
|
|
45
|
+
- `npm run sync:ide:gemini`
|
|
46
|
+
- `npm run validate:gemini-sync`
|
|
47
|
+
- `npm run validate:gemini-integration`
|
|
48
|
+
<!-- AIOS-MANAGED-END: gemini-integration -->
|
|
49
|
+
|
|
50
|
+
<!-- AIOS-MANAGED-START: parity -->
|
|
51
|
+
## Multi-IDE Parity
|
|
52
|
+
|
|
53
|
+
Para garantir paridade entre Claude Code, Codex e Gemini:
|
|
54
|
+
- `npm run validate:parity`
|
|
55
|
+
- `npm run validate:paths`
|
|
56
|
+
<!-- AIOS-MANAGED-END: parity -->
|
|
57
|
+
|
|
58
|
+
<!-- AIOS-MANAGED-START: activation -->
|
|
59
|
+
## Agent Activation
|
|
60
|
+
|
|
61
|
+
Preferencia de ativacao:
|
|
62
|
+
1. Use agentes em `.gemini/rules/AIOS/agents/`
|
|
63
|
+
2. Se necessario, use fonte canonica em `.aios-core/development/agents/`
|
|
64
|
+
|
|
65
|
+
Ao ativar agente:
|
|
66
|
+
- carregar definicao completa do agente
|
|
67
|
+
- renderizar greeting via `node .aios-core/development/scripts/generate-greeting.js <agent-id>`
|
|
68
|
+
- manter persona ativa ate `*exit`
|
|
69
|
+
|
|
70
|
+
Atalhos recomendados no Gemini:
|
|
71
|
+
- `/aios-menu` para listar agentes
|
|
72
|
+
- `/aios-<agent-id>` (ex.: `/aios-dev`, `/aios-architect`)
|
|
73
|
+
- `/aios-agent <agent-id>` para launcher generico
|
|
74
|
+
<!-- AIOS-MANAGED-END: activation -->
|
|
75
|
+
|
|
76
|
+
<!-- AIOS-MANAGED-START: commands -->
|
|
77
|
+
## Common Commands
|
|
78
|
+
|
|
79
|
+
- `npm run sync:ide`
|
|
80
|
+
- `npm run sync:ide:check`
|
|
81
|
+
- `npm run sync:ide:gemini`
|
|
82
|
+
- `npm run validate:gemini-sync`
|
|
83
|
+
- `npm run validate:gemini-integration`
|
|
84
|
+
- `npm run validate:parity`
|
|
85
|
+
- `npm run validate:structure`
|
|
86
|
+
- `npm run validate:agents`
|
|
87
|
+
<!-- AIOS-MANAGED-END: commands -->
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AIOS Unified Statusline v3 for Claude Code
|
|
5
|
+
*
|
|
6
|
+
* Displays: Session | Model | Context Bar | Time | Agent | Squad | Project:Branch | Git | Messages | Alert
|
|
7
|
+
*
|
|
8
|
+
* Installed automatically by `npx aios-core install` when no existing statusline is detected.
|
|
9
|
+
* Source: .aios-core/product/templates/statusline/
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const os = require('os');
|
|
16
|
+
|
|
17
|
+
let input = '';
|
|
18
|
+
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
19
|
+
|
|
20
|
+
process.stdin.on('end', () => {
|
|
21
|
+
try {
|
|
22
|
+
const data = JSON.parse(input);
|
|
23
|
+
console.log(buildStatusLine(data));
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.log(`err: ${error.message}`);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
function buildStatusLine(data) {
|
|
30
|
+
const reset = '\x1b[0m';
|
|
31
|
+
const bold = '\x1b[1m';
|
|
32
|
+
const dim = '\x1b[2m';
|
|
33
|
+
const red = '\x1b[31m';
|
|
34
|
+
const green = '\x1b[32m';
|
|
35
|
+
const yellow = '\x1b[33m';
|
|
36
|
+
const blue = '\x1b[34m';
|
|
37
|
+
const magenta = '\x1b[35m';
|
|
38
|
+
const cyan = '\x1b[36m';
|
|
39
|
+
const white = '\x1b[37m';
|
|
40
|
+
const orange = '\x1b[38;5;208m';
|
|
41
|
+
const boldBlue = `${bold}${blue}`;
|
|
42
|
+
const boldRed = `${bold}${red}`;
|
|
43
|
+
|
|
44
|
+
const parts = [];
|
|
45
|
+
|
|
46
|
+
// 1. Session ID (first 8 chars)
|
|
47
|
+
const sessionId = data.session_id || '';
|
|
48
|
+
if (sessionId) parts.push(`${dim}${sessionId.substring(0, 8)}${reset}`);
|
|
49
|
+
|
|
50
|
+
// 2. Model
|
|
51
|
+
const modelId = data.model?.id || '';
|
|
52
|
+
const modelName = formatModel(modelId);
|
|
53
|
+
if (modelName) parts.push(`${boldBlue}${modelName}${reset}`);
|
|
54
|
+
|
|
55
|
+
// 3. Context — progress bar + % + total (in/out)
|
|
56
|
+
const usedPct = data.context_window?.used_percentage ?? null;
|
|
57
|
+
const totalIn = data.context_window?.total_input_tokens ?? 0;
|
|
58
|
+
const totalOut = data.context_window?.total_output_tokens ?? 0;
|
|
59
|
+
if (usedPct !== null) {
|
|
60
|
+
const bar = progressBar(usedPct, 10);
|
|
61
|
+
const pctColor = usedPct > 80 ? red : usedPct > 60 ? yellow : green;
|
|
62
|
+
const totalTokens = totalIn + totalOut;
|
|
63
|
+
const inStr = fmtTokens(totalIn);
|
|
64
|
+
const outStr = fmtTokens(totalOut);
|
|
65
|
+
parts.push(`${bar} ${pctColor}${Math.round(usedPct)}%${reset} ${white}${fmtTokens(totalTokens)}${reset} ${dim}(\u2b07${inStr}/\u2b06${outStr})${reset}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 4. Time
|
|
69
|
+
const totalDuration = data.cost?.total_duration_ms ?? 0;
|
|
70
|
+
if (totalDuration > 0) {
|
|
71
|
+
const min = Math.floor(totalDuration / 60000);
|
|
72
|
+
const sec = Math.floor((totalDuration % 60000) / 1000);
|
|
73
|
+
parts.push(`${cyan}\u23f1 ${min}m${String(sec).padStart(2, '0')}s${reset}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 5 & 6. Agent & Squad (from session cache + API fallback)
|
|
77
|
+
const cache = readSessionCache();
|
|
78
|
+
const activeAgent = cache.agent || data.agent?.name || '';
|
|
79
|
+
const activeSquad = cache.squad || '';
|
|
80
|
+
if (activeAgent) parts.push(`${cyan}\ud83e\udd16 ${activeAgent}${reset}`);
|
|
81
|
+
if (activeSquad) parts.push(`${orange}\ud83c\udfaf ${activeSquad}${reset}`);
|
|
82
|
+
|
|
83
|
+
// 7. Project:Branch
|
|
84
|
+
const gitInfo = getGitInfo();
|
|
85
|
+
if (gitInfo.project) {
|
|
86
|
+
parts.push(`${yellow}${gitInfo.project}${reset}:${magenta}${gitInfo.branch}${reset}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 8. Git changes
|
|
90
|
+
const linesAdded = data.cost?.total_lines_added ?? 0;
|
|
91
|
+
const linesRemoved = data.cost?.total_lines_removed ?? 0;
|
|
92
|
+
const filesChanged = gitInfo.filesChanged;
|
|
93
|
+
if (linesAdded > 0 || linesRemoved > 0 || filesChanged > 0) {
|
|
94
|
+
const fc = filesChanged > 0 ? `${filesChanged}f ` : '';
|
|
95
|
+
parts.push(`\ud83d\udcdd ${white}${fc}${reset}${green}+${linesAdded}${reset} ${red}-${linesRemoved}${reset}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 9. Message count (from transcript JSONL)
|
|
99
|
+
const msgCount = countMessages(data.transcript_path);
|
|
100
|
+
if (msgCount > 0) {
|
|
101
|
+
parts.push(`${white}\ud83d\udd22 ${msgCount}${reset}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 10. Alert >200k
|
|
105
|
+
if (data.exceeds_200k_tokens) {
|
|
106
|
+
parts.push(`${boldRed}\u26a0 >200k!${reset}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return parts.join(' | ');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// --- Helpers ---
|
|
113
|
+
|
|
114
|
+
function formatModel(id) {
|
|
115
|
+
if (!id) return '';
|
|
116
|
+
if (id.includes('opus')) return 'Opus 4.6';
|
|
117
|
+
if (id.includes('sonnet')) return 'Sonnet 4.5';
|
|
118
|
+
if (id.includes('haiku')) return 'Haiku 4.5';
|
|
119
|
+
return id.split('-').slice(0, 2).join(' ');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function progressBar(pct, width) {
|
|
123
|
+
const filled = Math.round((pct / 100) * width);
|
|
124
|
+
const empty = width - filled;
|
|
125
|
+
const filledColor = pct > 80 ? '\x1b[31m' : pct > 60 ? '\x1b[33m' : '\x1b[32m';
|
|
126
|
+
return `${filledColor}${'\u2588'.repeat(filled)}${'\u2591'.repeat(empty)}\x1b[0m`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function fmtTokens(n) {
|
|
130
|
+
if (n >= 1000000) return `${(n / 1000000).toFixed(1)}M`;
|
|
131
|
+
if (n >= 1000) return `${Math.round(n / 1000)}k`;
|
|
132
|
+
return String(n);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function readSessionCache() {
|
|
136
|
+
try {
|
|
137
|
+
const cacheDir = path.join(os.homedir(), '.claude', 'session-cache');
|
|
138
|
+
const cwd = process.cwd();
|
|
139
|
+
const hash = simpleHash(cwd);
|
|
140
|
+
const cachePath = path.join(cacheDir, `${hash}.json`);
|
|
141
|
+
if (fs.existsSync(cachePath)) {
|
|
142
|
+
const cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
|
|
143
|
+
return { agent: cache.agent || '', squad: cache.squad || '' };
|
|
144
|
+
}
|
|
145
|
+
} catch {}
|
|
146
|
+
return { agent: '', squad: '' };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function simpleHash(str) {
|
|
150
|
+
let hash = 0;
|
|
151
|
+
for (let i = 0; i < str.length; i++) {
|
|
152
|
+
const char = str.charCodeAt(i);
|
|
153
|
+
hash = ((hash << 5) - hash) + char;
|
|
154
|
+
hash |= 0;
|
|
155
|
+
}
|
|
156
|
+
return Math.abs(hash).toString(16);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function getGitInfo() {
|
|
160
|
+
const result = { project: '', branch: '', filesChanged: 0 };
|
|
161
|
+
try {
|
|
162
|
+
const toplevel = execSync('git rev-parse --show-toplevel 2>/dev/null', { encoding: 'utf8', timeout: 3000 }).trim();
|
|
163
|
+
result.project = path.basename(toplevel);
|
|
164
|
+
result.branch = execSync('git rev-parse --abbrev-ref HEAD 2>/dev/null', { encoding: 'utf8', timeout: 3000 }).trim();
|
|
165
|
+
const status = execSync('git status --porcelain 2>/dev/null', { encoding: 'utf8', timeout: 3000 }).trim();
|
|
166
|
+
if (status) {
|
|
167
|
+
result.filesChanged = status.split('\n').filter(l => l.trim()).length;
|
|
168
|
+
}
|
|
169
|
+
} catch {}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function countMessages(transcriptPath) {
|
|
174
|
+
if (!transcriptPath) return 0;
|
|
175
|
+
try {
|
|
176
|
+
const content = fs.readFileSync(transcriptPath, 'utf8');
|
|
177
|
+
let count = 0;
|
|
178
|
+
for (const line of content.split('\n')) {
|
|
179
|
+
if (!line.trim()) continue;
|
|
180
|
+
try {
|
|
181
|
+
const entry = JSON.parse(line);
|
|
182
|
+
if (entry.type === 'user' || entry.type === 'human') count++;
|
|
183
|
+
} catch {}
|
|
184
|
+
}
|
|
185
|
+
return count;
|
|
186
|
+
} catch {}
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# AIOS Agent/Squad Tracker for Claude Code Statusline
|
|
3
|
+
# Called via Claude Code UserPromptSubmit hook
|
|
4
|
+
#
|
|
5
|
+
# Detects @agent, /squad:command, /ns:agents:name activations
|
|
6
|
+
# Writes to ~/.claude/session-cache/ for statusline-script.js to read
|
|
7
|
+
#
|
|
8
|
+
# Installed automatically by `npx aios-core install`
|
|
9
|
+
# Source: .aios-core/product/templates/statusline/
|
|
10
|
+
|
|
11
|
+
INPUT=$(cat)
|
|
12
|
+
|
|
13
|
+
node -e "
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const os = require('os');
|
|
17
|
+
|
|
18
|
+
let prompt = '';
|
|
19
|
+
try {
|
|
20
|
+
const j = JSON.parse(process.argv[1]);
|
|
21
|
+
prompt = j.prompt || j.message || '';
|
|
22
|
+
} catch {}
|
|
23
|
+
if (!prompt) process.exit(0);
|
|
24
|
+
|
|
25
|
+
function simpleHash(str) {
|
|
26
|
+
let h = 0;
|
|
27
|
+
for (let i = 0; i < str.length; i++) {
|
|
28
|
+
h = ((h << 5) - h) + str.charCodeAt(i);
|
|
29
|
+
h |= 0;
|
|
30
|
+
}
|
|
31
|
+
return Math.abs(h).toString(16);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const cacheDir = path.join(os.homedir(), '.claude', 'session-cache');
|
|
35
|
+
try { fs.mkdirSync(cacheDir, { recursive: true }); } catch {}
|
|
36
|
+
|
|
37
|
+
const hash = simpleHash(process.cwd());
|
|
38
|
+
const cacheFile = path.join(cacheDir, hash + '.json');
|
|
39
|
+
|
|
40
|
+
let agent = '', squad = '';
|
|
41
|
+
try {
|
|
42
|
+
const c = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
43
|
+
agent = c.agent || '';
|
|
44
|
+
squad = c.squad || '';
|
|
45
|
+
} catch {}
|
|
46
|
+
|
|
47
|
+
let changed = false;
|
|
48
|
+
|
|
49
|
+
if (/^\*exit\b/.test(prompt)) {
|
|
50
|
+
agent = ''; squad = '';
|
|
51
|
+
changed = true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const agentMatch = prompt.match(/@([a-zA-Z_-]+)/);
|
|
55
|
+
if (agentMatch) { agent = agentMatch[1]; changed = true; }
|
|
56
|
+
|
|
57
|
+
const nsMatch = prompt.match(/\/[a-zA-Z_-]+:agents:([a-zA-Z_-]+)/);
|
|
58
|
+
if (nsMatch) { agent = nsMatch[1]; changed = true; }
|
|
59
|
+
|
|
60
|
+
const squadMatch = prompt.match(/\/([a-zA-Z_-]+):[a-zA-Z_-]+/);
|
|
61
|
+
if (squadMatch && !/:agents:/.test(squadMatch[0])) { squad = squadMatch[1]; changed = true; }
|
|
62
|
+
|
|
63
|
+
if (changed) {
|
|
64
|
+
fs.writeFileSync(cacheFile, JSON.stringify({ agent, squad, updated: new Date().toISOString() }));
|
|
65
|
+
}
|
|
66
|
+
" "$INPUT"
|
|
67
|
+
|
|
68
|
+
exit 0
|