company-skill 2.2.3 → 3.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.
package/README.md CHANGED
@@ -10,7 +10,6 @@ A Claude Code skill that reads your team structure from `COMPANY.md`, runs every
10
10
 
11
11
  ## Install
12
12
 
13
- npm:
14
13
  ```bash
15
14
  npx company-skill install
16
15
  ```
@@ -27,73 +26,79 @@ Edit `COMPANY.md` with your team. Or skip it, the skill creates a minimal compan
27
26
  ```
28
27
  GOAL: "Build the auth system"
29
28
 
30
- THINK Leads break the goal into tasks
31
- EXECUTE Employees do the work
32
- VERIFY Built-in Reviewer + Critic check if the goal is met
29
+ THINK CEO picks relevant employees, leads assign tasks
30
+ EXECUTE Employees do the work, use installed skills
31
+ VERIFY Reviewer checks criteria.json, Advocate attacks results
33
32
 
34
- Not done? Loop back with feedback on what's missing.
35
- Done? Write STATUS.md, report to user.
33
+ Not done? Loop back with feedback.
34
+ Done? Update playbook, write STATUS.md.
36
35
  ```
37
36
 
38
- No arbitrary limit. The loop runs until ALL criteria in `criteria.json` pass. A Stop Hook blocks Claude from exiting early. To cancel: `touch .company/CANCEL`.
37
+ The loop runs until ALL criteria in `criteria.json` pass. A Stop Hook blocks Claude from exiting early. To cancel: `touch .company/CANCEL`.
38
+
39
+ ## Goal Enforcement
40
+
41
+ The skill creates `criteria.json` with checkable success criteria:
42
+
43
+ ```json
44
+ {"goal":"Build auth","criteria":[
45
+ {"id":1,"description":"OAuth2 login works with Google","passes":false,"evidence":null},
46
+ {"id":2,"description":"All tests pass","passes":false,"evidence":null}
47
+ ]}
48
+ ```
49
+
50
+ The reviewer updates `passes` to `true` with evidence as work completes. The stop hook reads this file and blocks exit until everything passes.
51
+
52
+ ## Self-Improvement
53
+
54
+ One file: `.company/playbook.md`. Accumulates across sessions.
55
+
56
+ After each session, the CEO writes:
57
+ - WORKED: what succeeded (with evidence)
58
+ - FAILED: what failed, USE INSTEAD: what works, WHY: the difference
59
+ - INEFFICIENT: what was slow, FASTER: better approach
60
+ - TOP: best employees for priority activation next time
61
+ - HIRE/FIRE: roles added or deactivated
62
+
63
+ Leads read the playbook before every THINK phase. Employees check failed approaches before proposing new ones. The company that starts session 5 is smarter than session 1.
64
+
65
+ The CEO also updates COMPANY.md: tags `[inactive]` on zero-contribution roles, `[priority]` on top performers, adds hired roles, evolves employee descriptions based on what they're good at.
39
66
 
40
67
  ## Built-In Roles
41
68
 
42
- Every company gets these employees automatically, even if your COMPANY.md is empty:
69
+ Every company gets these automatically:
43
70
 
44
71
  | Role | Phase | What they do |
45
72
  |------|-------|-------------|
46
- | CEO | THINK | Sets priorities, resolves conflicts |
73
+ | CEO | THINK | Picks relevant employees for the goal, resolves conflicts |
47
74
  | CTO | THINK | Technical decisions, architecture |
48
- | Internal Reviewer | VERIFY | Checks work against goal criteria |
75
+ | Internal Reviewer | VERIFY | Checks criteria.json, rejects findings without sources |
49
76
  | User Advocate | VERIFY | Represents the end user |
50
77
  | Devil's Advocate | VERIFY | Attacks results, finds holes |
51
78
  | Elegance Enforcer | VERIFY | Prevents over-engineering |
52
79
 
53
- If you define these roles in COMPANY.md, the skill uses your description instead. No duplicates.
54
-
55
- A minimal `/company "fix the login bug"` with no COMPANY.md runs: CEO + CTO + 2 auto-created engineers + 4 built-in reviewers = 8 employees.
80
+ Deduplicated if you define them in COMPANY.md.
56
81
 
57
- ## Write Your Company
82
+ ## Source Citations
58
83
 
59
- `COMPANY.md` adds your own employees on top of the built-ins:
84
+ Every finding needs a source:
85
+ - Existing claims: file path, URL, or command output
86
+ - Novel ideas: "NOVEL - needs validation" (reviewer adds a validation criterion)
60
87
 
