Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/cli/src/ui/utils/statsDataService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,13 @@ describe('loadStatsData - new fields', () => {
now.getMonth(),
now.getDate(),
);
const todayTimestamp = Math.max(todayStart.getTime(), now.getTime() - 1000);
const yesterdayMid = todayStart.getTime() - 12 * 60 * 60 * 1000; // yesterday noon

const todayRecord = makeRecord({
sessionId: 'today-1',
timestamp: todayStart.getTime() + 3600000,
startTime: todayStart.getTime() + 3600000 - 60000,
timestamp: todayTimestamp,
startTime: todayTimestamp - 60000,
durationMs: 60000,
totalLatencyMs: 1000,
models: {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/subagents/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ export { SubagentValidator } from './validation.js';
// live in `agent-frontmatter-schema.ts` and are intentionally NOT
// re-exported here — they are internal to the `SubagentManager` /
// `claude-converter` parse paths and locking their names in the
// package's public API would constrain follow-up PRs (e.g. when
// `js-yaml` lands and the schema shape changes). Re-introduce specific
// exports here when a cross-package caller actually needs them.
// package's public API would constrain follow-up schema changes.
// Re-introduce specific exports here when a cross-package caller actually
// needs them.

// Main management class
export { SubagentManager } from './subagent-manager.js';
35 changes: 9 additions & 26 deletions packages/core/src/utils/yaml-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,39 +308,22 @@ describe('yaml-parser', () => {
});
});

// The following two tests pin known limitations of this lightweight YAML
// parser that surfaced while porting Claude Code's declarative-agent
// schema (see docs/declarative-agents-port.md). They will FAIL when the
// parser gains real nested-YAML support (e.g. after switching to
// `js-yaml`) — that failure is the signal to revisit the
// `mcpServers` / `hooks` carve-outs in SubagentManager and the
// documentation around them.
describe('known limitations — nested YAML (pin until js-yaml lands)', () => {
it('garbles array-of-records: deeper keys leak to parent scope', () => {
describe('nested YAML', () => {
it('parses array-of-records', () => {
const yaml =
'mcpServers:\n - filesystem:\n type: stdio\n command: node';
const result = parse(yaml);
// What we'd ideally get: { mcpServers: [{ filesystem: { type: 'stdio', command: 'node' } }] }
// What the lightweight parser actually returns: the list item is read
// as the bare key string "filesystem:" and the deeper indented keys
// become siblings of mcpServers at the top level.
expect(result['mcpServers']).toEqual(['filesystem:']);
expect(result['type']).toBe('stdio');
expect(result['command']).toBe('node');
expect(result['mcpServers']).toEqual([
{ filesystem: { type: 'stdio', command: 'node' } },
]);
});

it('garbles record-of-records: deeper keys leak into the record', () => {
it('parses record-of-records with arrays', () => {
const yaml = 'hooks:\n PreToolUse:\n - matcher: Read';
const result = parse(yaml);
// Ideal: { hooks: { PreToolUse: [{ matcher: 'Read' }] } }
// Actual: nested list-item parsed as a sibling key with the dash
// pasted into the key.
expect((result['hooks'] as Record<string, unknown>)['PreToolUse']).toBe(
'',
);
expect((result['hooks'] as Record<string, unknown>)['- matcher']).toBe(
'Read',
);
expect(result['hooks']).toEqual({
PreToolUse: [{ matcher: 'Read' }],
});
});
});
});
Expand Down
Loading