fivocell 4.1.8 → 4.2.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/dist/__tests__/agents-md.test.d.ts +2 -0
- package/dist/__tests__/agents-md.test.d.ts.map +1 -0
- package/dist/__tests__/agents-md.test.js +141 -0
- package/dist/__tests__/agents-md.test.js.map +1 -0
- package/dist/__tests__/atcell-live-fallback.test.d.ts +2 -0
- package/dist/__tests__/atcell-live-fallback.test.d.ts.map +1 -0
- package/dist/__tests__/atcell-live-fallback.test.js +138 -0
- package/dist/__tests__/atcell-live-fallback.test.js.map +1 -0
- package/dist/__tests__/watch-cli.test.d.ts +2 -0
- package/dist/__tests__/watch-cli.test.d.ts.map +1 -0
- package/dist/__tests__/watch-cli.test.js +98 -0
- package/dist/__tests__/watch-cli.test.js.map +1 -0
- package/dist/cli.js +54 -8
- package/dist/cli.js.map +1 -1
- package/dist/core/agents-md.d.ts +22 -0
- package/dist/core/agents-md.d.ts.map +1 -0
- package/dist/core/agents-md.js +164 -0
- package/dist/core/agents-md.js.map +1 -0
- package/dist/core/prompt-builder.d.ts +5 -0
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +32 -0
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/watch-cli.d.ts +11 -0
- package/dist/core/watch-cli.d.ts.map +1 -0
- package/dist/core/watch-cli.js +71 -0
- package/dist/core/watch-cli.js.map +1 -0
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +60 -4
- package/dist/daemon/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/agents-md.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const fs = __importStar(require("fs"));
|
|
37
|
+
const os = __importStar(require("os"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const agents_md_1 = require("../core/agents-md");
|
|
40
|
+
describe('agents-md (AGENTS.md + .cursorrules writers)', () => {
|
|
41
|
+
let tmpDir;
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cell-agents-md-'));
|
|
44
|
+
});
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
try {
|
|
47
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
48
|
+
}
|
|
49
|
+
catch { }
|
|
50
|
+
});
|
|
51
|
+
describe('templates', () => {
|
|
52
|
+
it('AGENTS_MD_TEMPLATE declares FIVO Cell rules and the @cell convention', () => {
|
|
53
|
+
expect(agents_md_1.AGENTS_MD_TEMPLATE).toContain(agents_md_1.CELL_RULES_MARKER);
|
|
54
|
+
expect(agents_md_1.AGENTS_MD_TEMPLATE).toContain('@cell');
|
|
55
|
+
expect(agents_md_1.AGENTS_MD_TEMPLATE).toContain('cell_get_context');
|
|
56
|
+
expect(agents_md_1.AGENTS_MD_TEMPLATE).toContain('cell_session_start');
|
|
57
|
+
expect(agents_md_1.AGENTS_MD_TEMPLATE).toContain('path.basename(process.cwd())');
|
|
58
|
+
});
|
|
59
|
+
it('CURSORRULES_TEMPLATE mentions @cell and cell_get_context', () => {
|
|
60
|
+
expect(agents_md_1.CURSORRULES_TEMPLATE).toContain(agents_md_1.CELL_RULES_MARKER);
|
|
61
|
+
expect(agents_md_1.CURSORRULES_TEMPLATE).toContain('@cell');
|
|
62
|
+
expect(agents_md_1.CURSORRULES_TEMPLATE).toContain('cell_get_context');
|
|
63
|
+
});
|
|
64
|
+
it('isCellRulesFile detects the marker in any file content', () => {
|
|
65
|
+
expect((0, agents_md_1.isCellRulesFile)(agents_md_1.AGENTS_MD_TEMPLATE)).toBe(true);
|
|
66
|
+
expect((0, agents_md_1.isCellRulesFile)('# User custom rules')).toBe(false);
|
|
67
|
+
expect((0, agents_md_1.isCellRulesFile)('partial marker mention')).toBe(false);
|
|
68
|
+
expect((0, agents_md_1.isCellRulesFile)('# fivo-cell:rules:v1\n# body')).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe('writeAgentsMd', () => {
|
|
72
|
+
it('writes AGENTS.md to project root', () => {
|
|
73
|
+
const result = (0, agents_md_1.writeAgentsMd)(tmpDir);
|
|
74
|
+
expect(result).toBe('written');
|
|
75
|
+
const filePath = path.join(tmpDir, agents_md_1.AGENTS_MD_FILENAME);
|
|
76
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
77
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
78
|
+
expect(content).toBe(agents_md_1.AGENTS_MD_TEMPLATE);
|
|
79
|
+
});
|
|
80
|
+
it('does not overwrite existing AGENTS.md (idempotent — respects user edits)', () => {
|
|
81
|
+
const filePath = path.join(tmpDir, agents_md_1.AGENTS_MD_FILENAME);
|
|
82
|
+
const custom = '# My custom team rules\nDo not touch this file.\n';
|
|
83
|
+
fs.writeFileSync(filePath, custom, 'utf8');
|
|
84
|
+
const result = (0, agents_md_1.writeAgentsMd)(tmpDir);
|
|
85
|
+
expect(result).toBe('exists');
|
|
86
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
87
|
+
expect(content).toBe(custom);
|
|
88
|
+
});
|
|
89
|
+
it('overwrites existing AGENTS.md when overwrite: true', () => {
|
|
90
|
+
const filePath = path.join(tmpDir, agents_md_1.AGENTS_MD_FILENAME);
|
|
91
|
+
fs.writeFileSync(filePath, 'old content', 'utf8');
|
|
92
|
+
const result = (0, agents_md_1.writeAgentsMd)(tmpDir, { overwrite: true });
|
|
93
|
+
expect(result).toBe('written');
|
|
94
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
95
|
+
expect(content).toBe(agents_md_1.AGENTS_MD_TEMPLATE);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe('writeCursorRules', () => {
|
|
99
|
+
it('writes .cursorrules to project root', () => {
|
|
100
|
+
const result = (0, agents_md_1.writeCursorRules)(tmpDir);
|
|
101
|
+
expect(result).toBe('written');
|
|
102
|
+
const filePath = path.join(tmpDir, agents_md_1.CURSORRULES_FILENAME);
|
|
103
|
+
expect(fs.existsSync(filePath)).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
it('does not overwrite existing .cursorrules', () => {
|
|
106
|
+
const filePath = path.join(tmpDir, agents_md_1.CURSORRULES_FILENAME);
|
|
107
|
+
fs.writeFileSync(filePath, 'user rules', 'utf8');
|
|
108
|
+
const result = (0, agents_md_1.writeCursorRules)(tmpDir);
|
|
109
|
+
expect(result).toBe('exists');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('writeCellRules', () => {
|
|
113
|
+
it('writes both files on a fresh project', () => {
|
|
114
|
+
const r = (0, agents_md_1.writeCellRules)(tmpDir);
|
|
115
|
+
expect(r.agentsMd).toBe('written');
|
|
116
|
+
expect(r.cursorRules).toBe('written');
|
|
117
|
+
expect(fs.existsSync(path.join(tmpDir, agents_md_1.AGENTS_MD_FILENAME))).toBe(true);
|
|
118
|
+
expect(fs.existsSync(path.join(tmpDir, agents_md_1.CURSORRULES_FILENAME))).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
it('returns exists for both when both files already present', () => {
|
|
121
|
+
fs.writeFileSync(path.join(tmpDir, agents_md_1.AGENTS_MD_FILENAME), 'x', 'utf8');
|
|
122
|
+
fs.writeFileSync(path.join(tmpDir, agents_md_1.CURSORRULES_FILENAME), 'y', 'utf8');
|
|
123
|
+
const r = (0, agents_md_1.writeCellRules)(tmpDir);
|
|
124
|
+
expect(r.agentsMd).toBe('exists');
|
|
125
|
+
expect(r.cursorRules).toBe('exists');
|
|
126
|
+
});
|
|
127
|
+
it('skips .cursorrules when cursor: false', () => {
|
|
128
|
+
const r = (0, agents_md_1.writeCellRules)(tmpDir, { cursor: false });
|
|
129
|
+
expect(r.agentsMd).toBe('written');
|
|
130
|
+
expect(r.cursorRules).toBe('skipped');
|
|
131
|
+
expect(fs.existsSync(path.join(tmpDir, agents_md_1.CURSORRULES_FILENAME))).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
describe('filename constants', () => {
|
|
135
|
+
it('exports the correct filenames', () => {
|
|
136
|
+
expect(agents_md_1.AGENTS_MD_FILENAME).toBe('AGENTS.md');
|
|
137
|
+
expect(agents_md_1.CURSORRULES_FILENAME).toBe('.cursorrules');
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=agents-md.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.test.js","sourceRoot":"","sources":["../../src/__tests__/agents-md.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atcell-live-fallback.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/atcell-live-fallback.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const prompt_builder_1 = require("../core/prompt-builder");
|
|
4
|
+
const mockDb = {
|
|
5
|
+
prepare: jest.fn(),
|
|
6
|
+
};
|
|
7
|
+
jest.mock('../core/database', () => ({
|
|
8
|
+
getDb: () => mockDb,
|
|
9
|
+
}));
|
|
10
|
+
function fakeStmt(rows) {
|
|
11
|
+
return {
|
|
12
|
+
all: (..._args) => rows,
|
|
13
|
+
get: (..._args) => rows[0] || undefined,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
describe('@cell live_event fallback (regression for v4.1.8 UX bug)', () => {
|
|
17
|
+
function setupMocks(opts = {}) {
|
|
18
|
+
const profileTs = opts.profileScannedAt || new Date().toISOString();
|
|
19
|
+
mockDb.prepare.mockReset();
|
|
20
|
+
mockDb.prepare.mockImplementation((sql) => {
|
|
21
|
+
const s = sql.trim().toUpperCase();
|
|
22
|
+
if (s.startsWith('SELECT * FROM DEVELOPER_PROFILES')) {
|
|
23
|
+
return fakeStmt([{ id: 1, project: 'fivo-cell', files_scanned: 100, total_lines: 5000, scanned_at: profileTs }]);
|
|
24
|
+
}
|
|
25
|
+
if (s.startsWith('SELECT PATTERN_TYPE, PATTERN_VALUE, CATEGORY, COUNT, TRUST_SCORE FROM CODE_PATTERNS')) {
|
|
26
|
+
if (s.includes("CATEGORY = 'BLIND_SPOTS'"))
|
|
27
|
+
return fakeStmt([]);
|
|
28
|
+
return fakeStmt([{ pattern_type: 'naming', pattern_value: 'camelCase', category: 'naming', count: 10, trust_score: 90 }]);
|
|
29
|
+
}
|
|
30
|
+
if (s.startsWith('SELECT * FROM SCANS')) {
|
|
31
|
+
return fakeStmt([{ id: 1, project: 'fivo-cell', started_at: new Date().toISOString(), completed_at: new Date().toISOString(), files_scanned: 100 }]);
|
|
32
|
+
}
|
|
33
|
+
if (s.startsWith('SELECT * FROM ERROR_LOG'))
|
|
34
|
+
return fakeStmt([]);
|
|
35
|
+
if (s.startsWith('SELECT PATTERN_VALUE FROM CODE_PATTERNS'))
|
|
36
|
+
return fakeStmt([]);
|
|
37
|
+
if (s.startsWith('SELECT * FROM SESSIONS')) {
|
|
38
|
+
return fakeStmt(opts.sessionRows || []);
|
|
39
|
+
}
|
|
40
|
+
if (s.startsWith('SELECT * FROM LIVE_EVENTS')) {
|
|
41
|
+
return opts.liveEventRows ? fakeStmt(opts.liveEventRows) : fakeStmt([]);
|
|
42
|
+
}
|
|
43
|
+
if (s.includes('SESSION_APPROACHES') && s.includes('GROUP BY'))
|
|
44
|
+
return fakeStmt([]);
|
|
45
|
+
if (s.startsWith('SELECT FILE_PATH') && s.includes('SESSION_FILES'))
|
|
46
|
+
return fakeStmt([]);
|
|
47
|
+
if (s.startsWith('SELECT * FROM SESSION_QUESTIONS'))
|
|
48
|
+
return fakeStmt([]);
|
|
49
|
+
return fakeStmt([]);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
it('sets lastLiveFile when no session exists but live_events has rows', () => {
|
|
53
|
+
const eventTs = new Date(Date.now() - 60_000).toISOString();
|
|
54
|
+
setupMocks({
|
|
55
|
+
sessionRows: [],
|
|
56
|
+
liveEventRows: [{ id: 1217, project: 'fivo-cell', event_type: 'file_save', file_path: 'src/components/layout/AppLayout.tsx', created_at: eventTs }],
|
|
57
|
+
});
|
|
58
|
+
const ctx = (0, prompt_builder_1.buildContext)('fivo-cell', 'claude-code');
|
|
59
|
+
expect(ctx.lastSession).toBeUndefined();
|
|
60
|
+
expect(ctx.lastLiveFile).toBeDefined();
|
|
61
|
+
expect(ctx.lastLiveFile?.filePath).toBe('src/components/layout/AppLayout.tsx');
|
|
62
|
+
expect(ctx.lastLiveFile?.eventType).toBe('file_save');
|
|
63
|
+
});
|
|
64
|
+
it('@cell block shows "Live: saved <path>" when only live_event is present (regression for empty Last Session)', () => {
|
|
65
|
+
const eventTs = new Date(Date.now() - 30_000).toISOString();
|
|
66
|
+
setupMocks({
|
|
67
|
+
sessionRows: [],
|
|
68
|
+
liveEventRows: [{ id: 50, project: 'fivo-cell', event_type: 'file_save', file_path: 'src/foo.ts', created_at: eventTs }],
|
|
69
|
+
});
|
|
70
|
+
const ctx = (0, prompt_builder_1.buildContext)('fivo-cell', 'claude-code');
|
|
71
|
+
const out = (0, prompt_builder_1.formatContextForTool)(ctx, 'claude-code');
|
|
72
|
+
expect(out).toContain('Live: saved src/foo.ts');
|
|
73
|
+
expect(out).not.toContain('(no session yet — first run)');
|
|
74
|
+
expect(out).toContain('cell session start');
|
|
75
|
+
});
|
|
76
|
+
it('@cell block shows "Live: created <path>" for file_create events', () => {
|
|
77
|
+
const eventTs = new Date().toISOString();
|
|
78
|
+
setupMocks({
|
|
79
|
+
sessionRows: [],
|
|
80
|
+
liveEventRows: [{ id: 51, project: 'fivo-cell', event_type: 'file_create', file_path: 'src/new.ts', created_at: eventTs }],
|
|
81
|
+
});
|
|
82
|
+
const ctx = (0, prompt_builder_1.buildContext)('fivo-cell', 'claude-code');
|
|
83
|
+
const out = (0, prompt_builder_1.formatContextForTool)(ctx, 'claude-code');
|
|
84
|
+
expect(out).toContain('Live: created src/new.ts');
|
|
85
|
+
});
|
|
86
|
+
it('@cell block shows "Live: deleted <path>" for file_delete events', () => {
|
|
87
|
+
const eventTs = new Date().toISOString();
|
|
88
|
+
setupMocks({
|
|
89
|
+
sessionRows: [],
|
|
90
|
+
liveEventRows: [{ id: 52, project: 'fivo-cell', event_type: 'file_delete', file_path: 'src/old.ts', created_at: eventTs }],
|
|
91
|
+
});
|
|
92
|
+
const ctx = (0, prompt_builder_1.buildContext)('fivo-cell', 'claude-code');
|
|
93
|
+
const out = (0, prompt_builder_1.formatContextForTool)(ctx, 'claude-code');
|
|
94
|
+
expect(out).toContain('Live: deleted src/old.ts');
|
|
95
|
+
});
|
|
96
|
+
it('prefers lastSession over lastLiveFile when both exist (session is richer context)', () => {
|
|
97
|
+
const eventTs = new Date(Date.now() - 30_000).toISOString();
|
|
98
|
+
setupMocks({
|
|
99
|
+
sessionRows: [{
|
|
100
|
+
id: 5, tool_name: 'cursor', project: 'fivo-cell',
|
|
101
|
+
start_time: new Date(Date.now() - 600_000).toISOString(),
|
|
102
|
+
end_time: new Date().toISOString(),
|
|
103
|
+
files_touched: '["src/session-tracker.ts"]',
|
|
104
|
+
key_decisions: '["Phase 2"]',
|
|
105
|
+
context_snapshot: 'Working on session data',
|
|
106
|
+
}],
|
|
107
|
+
liveEventRows: [{ id: 100, project: 'fivo-cell', event_type: 'file_save', file_path: 'src/recent.ts', created_at: eventTs }],
|
|
108
|
+
});
|
|
109
|
+
const ctx = (0, prompt_builder_1.buildContext)('fivo-cell', 'claude-code');
|
|
110
|
+
expect(ctx.lastSession).toBeDefined();
|
|
111
|
+
expect(ctx.lastLiveFile).toBeDefined();
|
|
112
|
+
const out = (0, prompt_builder_1.formatContextForTool)(ctx, 'claude-code');
|
|
113
|
+
expect(out).toContain('Tool: cursor');
|
|
114
|
+
expect(out).toContain('Working on: Working on session data');
|
|
115
|
+
// Should NOT show the live fallback when a session exists
|
|
116
|
+
expect(out).not.toContain('Live: saved');
|
|
117
|
+
});
|
|
118
|
+
it('shows cold-start message when neither session nor live events exist', () => {
|
|
119
|
+
setupMocks({ sessionRows: [], liveEventRows: [] });
|
|
120
|
+
const ctx = (0, prompt_builder_1.buildContext)('unknown-project', 'claude-code');
|
|
121
|
+
expect(ctx.lastSession).toBeUndefined();
|
|
122
|
+
expect(ctx.lastLiveFile).toBeUndefined();
|
|
123
|
+
const out = (0, prompt_builder_1.formatContextForTool)(ctx, 'claude-code');
|
|
124
|
+
expect(out).toContain('(no session yet — first run)');
|
|
125
|
+
});
|
|
126
|
+
it('handles live_events query failure gracefully (returns undefined, does not crash)', () => {
|
|
127
|
+
setupMocks({ sessionRows: [] });
|
|
128
|
+
mockDb.prepare.mockImplementation((sql) => {
|
|
129
|
+
if (sql.trim().toUpperCase().startsWith('SELECT * FROM LIVE_EVENTS')) {
|
|
130
|
+
throw new Error('table missing');
|
|
131
|
+
}
|
|
132
|
+
return fakeStmt([]);
|
|
133
|
+
});
|
|
134
|
+
const ctx = (0, prompt_builder_1.buildContext)('fivo-cell', 'claude-code');
|
|
135
|
+
expect(ctx.lastLiveFile).toBeUndefined();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=atcell-live-fallback.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atcell-live-fallback.test.js","sourceRoot":"","sources":["../../src/__tests__/atcell-live-fallback.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-cli.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/watch-cli.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const watch_cli_1 = require("../core/watch-cli");
|
|
4
|
+
describe('watch-cli parser (cell watch events --limit/--type)', () => {
|
|
5
|
+
describe('parseWatchFlags', () => {
|
|
6
|
+
it('returns all positional args when no flags present', () => {
|
|
7
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['fivo-cell', '/path/to/dir']);
|
|
8
|
+
expect(r.positional).toEqual(['fivo-cell', '/path/to/dir']);
|
|
9
|
+
});
|
|
10
|
+
it('strips --limit N flag from positional list', () => {
|
|
11
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['fivo-cell', '--limit', '10']);
|
|
12
|
+
expect(r.positional).toEqual(['fivo-cell']);
|
|
13
|
+
});
|
|
14
|
+
it('strips --limit=N form', () => {
|
|
15
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['fivo-cell', '--limit=10']);
|
|
16
|
+
expect(r.positional).toEqual(['fivo-cell']);
|
|
17
|
+
});
|
|
18
|
+
it('strips --type file_save flag', () => {
|
|
19
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['fivo-cell', '--type', 'file_save']);
|
|
20
|
+
expect(r.positional).toEqual(['fivo-cell']);
|
|
21
|
+
});
|
|
22
|
+
it('strips --type=file_save form', () => {
|
|
23
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['fivo-cell', '--type=file_save']);
|
|
24
|
+
expect(r.positional).toEqual(['fivo-cell']);
|
|
25
|
+
});
|
|
26
|
+
it('handles flags before and after positional args (regression for v4.1.8 bug where --limit became project name)', () => {
|
|
27
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['--limit', '3', 'fivo-cell', '--type', 'file_save']);
|
|
28
|
+
expect(r.positional).toEqual(['fivo-cell']);
|
|
29
|
+
});
|
|
30
|
+
it('ignores unknown --flags without breaking (treats them as no-arg switches)', () => {
|
|
31
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['fivo-cell', '--unknown', 'value', '/dir']);
|
|
32
|
+
expect(r.positional).toEqual(['fivo-cell', 'value', '/dir']);
|
|
33
|
+
});
|
|
34
|
+
it('returns empty list when only flags provided', () => {
|
|
35
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['--limit', '5', '--type', 'file_save']);
|
|
36
|
+
expect(r.positional).toEqual([]);
|
|
37
|
+
});
|
|
38
|
+
it('handles --limit at end of args (no value)', () => {
|
|
39
|
+
const r = (0, watch_cli_1.parseWatchFlags)(['fivo-cell', '--limit']);
|
|
40
|
+
expect(r.positional).toEqual(['fivo-cell']);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('parseWatchLimit', () => {
|
|
44
|
+
it('returns default when no flag present', () => {
|
|
45
|
+
expect((0, watch_cli_1.parseWatchLimit)(['fivo-cell'])).toBe(watch_cli_1.DEFAULT_EVENT_LIMIT);
|
|
46
|
+
expect((0, watch_cli_1.parseWatchLimit)([])).toBe(watch_cli_1.DEFAULT_EVENT_LIMIT);
|
|
47
|
+
});
|
|
48
|
+
it('parses --limit N form', () => {
|
|
49
|
+
expect((0, watch_cli_1.parseWatchLimit)(['fivo-cell', '--limit', '50'])).toBe(50);
|
|
50
|
+
});
|
|
51
|
+
it('parses --limit=N form', () => {
|
|
52
|
+
expect((0, watch_cli_1.parseWatchLimit)(['fivo-cell', '--limit=42'])).toBe(42);
|
|
53
|
+
});
|
|
54
|
+
it('clamps absurdly large values to MAX_EVENT_LIMIT', () => {
|
|
55
|
+
expect((0, watch_cli_1.parseWatchLimit)(['--limit', '99999'])).toBe(watch_cli_1.MAX_EVENT_LIMIT);
|
|
56
|
+
});
|
|
57
|
+
it('falls back to default for non-numeric input', () => {
|
|
58
|
+
expect((0, watch_cli_1.parseWatchLimit)(['--limit', 'abc'])).toBe(watch_cli_1.DEFAULT_EVENT_LIMIT);
|
|
59
|
+
});
|
|
60
|
+
it('falls back to default for zero or negative', () => {
|
|
61
|
+
expect((0, watch_cli_1.parseWatchLimit)(['--limit', '0'])).toBe(watch_cli_1.DEFAULT_EVENT_LIMIT);
|
|
62
|
+
expect((0, watch_cli_1.parseWatchLimit)(['--limit', '-5'])).toBe(watch_cli_1.DEFAULT_EVENT_LIMIT);
|
|
63
|
+
});
|
|
64
|
+
it('uses custom fallback when provided', () => {
|
|
65
|
+
expect((0, watch_cli_1.parseWatchLimit)([], 100)).toBe(100);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('parseWatchEventType', () => {
|
|
69
|
+
it('returns undefined when no flag present', () => {
|
|
70
|
+
expect((0, watch_cli_1.parseWatchEventType)(['fivo-cell'])).toBeUndefined();
|
|
71
|
+
expect((0, watch_cli_1.parseWatchEventType)([])).toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
it('parses --type T form', () => {
|
|
74
|
+
expect((0, watch_cli_1.parseWatchEventType)(['--type', 'file_save'])).toBe('file_save');
|
|
75
|
+
});
|
|
76
|
+
it('parses --type=T form', () => {
|
|
77
|
+
expect((0, watch_cli_1.parseWatchEventType)(['--type=file_delete'])).toBe('file_delete');
|
|
78
|
+
});
|
|
79
|
+
it('works with positional args before/after', () => {
|
|
80
|
+
expect((0, watch_cli_1.parseWatchEventType)(['fivo-cell', '--type', 'git_commit'])).toBe('git_commit');
|
|
81
|
+
expect((0, watch_cli_1.parseWatchEventType)(['--type', 'file_rename', 'fivo-cell'])).toBe('file_rename');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe('isValidEventType', () => {
|
|
85
|
+
it('accepts all known event types', () => {
|
|
86
|
+
for (const t of ['file_save', 'file_create', 'file_delete', 'file_rename', 'git_commit', 'package_change']) {
|
|
87
|
+
expect((0, watch_cli_1.isValidEventType)(t)).toBe(true);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
it('rejects unknown types', () => {
|
|
91
|
+
expect((0, watch_cli_1.isValidEventType)('foo')).toBe(false);
|
|
92
|
+
expect((0, watch_cli_1.isValidEventType)('FILE_SAVE')).toBe(false);
|
|
93
|
+
expect((0, watch_cli_1.isValidEventType)(undefined)).toBe(false);
|
|
94
|
+
expect((0, watch_cli_1.isValidEventType)('')).toBe(false);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=watch-cli.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch-cli.test.js","sourceRoot":"","sources":["../../src/__tests__/watch-cli.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -300,19 +300,46 @@ function doScan() {
|
|
|
300
300
|
const banner = figlet_1.default.textSync('CELL', { font: 'ANSI Shadow', horizontalLayout: 'fitted' });
|
|
301
301
|
console.log((0, gradient_string_1.default)(['#FF6B35', '#FFAB91'])(banner));
|
|
302
302
|
console.log(C.dim(' Scanning codebase + building all layers...\n'));
|
|
303
|
+
// ─── Flag parsing ─────────────────────────────────────────────────────
|
|
304
|
+
// --no-rules → skip writing AGENTS.md and .cursorrules to project root
|
|
305
|
+
// --force-rules → overwrite existing AGENTS.md/.cursorrules (otherwise keep user edits)
|
|
306
|
+
const noRules = args.includes('--no-rules');
|
|
307
|
+
const forceRules = args.includes('--force-rules');
|
|
308
|
+
const scanPathArg = args.find((a, i) => i >= 1 && !a.startsWith('--')) || project;
|
|
309
|
+
const scanCwd = path.resolve(scanPathArg);
|
|
310
|
+
const scanProject = path.basename(scanCwd);
|
|
303
311
|
try {
|
|
304
312
|
const { scanCodebase } = require('./code-scanner');
|
|
305
|
-
const result = scanCodebase(
|
|
313
|
+
const result = scanCodebase(scanCwd, scanProject);
|
|
306
314
|
console.log(C.success(` [1/2] Scanned ${result.filesScanned} files, ${result.totalLines.toLocaleString()} lines`));
|
|
307
315
|
(0, layers_1.populateAllLayers)({
|
|
308
316
|
profile: result.profile,
|
|
309
317
|
patterns: result.patterns,
|
|
310
|
-
project,
|
|
318
|
+
project: scanProject,
|
|
311
319
|
});
|
|
312
320
|
console.log(C.success(' [2/2] Populated all layers:'));
|
|
313
321
|
console.log(C.dim(' .cell/personal/ — profile, style, errors, decisions'));
|
|
314
322
|
console.log(C.dim(' .cell/team/ — shared patterns, blind spots'));
|
|
315
323
|
console.log(C.dim(' .cell/community/ — community patterns, trends'));
|
|
324
|
+
// ─── AI rules files (AGENTS.md, .cursorrules) ─────────────────────────
|
|
325
|
+
if (!noRules) {
|
|
326
|
+
const { writeCellRules } = require('./core/agents-md');
|
|
327
|
+
const rulesResult = writeCellRules(scanCwd, { overwrite: forceRules });
|
|
328
|
+
const lines = [];
|
|
329
|
+
if (rulesResult.agentsMd === 'written')
|
|
330
|
+
lines.push('AGENTS.md');
|
|
331
|
+
if (rulesResult.cursorRules === 'written')
|
|
332
|
+
lines.push('.cursorrules');
|
|
333
|
+
if (lines.length > 0) {
|
|
334
|
+
console.log(C.success(` [3/3] Wrote AI rules: ${lines.join(', ')} (idempotent — kept existing files)`));
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
console.log(C.dim(' [3/3] AI rules: AGENTS.md + .cursorrules already present (kept as-is)'));
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
console.log(C.dim(' [3/3] AI rules: skipped (--no-rules)'));
|
|
342
|
+
}
|
|
316
343
|
console.log();
|
|
317
344
|
console.log(C.dim(' Run: cell status'));
|
|
318
345
|
console.log();
|
|
@@ -988,8 +1015,19 @@ function doWatch() {
|
|
|
988
1015
|
console.log(C.dim(' ─────────────────'));
|
|
989
1016
|
console.log();
|
|
990
1017
|
const sub = args[1] || 'daemon';
|
|
991
|
-
|
|
992
|
-
|
|
1018
|
+
// Parse flags first so positional args don't get eaten by --limit / --type.
|
|
1019
|
+
// Examples supported:
|
|
1020
|
+
// cell watch events
|
|
1021
|
+
// cell watch events fivo-cell
|
|
1022
|
+
// cell watch events fivo-cell --limit 10
|
|
1023
|
+
// cell watch events fivo-cell --type file_save
|
|
1024
|
+
// cell watch events --limit 5 --type file_create
|
|
1025
|
+
const watchArgs = args.slice(2);
|
|
1026
|
+
const { positional } = require('./core/watch-cli').parseWatchFlags(watchArgs);
|
|
1027
|
+
const watchLimit = require('./core/watch-cli').parseWatchLimit(watchArgs);
|
|
1028
|
+
const watchEventType = require('./core/watch-cli').parseWatchEventType(watchArgs);
|
|
1029
|
+
const project = positional[0] || path.basename(process.cwd());
|
|
1030
|
+
const dir = positional[1] || process.cwd();
|
|
993
1031
|
// If invoked with no subcommand: run as a long-lived watcher daemon (for .bat auto-restart loop)
|
|
994
1032
|
if (sub === 'daemon' || sub === '') {
|
|
995
1033
|
runWatchDaemon(project, dir);
|
|
@@ -1037,14 +1075,22 @@ function doWatch() {
|
|
|
1037
1075
|
return;
|
|
1038
1076
|
}
|
|
1039
1077
|
if (sub === 'events') {
|
|
1040
|
-
const
|
|
1078
|
+
const { isValidEventType } = require('./core/watch-cli');
|
|
1079
|
+
const typeFilter = isValidEventType(watchEventType) ? watchEventType : undefined;
|
|
1080
|
+
const events = liveWatcher.getLiveEvents(project, watchLimit, typeFilter);
|
|
1041
1081
|
if (events.length === 0) {
|
|
1042
|
-
|
|
1082
|
+
const hint = typeFilter
|
|
1083
|
+
? `No ${typeFilter} events for ${project} in the last ${watchLimit}.`
|
|
1084
|
+
: `No live events for ${project} yet. Start watcher with: cell watch start ${project}`;
|
|
1085
|
+
console.log(C.dim(` ${hint}`));
|
|
1043
1086
|
}
|
|
1044
1087
|
else {
|
|
1045
|
-
|
|
1088
|
+
const header = typeFilter
|
|
1089
|
+
? `Recent ${typeFilter} events for ${project} (${events.length}, limit ${watchLimit}):`
|
|
1090
|
+
: `Recent events for ${project} (${events.length}, limit ${watchLimit}):`;
|
|
1091
|
+
console.log(C.bold(` ${header}`));
|
|
1046
1092
|
for (const e of events) {
|
|
1047
|
-
const icon = e.eventType === 'file_save' ? '~' : e.eventType === 'file_create' ? '+' : e.eventType === 'file_delete' ? '-' : '*';
|
|
1093
|
+
const icon = e.eventType === 'file_save' ? '~' : e.eventType === 'file_create' ? '+' : e.eventType === 'file_delete' ? '-' : e.eventType === 'file_rename' ? '>' : e.eventType === 'git_commit' ? '@' : '*';
|
|
1048
1094
|
console.log(` ${C.dim(icon)} ${C.dim(e.createdAt)} ${e.eventType}: ${C.num(e.filePath)}`);
|
|
1049
1095
|
}
|
|
1050
1096
|
}
|