61
- ```markdown
62
- # My Team
63
-
64
- ## Executive (Lead: CEO)
65
- - CEO, product vision, customer focus
66
- - CTO, architecture, technical standards
67
-
68
- ## Engineering (Lead: CTO)
69
- - Backend Developer, API, database
70
- - Frontend Developer, UI, components
71
- - DevOps Engineer, CI/CD, monitoring
72
-
73
- ## Priorities
74
- 1. [URGENT] Fix payment processing
75
- 2. [IMPORTANT] Add user dashboard
76
-
77
- ## Rules
78
- - No deploy without review
79
- ```
88
+ No source = rejected by reviewer.
80
89
 
81
90
  ## Commands
82
91
 
83
92
  ```
84
- /company "Build X" Run the company until X is done
85
- /company Run using priorities from COMPANY.md
86
- /company:run "Build X" Same as /company "Build X"
87
- /company:status Show last status without running
88
- /company:resume Continue from where last session stopped
93
+ /company "Build X" Run until X is done
94
+ /company Run using COMPANY.md priorities
95
+ /company:run "Build X" Same as above
96
+ /company:status Show last status
97
+ /company:resume Continue from last session
89
98
  ```
90
99
 
91
- Installs globally. Works from any directory.
92
-
93
100
  ## Visual Indicators
94
101
 
95
- When the skill runs, you see:
96
-
97
102
  ```
98
103
  ════════════════════════════════════════════════
99
104
  🏢 COMPANY SKILL ACTIVE
@@ -105,35 +110,28 @@ When the skill runs, you see:
105
110
 
106
111
  📋 CYCLE 1 VERDICT: NOT DONE
107
112
  Missing validation of compression ratios
108
-
109
- ════════════════════════════════════════════════
110
- 🏢 CYCLE 2 - THINK > EXECUTE > VERIFY
111
- ════════════════════════════════════════════════
112
-
113
- 📋 CYCLE 2 VERDICT: DONE
114
- All success criteria met
115
113
  ```
116
114
 
117
- Employees show with colors: leads (cyan), workers (green), reviewers (yellow), digest (gray). Skills are mandatory when installed.
115
+ Employees show with colors: leads (cyan), workers (green), reviewers (yellow), digest (gray).
118
116
 
119
117
  ## Agents
120
118
 
121
- | Agent | Phase | Color | Role |
122
- |-------|-------|-------|------|
123
- | company-lead | THINK | Cyan | Department leads, deciding what to do |
124
- | company-worker | EXECUTE | Green | Employees doing the actual work |
125
- | company-reviewer | VERIFY | Yellow | Internal Reviewer, checking quality |
126
- | company-critic | VERIFY | Yellow | Devil's Advocate, finding holes |
127
- | company-digest | COMPRESS | Gray | Compresses output between cycles |
119
+ | Agent | Phase | Color |
120
+ |-------|-------|-------|
121
+ | company-lead | THINK | Cyan |
122
+ | company-worker | EXECUTE | Green |
123
+ | company-reviewer | VERIFY | Yellow |
124
+ | company-critic | VERIFY | Yellow |
125
+ | company-digest | COMPRESS | Gray |
128
126
 
129
127
  ## Model Assignment
130
128
 
131
129
  | Phase | Model | Who |
132
130
  |-------|-------|-----|
133
- | THINK | Opus | CEO, CTO, department leads |
134
- | EXECUTE | Sonnet | Engineers, researchers, scouts |
135
- | VERIFY | Opus | Reviewer, Advocate, Enforcer, User Advocate |
136
- | COMPRESS | Haiku | Digest writer between cycles |
131
+ | THINK | Opus | CEO, CTO, leads |
132
+ | EXECUTE | Sonnet | Workers |
133
+ | VERIFY | Opus | Reviewers |
134
+ | COMPRESS | Haiku | Digest writer |
137
135
 
138
136
  Override per employee: `- ML Scientist, experiments [opus]`
139
137
 
@@ -153,27 +151,22 @@ Install manually for more:
153
151
  /plugin marketplace add obra/superpowers-marketplace
154
152
  /plugin marketplace add wshobson/agents
155
153
  /plugin marketplace add alirezarezvani/claude-skills
156
- npm i -g claude-mem
157
- npm i -g oh-my-claude-sisyphus
158
154
  ```
159
155
 
160
- When installed, employees MUST use them. Raw tools only when no skill matches the task.
156
+ When installed, employees MUST use them.
161
157
 
162
158
  ## What Gets Created
163
159
 
164
160
  ```
165
161
  .company/
166
- GOAL.md
167
- STATUS.md
168
- memory/{dept}.json
169
- messages/{dept}.jsonl
170
- cycles/
171
- cycle-0-briefing.md
172
- cycle-1-think-{dept}.md
173
- cycle-1-review.md
174
- cycle-1-advocate.md
175
- cycle-1-briefing.md
176
- {dept}/{employee}.md
162
+ criteria.json Machine-checkable goal state
163
+ playbook.md Accumulated lessons (self-improvement)
164
+ active-roster.md Employees activated for this goal
165
+ active-tasks.md Deduplicated task list
166
+ STATUS.md Final report
167
+ cycles/ Per-cycle briefings and reviews
168
+ messages/ Typed findings per department
169
+ {dept}/ Per-employee findings (persist across sessions)
177
170
  ```
178
171
 
179
172
  ## Examples
package/bin/install.js CHANGED
@@ -31,59 +31,66 @@ for (const agent of ['lead', 'worker', 'reviewer', 'critic', 'digest']) {
31
31
  if (fs.existsSync(src)) copyFile(src, path.join(agentsDir, `company-${agent}.md`));
32
32
  }
33
33
 
34
- // Install stop hook
35
- const hookSrc = path.join(srcDir, 'hooks', 'stop-guard.js');
36
- if (fs.existsSync(hookSrc)) {
37
- copyFile(hookSrc, path.join(hooksDir, 'company-stop-guard.js'));
38
-
39
- // Add to settings.json Stop hooks
40
- const settingsPath = path.join(home, '.claude', 'settings.json');
41
- try {
42
- const settings = fs.existsSync(settingsPath)
43
- ? JSON.parse(fs.readFileSync(settingsPath, 'utf8'))
44
- : {};
45
-
46
- if (!settings.hooks) settings.hooks = {};
47
- if (!settings.hooks.Stop) settings.hooks.Stop = [];
48
-
49
- const hookCmd = `node "${path.join(hooksDir, 'company-stop-guard.js')}"`;
50
- const exists = settings.hooks.Stop.some(h =>
51
- h.hooks && h.hooks.some(hh => hh.command && hh.command.includes('company-stop-guard'))
52
- );
53
-
54
- if (!exists) {
55
- settings.hooks.Stop.push({
56
- hooks: [{
57
- type: 'command',
58
- command: hookCmd,
59
- timeout: 5
60
- }]
61
- });
62
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
63
- console.log('Stop hook installed: company will not stop until goal is achieved.');
64
- }
65
- } catch (e) {
66
- console.log('Could not install stop hook (optional). Add manually to settings.json.');
34
+ // Install all hooks
35
+ const hookFiles = {
36
+ 'stop-guard.js': 'company-stop-guard.js',
37
+ 'precompact.js': 'company-precompact.js',
38
+ 'session-restore.js': 'company-session-restore.js'
39
+ };
40
+
41
+ for (const [src, dest] of Object.entries(hookFiles)) {
42
+ const srcPath = path.join(srcDir, 'hooks', src);
43
+ if (fs.existsSync(srcPath)) copyFile(srcPath, path.join(hooksDir, dest));
44
+ }
45
+
46
+ // Register hooks in settings.json
47
+ const settingsPath = path.join(home, '.claude', 'settings.json');
48
+ try {
49
+ const settings = fs.existsSync(settingsPath)
50
+ ? JSON.parse(fs.readFileSync(settingsPath, 'utf8'))
51
+ : {};
52
+
53
+ if (!settings.hooks) settings.hooks = {};
54
+
55
+ // Stop hook
56
+ if (!settings.hooks.Stop) settings.hooks.Stop = [];
57
+ if (!settings.hooks.Stop.some(h => h.hooks?.some(hh => hh.command?.includes('company-stop-guard')))) {
58
+ settings.hooks.Stop.push({ hooks: [{ type: 'command', command: `node "${path.join(hooksDir, 'company-stop-guard.js')}"`, timeout: 5 }] });
67
59
  }
60
+
61
+ // PreCompact hook
62
+ if (!settings.hooks.PreCompact) settings.hooks.PreCompact = [];
63
+ if (!settings.hooks.PreCompact.some(h => h.hooks?.some(hh => hh.command?.includes('company-precompact')))) {
64
+ settings.hooks.PreCompact.push({ hooks: [{ type: 'command', command: `node "${path.join(hooksDir, 'company-precompact.js')}"`, timeout: 5 }] });
65
+ }
66
+
67
+ // SessionStart hook (compact restore)
68
+ if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
69
+ if (!settings.hooks.SessionStart.some(h => h.hooks?.some(hh => hh.command?.includes('company-session-restore')))) {
70
+ settings.hooks.SessionStart.push({ matcher: 'compact', hooks: [{ type: 'command', command: `node "${path.join(hooksDir, 'company-session-restore.js')}"`, timeout: 5 }] });
71
+ }
72
+
73
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
74
+ console.log('Hooks installed: Stop guard + PreCompact + SessionStart restore');
75
+ } catch (e) {
76
+ console.log('Could not register hooks. Add manually to settings.json.');
68
77
  }
69
78
 
70
- // Create COMPANY.md template in cwd if missing
79
+ // Create COMPANY.md template
71
80
  const companyMd = path.join(process.cwd(), 'COMPANY.md');
72
81
  const template = path.join(srcDir, 'COMPANY.md.template');
73
82
  if (!fs.existsSync(companyMd) && fs.existsSync(template)) {
74
83
  fs.copyFileSync(template, companyMd);
75
- console.log('Created COMPANY.md template. Edit it with your team.');
84
+ console.log('Created COMPANY.md template.');
76
85
  }
77
86
 
78
- // Add .company/ to .gitignore
79
- const gitignore = path.join(process.cwd(), '.gitignore');
87
+ // Gitignore
80
88
  try {
81
- const content = fs.existsSync(gitignore) ? fs.readFileSync(gitignore, 'utf8') : '';
82
- if (!content.includes('.company/')) {
83
- fs.appendFileSync(gitignore, '\n.company/\n');
84
- }
89
+ const gi = path.join(process.cwd(), '.gitignore');
90
+ const content = fs.existsSync(gi) ? fs.readFileSync(gi, 'utf8') : '';
91
+ if (!content.includes('.company/')) fs.appendFileSync(gi, '\n.company/\n');
85
92
  } catch (e) {}
86
93
 
87
- console.log('company-skill installed globally.');
94
+ console.log('company-skill installed.');
88
95
  console.log('Commands: /company, /company:run, /company:status, /company:resume');
89
- console.log('To cancel a running company: touch .company/CANCEL');
96
+ console.log('Cancel: touch .company/CANCEL');
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ // PostToolUse on Edit/Write: run compiler/linter immediately after code changes.
4
+ // Catches errors before Claude moves on to the next task.
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const { execSync } = require('child_process');
9
+
10
+ // Read tool input from stdin
11
+ let input = '';
12
+ try { input = fs.readFileSync('/dev/stdin', 'utf8'); } catch (e) {}
13
+
14
+ let filePath;
15
+ try {
16
+ const data = JSON.parse(input);
17
+ filePath = data.tool_response?.filePath || data.tool_input?.file_path;
18
+ } catch (e) {}
19
+
20
+ if (!filePath) process.exit(0);
21
+
22
+ const ext = path.extname(filePath);
23
+ let cmd = null;
24
+
25
+ if (['.ts', '.tsx'].includes(ext)) cmd = `npx tsc --noEmit "${filePath}" 2>&1 | head -5`;
26
+ else if (['.js', '.jsx'].includes(ext)) cmd = `node --check "${filePath}" 2>&1`;
27
+ else if (ext === '.py') cmd = `python3 -c "import py_compile; py_compile.compile('${filePath}', doraise=True)" 2>&1`;
28
+ else if (ext === '.json') cmd = `node -e "JSON.parse(require('fs').readFileSync('${filePath}','utf8'))" 2>&1`;
29
+
30
+ if (!cmd) process.exit(0);
31
+
32
+ try {
33
+ execSync(cmd, { timeout: 10000 });
34
+ } catch (e) {
35
+ const err = (e.stdout?.toString() || e.message).substring(0, 300);
36
+ console.log(JSON.stringify({
37
+ systemMessage: "Compile/syntax error in " + path.basename(filePath) + ": " + err
38
+ }));
39
+ }
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Save company state AND reasoning before context compaction.
4
+ // Saves both numbers (criteria, cycle) and intent (what we're trying and why).
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ const companyDir = path.join(process.cwd(), '.company');
10
+ if (!fs.existsSync(companyDir)) process.exit(0);
11
+
12
+ const lines = ['# Company Checkpoint (auto-saved before compaction)', ''];
13
+
14
+ // Goal
15
+ const goalPath = path.join(companyDir, 'GOAL.md');
16
+ if (fs.existsSync(goalPath)) {
17
+ lines.push('## Goal');
18
+ lines.push(fs.readFileSync(goalPath, 'utf8').substring(0, 500));
19
+ lines.push('');
20
+ }
21
+
22
+ // Cycle number
23
+ const cyclesDir = path.join(companyDir, 'cycles');
24
+ if (fs.existsSync(cyclesDir)) {
25
+ const files = fs.readdirSync(cyclesDir).filter(f => f.startsWith('cycle-'));
26
+ const nums = files.map(f => parseInt(f.match(/cycle-(\d+)/)?.[1] || '0'));
27
+ const cycle = Math.max(0, ...nums);
28
+ lines.push('## Cycle: ' + cycle);
29
+ lines.push('');
30
+
31
+ // Latest briefing (captures current reasoning/intent)
32
+ const briefing = path.join(cyclesDir, `cycle-${cycle}-briefing.md`);
33
+ if (fs.existsSync(briefing)) {
34
+ lines.push('## Current Reasoning');
35
+ lines.push(fs.readFileSync(briefing, 'utf8').substring(0, 1000));
36
+ lines.push('');
37
+ }
38
+
39
+ // Latest review (captures what's working/failing)
40
+ const review = path.join(cyclesDir, `cycle-${cycle}-review.md`);
41
+ if (fs.existsSync(review)) {
42
+ lines.push('## Latest Review');
43
+ lines.push(fs.readFileSync(review, 'utf8').substring(0, 500));
44
+ lines.push('');
45
+ }
46
+ }
47
+
48
+ // Criteria status
49
+ const criteriaPath = path.join(companyDir, 'criteria.json');
50
+ if (fs.existsSync(criteriaPath)) {
51
+ try {
52
+ const data = JSON.parse(fs.readFileSync(criteriaPath, 'utf8'));
53
+ const all = data.criteria || [];
54
+ lines.push('## Criteria: ' + all.filter(c => c.passes).length + '/' + all.length + ' passing');
55
+ for (const c of all) {
56
+ lines.push('- [' + (c.passes ? 'x' : ' ') + '] ' + c.description);
57
+ }
58
+ lines.push('');
59
+ } catch (e) {}
60
+ }
61
+
62
+ // Active roster
63
+ const rosterPath = path.join(companyDir, 'active-roster.md');
64
+ if (fs.existsSync(rosterPath)) {
65
+ lines.push('## Active Roster');
66
+ lines.push(fs.readFileSync(rosterPath, 'utf8').substring(0, 300));
67
+ lines.push('');
68
+ }
69
+
70
+ // Playbook (accumulated lessons)
71
+ const playbookPath = path.join(companyDir, 'playbook.md');
72
+ if (fs.existsSync(playbookPath)) {
73
+ lines.push('## Playbook (lessons)');
74
+ lines.push(fs.readFileSync(playbookPath, 'utf8').substring(0, 500));
75
+ lines.push('');
76
+ }
77
+
78
+ lines.push('## Next Action');
79
+ lines.push('Read .company/criteria.json and continue THINK > EXECUTE > VERIFY.');
80
+
81
+ fs.writeFileSync(path.join(companyDir, '.checkpoint.md'), lines.join('\n'));
82
+ process.exit(0);
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Restore company state after compaction. Reads the checkpoint with reasoning + state.
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+
8
+ const companyDir = path.join(process.cwd(), '.company');
9
+ if (!fs.existsSync(companyDir)) process.exit(0);
10
+
11
+ const checkpointMd = path.join(companyDir, '.checkpoint.md');
12
+ const checkpointJson = path.join(companyDir, '.checkpoint.json');
13
+
14
+ let msg = null;
15
+
16
+ if (fs.existsSync(checkpointMd)) {
17
+ msg = fs.readFileSync(checkpointMd, 'utf8').substring(0, 2000);
18
+ } else if (fs.existsSync(checkpointJson)) {
19
+ try {
20
+ const cp = JSON.parse(fs.readFileSync(checkpointJson, 'utf8'));
21
+ msg = "[COMPANY RESTORED] Goal: " + (cp.goal || "unknown") +
22
+ ", Cycle: " + (cp.cycle || 0) +
23
+ ", Criteria: " + (cp.passing || 0) + "/" + (cp.total || 0) +
24
+ ". Read .company/criteria.json and continue.";
25
+ } catch (e) {}
26
+ }
27
+
28
+ if (msg) {
29
+ console.log(JSON.stringify({ systemMessage: msg }));
30
+ }
@@ -3,19 +3,35 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
 
6
- const criteriaPath = path.join(process.cwd(), '.company', 'criteria.json');
7
- const goalPath = path.join(process.cwd(), '.company', 'GOAL.md');
8
- const cancelPath = path.join(process.cwd(), '.company', 'CANCEL');
9
-
6
+ const cwd = process.cwd();
7
+ const companyDir = path.join(cwd, '.company');
8
+ const criteriaPath = path.join(companyDir, 'criteria.json');
9
+ const goalPath = path.join(companyDir, 'GOAL.md');
10
+ const cancelPath = path.join(companyDir, 'CANCEL');
11
+ const counterPath = path.join(companyDir, '.stop-counter');
12
+
13
+ // No company running
10
14
  if (!fs.existsSync(goalPath) && !fs.existsSync(criteriaPath)) {
11
15
  process.exit(0);
12
16
  }
13
17
 
18
+ // Cancel signal
14
19
  if (fs.existsSync(cancelPath)) {
15
20
  try { fs.unlinkSync(cancelPath); } catch (e) {}
16
21
  process.exit(0);
17
22
  }
18
23
 
24
+ // Circuit breaker: max 10 blocks then allow stop
25
+ let count = 0;
26
+ try { count = parseInt(fs.readFileSync(counterPath, 'utf8')) || 0; } catch (e) {}
27
+ count++;
28
+ try { fs.writeFileSync(counterPath, String(count)); } catch (e) {}
29
+ if (count > 10) {
30
+ try { fs.unlinkSync(counterPath); } catch (e) {}
31
+ process.exit(0); // Allow stop, prevent infinite loop
32
+ }
33
+
34
+ // Check criteria
19
35
  if (fs.existsSync(criteriaPath)) {
20
36
  try {
21
37
  const data = JSON.parse(fs.readFileSync(criteriaPath, 'utf8'));
@@ -23,31 +39,23 @@ if (fs.existsSync(criteriaPath)) {
23
39
  const failing = all.filter(c => !c.passes || !c.evidence);
24
40
 
25
41
  if (all.length > 0 && failing.length === 0) {
26
- process.exit(0);
42
+ try { fs.unlinkSync(counterPath); } catch (e) {}
43
+ process.exit(0); // All pass, allow stop
27
44
  }
28
45
 
29
46
  const failList = failing.map(c => c.description).join(', ');
30
47
  console.log(JSON.stringify({
31
48
  continue: false,
32
- stopReason: failing.length + "/" + all.length + " criteria not met. Continue working.",
33
- systemMessage: "COMPANY GOAL NOT ACHIEVED. " + failing.length + " criteria still failing: " + failList + ". Read .company/criteria.json and start the next THINK > EXECUTE > VERIFY cycle."
49
+ message: "[COMPANY CYCLE] " + failing.length + "/" + all.length + " criteria not met: " + failList + ". Continue THINK > EXECUTE > VERIFY. Read .company/criteria.json."
34
50
  }));
35
51
  process.exit(0);
36
52
  } catch (e) {
37
- process.exit(0);
38
- }
39
- }
40
-
41
- const statusPath = path.join(process.cwd(), '.company', 'STATUS.md');
42
- if (fs.existsSync(statusPath)) {
43
- const status = fs.readFileSync(statusPath, 'utf8');
44
- if (status.includes('ACHIEVED')) {
45
- process.exit(0);
53
+ process.exit(0); // Malformed, allow stop
46
54
  }
47
55
  }
48
56
 
57
+ // No criteria but goal exists
49
58
  console.log(JSON.stringify({
50
59
  continue: false,
51
- stopReason: "Company goal not yet achieved.",
52
- systemMessage: "COMPANY GOAL NOT ACHIEVED. Read .company/criteria.json and .company/GOAL.md. Start the next THINK > EXECUTE > VERIFY cycle."
60
+ message: "[COMPANY] Goal not achieved. Read .company/GOAL.md and create criteria.json, then start THINK > EXECUTE > VERIFY."
53
61
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "company-skill",
3
- "version": "2.2.3",
3
+ "version": "3.1.0",
4
4
  "description": "Goal-driven multi-employee company for Claude Code. Give it a goal, it runs until done.",
5
5
  "bin": {
6
6
  "company-skill": "./bin/install.js"