hungry-ghost-hive 0.52.0 → 0.52.2

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 (41) hide show
  1. package/dist/cli/commands/agents.d.ts.map +1 -1
  2. package/dist/cli/commands/agents.js +4 -2
  3. package/dist/cli/commands/agents.js.map +1 -1
  4. package/dist/cli/commands/manager/token-capture.d.ts.map +1 -1
  5. package/dist/cli/commands/manager/token-capture.js +6 -3
  6. package/dist/cli/commands/manager/token-capture.js.map +1 -1
  7. package/dist/cli/commands/msg.d.ts.map +1 -1
  8. package/dist/cli/commands/msg.js +7 -2
  9. package/dist/cli/commands/msg.js.map +1 -1
  10. package/dist/cli/commands/msg.test.js +28 -0
  11. package/dist/cli/commands/msg.test.js.map +1 -1
  12. package/dist/cli/commands/status.js +4 -2
  13. package/dist/cli/commands/status.js.map +1 -1
  14. package/dist/cli/commands/tokens.js +2 -2
  15. package/dist/cli/commands/tokens.js.map +1 -1
  16. package/dist/db/client.d.ts +1 -1
  17. package/dist/db/client.d.ts.map +1 -1
  18. package/dist/db/postgres-provider.d.ts +19 -0
  19. package/dist/db/postgres-provider.d.ts.map +1 -1
  20. package/dist/db/postgres-provider.js +10 -3
  21. package/dist/db/postgres-provider.js.map +1 -1
  22. package/dist/db/postgres-provider.test.js +54 -1
  23. package/dist/db/postgres-provider.test.js.map +1 -1
  24. package/dist/db/queries/token-usage.d.ts.map +1 -1
  25. package/dist/db/queries/token-usage.js +10 -2
  26. package/dist/db/queries/token-usage.js.map +1 -1
  27. package/dist/parsers/token-usage-parser.d.ts.map +1 -1
  28. package/dist/parsers/token-usage-parser.js +33 -4
  29. package/dist/parsers/token-usage-parser.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/cli/commands/agents.ts +6 -2
  32. package/src/cli/commands/manager/token-capture.ts +9 -3
  33. package/src/cli/commands/msg.test.ts +30 -0
  34. package/src/cli/commands/msg.ts +9 -4
  35. package/src/cli/commands/status.ts +6 -2
  36. package/src/cli/commands/tokens.ts +2 -2
  37. package/src/db/client.ts +1 -1
  38. package/src/db/postgres-provider.test.ts +86 -1
  39. package/src/db/postgres-provider.ts +12 -3
  40. package/src/db/queries/token-usage.ts +14 -8
  41. package/src/parsers/token-usage-parser.ts +36 -4
@@ -1,6 +1,6 @@
1
1
  // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
2
  import { describe, expect, it } from 'vitest';
3
- import { convertParams } from './postgres-provider.js';
3
+ import { convertParams, injectInsertWorkspaceId, injectWhereWorkspaceId, } from './postgres-provider.js';
4
4
  describe('PostgresProvider utilities', () => {
5
5
  describe('convertParams', () => {
6
6
  it('should convert ? to $1, $2, $3', () => {
@@ -52,6 +52,59 @@ describe('PostgresProvider utilities', () => {
52
52
  expect(expectedTables).toHaveLength(10);
53
53
  });
54
54
  });
55
+ describe('injectWhereWorkspaceId', () => {
56
+ const ws = 'ws-123';
57
+ it('should inject WHERE clause when none exists', () => {
58
+ const result = injectWhereWorkspaceId('SELECT * FROM agent_logs ORDER BY timestamp DESC LIMIT ?', ws, [50]);
59
+ expect(result.sql).toContain('WHERE workspace_id = ?');
60
+ expect(result.sql).toContain('ORDER BY timestamp DESC LIMIT ?');
61
+ expect(result.params).toEqual([ws, 50]);
62
+ });
63
+ it('should append to existing WHERE with correct param order before LIMIT', () => {
64
+ const result = injectWhereWorkspaceId('SELECT * FROM agent_logs WHERE agent_id = ? ORDER BY timestamp DESC LIMIT ?', ws, ['agent-1', 100]);
65
+ expect(result.sql).toBe('SELECT * FROM agent_logs WHERE agent_id = ? AND workspace_id = ? ORDER BY timestamp DESC LIMIT ?');
66
+ expect(result.params).toEqual(['agent-1', ws, 100]);
67
+ });
68
+ it('should handle WHERE with no trailing clauses', () => {
69
+ const result = injectWhereWorkspaceId('SELECT * FROM agent_logs WHERE story_id = ?', ws, [
70
+ 'story-1',
71
+ ]);
72
+ expect(result.sql).toBe('SELECT * FROM agent_logs WHERE story_id = ? AND workspace_id = ?');
73
+ expect(result.params).toEqual(['story-1', ws]);
74
+ });
75
+ it('should handle WHERE with multiple conditions and LIMIT', () => {
76
+ const result = injectWhereWorkspaceId("SELECT COUNT(*) as count FROM agent_logs WHERE story_id = ? AND event_type = 'STORY_QA_FAILED'", ws, ['story-1']);
77
+ expect(result.sql).toContain('AND workspace_id = ?');
78
+ expect(result.params).toEqual(['story-1', ws]);
79
+ });
80
+ it('should handle DELETE with WHERE and no trailing', () => {
81
+ const result = injectWhereWorkspaceId('DELETE FROM agent_logs WHERE timestamp < ?', ws, [
82
+ '2024-01-01',
83
+ ]);
84
+ expect(result.sql).toBe('DELETE FROM agent_logs WHERE timestamp < ? AND workspace_id = ?');
85
+ expect(result.params).toEqual(['2024-01-01', ws]);
86
+ });
87
+ it('should skip injection when workspace_id already present', () => {
88
+ const sql = 'SELECT * FROM agent_logs WHERE workspace_id = ? AND agent_id = ?';
89
+ const result = injectWhereWorkspaceId(sql, ws, [ws, 'agent-1']);
90
+ expect(result.sql).toBe(sql);
91
+ expect(result.params).toEqual([ws, 'agent-1']);
92
+ });
93
+ });
94
+ describe('injectInsertWorkspaceId', () => {
95
+ const ws = 'ws-123';
96
+ it('should add workspace_id column and value to INSERT', () => {
97
+ const result = injectInsertWorkspaceId('INSERT INTO agent_logs (agent_id, event_type) VALUES (?, ?)', ws, ['agent-1', 'AGENT_SPAWNED']);
98
+ expect(result.sql).toContain('workspace_id');
99
+ expect(result.params).toEqual(['agent-1', 'AGENT_SPAWNED', ws]);
100
+ });
101
+ it('should skip injection when workspace_id already present', () => {
102
+ const sql = 'INSERT INTO agent_logs (agent_id, workspace_id) VALUES (?, ?)';
103
+ const result = injectInsertWorkspaceId(sql, ws, ['agent-1', ws]);
104
+ expect(result.sql).toBe(sql);
105
+ expect(result.params).toEqual(['agent-1', ws]);
106
+ });
107
+ });
55
108
  describe('convertParams edge cases', () => {
56
109
  it('should handle empty string', () => {
57
110
  expect(convertParams('')).toBe('');
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-provider.test.js","sourceRoot":"","sources":["../../src/db/postgres-provider.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgres-provider.test.js","sourceRoot":"","sources":["../../src/db/postgres-provider.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"token-usage.d.ts","sourceRoot":"","sources":["../../../src/db/queries/token-usage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAyBxB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAED,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,OAAO,CAAC,iBAAiB,CAAC,CAoC5B"}
1
+ {"version":3,"file":"token-usage.d.ts","sourceRoot":"","sources":["../../../src/db/queries/token-usage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAyBxB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAED,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,OAAO,CAAC,iBAAiB,CAAC,CA0C5B"}
@@ -62,11 +62,19 @@ export async function getTotalTokens(provider, options) {
62
62
  FROM token_usage
63
63
  ${whereClause}
64
64
  `, params);
65
- return (result || {
65
+ // Postgres SUM/COUNT return bigint, which node-postgres converts to strings.
66
+ // Coerce to numbers for consistent behavior across SQLite and Postgres.
67
+ const raw = result || {
66
68
  total_input_tokens: 0,
67
69
  total_output_tokens: 0,
68
70
  total_tokens: 0,
69
71
  record_count: 0,
70
- });
72
+ };
73
+ return {
74
+ total_input_tokens: Number(raw.total_input_tokens),
75
+ total_output_tokens: Number(raw.total_output_tokens),
76
+ total_tokens: Number(raw.total_tokens),
77
+ record_count: Number(raw.record_count),
78
+ };
71
79
  }
72
80
  //# sourceMappingURL=token-usage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-usage.js","sourceRoot":"","sources":["../../../src/db/queries/token-usage.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAmC7D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,KAA4B;IAE5B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CACpC;;;;GAID,EACC;QACE,KAAK,CAAC,OAAO;QACb,KAAK,CAAC,OAAO,IAAI,IAAI;QACrB,KAAK,CAAC,aAAa,IAAI,IAAI;QAC3B,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,KAAK,IAAI,IAAI;QACnB,KAAK,CAAC,SAAS,IAAI,IAAI;QACvB,GAAG;KACJ,CACF,CAAC;IAEF,OAAO,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAgB,wCAAwC,EAAE;QACvF,MAAM,EAAE,EAAE,IAAI,CAAC;KAChB,CAAC,CAAE,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,OAAe;IAEf,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAC5B;;;;GAID,EACC,CAAC,OAAO,CAAC,CACV,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,OAAe;IAEf,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAC5B;;;;GAID,EACC,CAAC,OAAO,CAAC,CACV,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAA0B,EAC1B,aAAqB;IAErB,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAC5B;;;;GAID,EACC,CAAC,aAAa,CAAC,CAChB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAA0B,EAC1B,OAA4C;IAE5C,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAErF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CACpC;;;;;;;MAOE,WAAW;GACd,EACC,MAAM,CACP,CAAC;IAEF,OAAO,CACL,MAAM,IAAI;QACR,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,CAAC;QACtB,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,CAAC;KAChB,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"token-usage.js","sourceRoot":"","sources":["../../../src/db/queries/token-usage.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAmC7D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,KAA4B;IAE5B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CACpC;;;;GAID,EACC;QACE,KAAK,CAAC,OAAO;QACb,KAAK,CAAC,OAAO,IAAI,IAAI;QACrB,KAAK,CAAC,aAAa,IAAI,IAAI;QAC3B,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,KAAK,IAAI,IAAI;QACnB,KAAK,CAAC,SAAS,IAAI,IAAI;QACvB,GAAG;KACJ,CACF,CAAC;IAEF,OAAO,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAgB,wCAAwC,EAAE;QACvF,MAAM,EAAE,EAAE,IAAI,CAAC;KAChB,CAAC,CAAE,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,OAAe;IAEf,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAC5B;;;;GAID,EACC,CAAC,OAAO,CAAC,CACV,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,OAAe;IAEf,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAC5B;;;;GAID,EACC,CAAC,OAAO,CAAC,CACV,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAA0B,EAC1B,aAAqB;IAErB,OAAO,MAAM,QAAQ,CAAC,QAAQ,CAC5B;;;;GAID,EACC,CAAC,aAAa,CAAC,CAChB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAA0B,EAC1B,OAA4C;IAE5C,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;QACnB,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAErF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CACpC;;;;;;;MAOE,WAAW;GACd,EACC,MAAM,CACP,CAAC;IAEF,6EAA6E;IAC7E,wEAAwE;IACxE,MAAM,GAAG,GAAG,MAAM,IAAI;QACpB,kBAAkB,EAAE,CAAC;QACrB,mBAAmB,EAAE,CAAC;QACtB,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,CAAC;KAChB,CAAC;IACF,OAAO;QACL,kBAAkB,EAAE,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAClD,mBAAmB,EAAE,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACpD,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;QACtC,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;KACvC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"token-usage-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/token-usage-parser.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAsKD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAOvE;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAkClF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAmB9E"}
1
+ {"version":3,"file":"token-usage-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/token-usage-parser.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAsKD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAOvE;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAkClF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAmB9E"}
@@ -6,8 +6,9 @@
6
6
  * Supports Claude Code, Codex, and Gemini output formats.
7
7
  * Also reads token usage directly from Claude Code's JSONL conversation logs.
8
8
  */
9
- import { readFileSync, readdirSync } from 'fs';
10
- import { homedir } from 'os';
9
+ import { execSync } from 'child_process';
10
+ import { readFileSync, readdirSync, statSync } from 'fs';
11
+ import { homedir, userInfo } from 'os';
11
12
  import { join, resolve } from 'path';
12
13
  /**
13
14
  * Parse a number string that may contain commas (e.g. "12,345" -> 12345)
@@ -226,12 +227,40 @@ export function getTokenUsageForAgent(workDir) {
226
227
  return null;
227
228
  return { inputTokens: totalInput, outputTokens: totalOutput, totalTokens };
228
229
  }
230
+ /**
231
+ * Resolve the home directory for the OS user that owns a given path.
232
+ * Falls back to the current process's homedir() if detection fails.
233
+ */
234
+ function resolveHomeDirForPath(dirPath) {
235
+ try {
236
+ const stat = statSync(dirPath);
237
+ const currentUid = userInfo().uid;
238
+ // If the directory is owned by the current user, just use homedir()
239
+ if (stat.uid === currentUid) {
240
+ return homedir();
241
+ }
242
+ // Look up the owning user's home directory via getent (POSIX)
243
+ const passwd = execSync(`getent passwd ${stat.uid}`, { encoding: 'utf-8' }).trim();
244
+ const fields = passwd.split(':');
245
+ if (fields.length >= 6 && fields[5]) {
246
+ return fields[5];
247
+ }
248
+ }
249
+ catch {
250
+ // Fall through to default
251
+ }
252
+ return homedir();
253
+ }
229
254
  /**
230
255
  * Find all JSONL session files for a given working directory.
256
+ * Resolves the Claude config directory from the user that owns the workDir,
257
+ * so the manager can read JSONL logs even when running as a different user.
231
258
  */
232
259
  function findAllSessionFiles(workDir) {
233
- const projectDir = pathToClaudeProjectDir(resolve(workDir));
234
- const claudeProjectsDir = join(homedir(), '.claude', 'projects', projectDir);
260
+ const resolvedWorkDir = resolve(workDir);
261
+ const projectDir = pathToClaudeProjectDir(resolvedWorkDir);
262
+ const home = resolveHomeDirForPath(resolvedWorkDir);
263
+ const claudeProjectsDir = join(home, '.claude', 'projects', projectDir);
235
264
  try {
236
265
  return readdirSync(claudeProjectsDir)
237
266
  .filter(f => f.endsWith('.jsonl'))
@@ -1 +1 @@
1
- {"version":3,"file":"token-usage-parser.js","sourceRoot":"","sources":["../../src/parsers/token-usage-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token-usage-parser.js","sourceRoot":"","sources":["../../src/parsers/token-usage-parser.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hungry-ghost-hive",
3
- "version": "0.52.0",
3
+ "version": "0.52.2",
4
4
  "description": "AI Agent Orchestrator - Manages agile software development teams of AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -86,7 +86,9 @@ agentsCommand
86
86
  console.log(chalk.bold(`\nLogs for ${agentId}:\n`));
87
87
 
88
88
  for (const log of logs) {
89
- const time = log.timestamp.substring(0, 19).replace('T', ' ');
89
+ const tsStr =
90
+ log.timestamp instanceof Date ? log.timestamp.toISOString() : String(log.timestamp);
91
+ const time = tsStr.substring(0, 19).replace('T', ' ');
90
92
  const storyInfo = log.story_id ? chalk.cyan(` [${log.story_id}]`) : '';
91
93
  const message = log.message ? `: ${log.message}` : '';
92
94
 
@@ -137,7 +139,9 @@ agentsCommand
137
139
  if (logs.length > 0) {
138
140
  console.log(chalk.bold('\nRecent Activity:'));
139
141
  for (const log of logs) {
140
- const time = log.timestamp.substring(11, 19);
142
+ const tsStr =
143
+ log.timestamp instanceof Date ? log.timestamp.toISOString() : String(log.timestamp);
144
+ const time = tsStr.substring(11, 19);
141
145
  const message = log.message ? `: ${log.message.substring(0, 50)}` : '';
142
146
  console.log(chalk.gray(` ${time} | ${log.event_type}${message}`));
143
147
  }
@@ -63,7 +63,8 @@ export async function captureAndPersistTokenUsage(
63
63
  }
64
64
 
65
65
  return await parseAndPersistTokenUsage(output, ctx, agentId, storyId);
66
- } catch {
66
+ } catch (err) {
67
+ console.error(`[token-capture] captureAndPersistTokenUsage failed for agent=${agentId}:`, err);
67
68
  return { captured: false, tokens: null, persisted: false };
68
69
  }
69
70
  }
@@ -104,7 +105,8 @@ export async function parseAndPersistTokenUsage(
104
105
  });
105
106
 
106
107
  return { captured: true, tokens, persisted: true };
107
- } catch {
108
+ } catch (err) {
109
+ console.error(`[token-capture] parseAndPersistTokenUsage failed for agent=${agentId}:`, err);
108
110
  return { captured: false, tokens: null, persisted: false };
109
111
  }
110
112
  }
@@ -171,7 +173,11 @@ export async function parseAndPersistTokenUsageIfChanged(
171
173
  });
172
174
 
173
175
  return { captured: true, tokens, persisted: true, changed: true };
174
- } catch {
176
+ } catch (err) {
177
+ console.error(
178
+ `[token-capture] parseAndPersistTokenUsageIfChanged failed for agent=${agentId}:`,
179
+ err
180
+ );
175
181
  return { captured: false, tokens: null, persisted: false, changed: false };
176
182
  }
177
183
  }
@@ -82,5 +82,35 @@ describe('msg command', () => {
82
82
  const allOpt = inboxCmd?.options.find(opt => opt.long === '--all');
83
83
  expect(allOpt).toBeDefined();
84
84
  });
85
+
86
+ it('should not crash when created_at is a Date object (Postgres mode)', async () => {
87
+ const { withReadOnlyHiveContext } = await import('../../utils/with-hive-context.js');
88
+ const mockMsg = {
89
+ id: 'msg-test1',
90
+ from_session: 'sender',
91
+ to_session: 'receiver',
92
+ subject: 'test',
93
+ body: 'hello',
94
+ reply: null,
95
+ status: 'pending' as const,
96
+ created_at: new Date('2024-01-15T10:30:00.000Z'),
97
+ replied_at: null,
98
+ };
99
+ vi.mocked(withReadOnlyHiveContext).mockImplementationOnce(async callback => {
100
+ await callback({
101
+ db: {
102
+ db: {},
103
+ provider: { queryAll: vi.fn().mockResolvedValue([mockMsg]) },
104
+ save: vi.fn(),
105
+ },
106
+ paths: { hiveDir: '/tmp/test-hive' },
107
+ } as unknown as Parameters<typeof callback>[0]);
108
+ });
109
+
110
+ const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
111
+ const inboxCmd = msgCommand.commands.find(cmd => cmd.name() === 'inbox')!;
112
+ await expect(inboxCmd.parseAsync(['receiver'], { from: 'user' })).resolves.not.toThrow();
113
+ consoleSpy.mockRestore();
114
+ });
85
115
  });
86
116
  });
@@ -14,8 +14,13 @@ interface MessageRow {
14
14
  body: string;
15
15
  reply: string | null;
16
16
  status: 'pending' | 'read' | 'replied';
17
- created_at: string;
18
- replied_at: string | null;
17
+ created_at: string | Date;
18
+ replied_at: string | Date | null;
19
+ }
20
+
21
+ function toISOString(value: string | Date | null): string {
22
+ if (value === null) return '';
23
+ return value instanceof Date ? value.toISOString() : value;
19
24
  }
20
25
 
21
26
  export const msgCommand = new Command('msg').description('Inter-agent messaging');
@@ -79,7 +84,7 @@ msgCommand
79
84
  : msg.status === 'replied'
80
85
  ? chalk.green('✓')
81
86
  : chalk.gray('○');
82
- const time = msg.created_at.substring(0, 16).replace('T', ' ');
87
+ const time = toISOString(msg.created_at).substring(0, 16).replace('T', ' ');
83
88
 
84
89
  console.log(`${statusIcon} ${chalk.cyan(msg.id)} from ${chalk.bold(msg.from_session)}`);
85
90
  console.log(` ${chalk.gray(time)} ${msg.subject || ''}`);
@@ -120,7 +125,7 @@ msgCommand
120
125
  console.log(`From: ${chalk.cyan(msg.from_session)}`);
121
126
  console.log(`To: ${msg.to_session}`);
122
127
  console.log(`Subject: ${msg.subject || '(none)'}`);
123
- console.log(`Time: ${msg.created_at}`);
128
+ console.log(`Time: ${toISOString(msg.created_at)}`);
124
129
  console.log(`Status: ${msg.status}`);
125
130
  console.log(chalk.gray('─'.repeat(50)));
126
131
  console.log(msg.body);
@@ -147,7 +147,9 @@ async function showOverallStatus(db: DatabaseProvider, json?: boolean): Promise<
147
147
  if (recentLogs.length > 0) {
148
148
  console.log(chalk.bold('Recent Activity:'));
149
149
  for (const log of recentLogs) {
150
- const time = log.timestamp.substring(11, 19);
150
+ const ts =
151
+ log.timestamp instanceof Date ? log.timestamp.toISOString() : String(log.timestamp);
152
+ const time = ts.substring(11, 19);
151
153
  console.log(chalk.gray(` ${time} | ${log.agent_id.padEnd(15)} | ${log.event_type}`));
152
154
  }
153
155
  console.log();
@@ -326,7 +328,9 @@ async function showStoryStatus(
326
328
  if (logs.length > 0) {
327
329
  console.log(chalk.bold('Recent Activity:'));
328
330
  for (const log of logs) {
329
- const time = log.timestamp.substring(11, 19);
331
+ const ts =
332
+ log.timestamp instanceof Date ? log.timestamp.toISOString() : String(log.timestamp);
333
+ const time = ts.substring(11, 19);
330
334
  const msg = log.message ? `: ${log.message.substring(0, 40)}` : '';
331
335
  console.log(chalk.gray(` ${time} | ${log.agent_id.padEnd(15)} | ${log.event_type}${msg}`));
332
336
  }
@@ -69,7 +69,7 @@ tokensCommand
69
69
  console.log(chalk.gray('─'.repeat(90)));
70
70
 
71
71
  for (const row of rows) {
72
- const time = row.recorded_at.substring(0, 19).replace('T', ' ');
72
+ const time = new Date(row.recorded_at).toISOString().substring(0, 19).replace('T', ' ');
73
73
  const story = (row.story_id || '-').padEnd(20);
74
74
  const model = (row.model || '-').padEnd(15);
75
75
  console.log(
@@ -119,7 +119,7 @@ tokensCommand
119
119
  console.log(chalk.gray('─'.repeat(95)));
120
120
 
121
121
  for (const row of rows) {
122
- const time = row.recorded_at.substring(0, 19).replace('T', ' ');
122
+ const time = new Date(row.recorded_at).toISOString().substring(0, 19).replace('T', ' ');
123
123
  const agent = row.agent_id.padEnd(25);
124
124
  const model = (row.model || '-').padEnd(15);
125
125
  console.log(
package/src/db/client.ts CHANGED
@@ -878,7 +878,7 @@ export interface AgentLogRow {
878
878
  status: string | null;
879
879
  message: string | null;
880
880
  metadata: string | null;
881
- timestamp: string;
881
+ timestamp: string | Date;
882
882
  }
883
883
 
884
884
  export interface EscalationRow {
@@ -1,7 +1,11 @@
1
1
  // Licensed under the Hungry Ghost Hive License. See LICENSE.
2
2
 
3
3
  import { describe, expect, it } from 'vitest';
4
- import { convertParams } from './postgres-provider.js';
4
+ import {
5
+ convertParams,
6
+ injectInsertWorkspaceId,
7
+ injectWhereWorkspaceId,
8
+ } from './postgres-provider.js';
5
9
 
6
10
  describe('PostgresProvider utilities', () => {
7
11
  describe('convertParams', () => {
@@ -71,6 +75,87 @@ describe('PostgresProvider utilities', () => {
71
75
  });
72
76
  });
73
77
 
78
+ describe('injectWhereWorkspaceId', () => {
79
+ const ws = 'ws-123';
80
+
81
+ it('should inject WHERE clause when none exists', () => {
82
+ const result = injectWhereWorkspaceId(
83
+ 'SELECT * FROM agent_logs ORDER BY timestamp DESC LIMIT ?',
84
+ ws,
85
+ [50]
86
+ );
87
+ expect(result.sql).toContain('WHERE workspace_id = ?');
88
+ expect(result.sql).toContain('ORDER BY timestamp DESC LIMIT ?');
89
+ expect(result.params).toEqual([ws, 50]);
90
+ });
91
+
92
+ it('should append to existing WHERE with correct param order before LIMIT', () => {
93
+ const result = injectWhereWorkspaceId(
94
+ 'SELECT * FROM agent_logs WHERE agent_id = ? ORDER BY timestamp DESC LIMIT ?',
95
+ ws,
96
+ ['agent-1', 100]
97
+ );
98
+ expect(result.sql).toBe(
99
+ 'SELECT * FROM agent_logs WHERE agent_id = ? AND workspace_id = ? ORDER BY timestamp DESC LIMIT ?'
100
+ );
101
+ expect(result.params).toEqual(['agent-1', ws, 100]);
102
+ });
103
+
104
+ it('should handle WHERE with no trailing clauses', () => {
105
+ const result = injectWhereWorkspaceId('SELECT * FROM agent_logs WHERE story_id = ?', ws, [
106
+ 'story-1',
107
+ ]);
108
+ expect(result.sql).toBe('SELECT * FROM agent_logs WHERE story_id = ? AND workspace_id = ?');
109
+ expect(result.params).toEqual(['story-1', ws]);
110
+ });
111
+
112
+ it('should handle WHERE with multiple conditions and LIMIT', () => {
113
+ const result = injectWhereWorkspaceId(
114
+ "SELECT COUNT(*) as count FROM agent_logs WHERE story_id = ? AND event_type = 'STORY_QA_FAILED'",
115
+ ws,
116
+ ['story-1']
117
+ );
118
+ expect(result.sql).toContain('AND workspace_id = ?');
119
+ expect(result.params).toEqual(['story-1', ws]);
120
+ });
121
+
122
+ it('should handle DELETE with WHERE and no trailing', () => {
123
+ const result = injectWhereWorkspaceId('DELETE FROM agent_logs WHERE timestamp < ?', ws, [
124
+ '2024-01-01',
125
+ ]);
126
+ expect(result.sql).toBe('DELETE FROM agent_logs WHERE timestamp < ? AND workspace_id = ?');
127
+ expect(result.params).toEqual(['2024-01-01', ws]);
128
+ });
129
+
130
+ it('should skip injection when workspace_id already present', () => {
131
+ const sql = 'SELECT * FROM agent_logs WHERE workspace_id = ? AND agent_id = ?';
132
+ const result = injectWhereWorkspaceId(sql, ws, [ws, 'agent-1']);
133
+ expect(result.sql).toBe(sql);
134
+ expect(result.params).toEqual([ws, 'agent-1']);
135
+ });
136
+ });
137
+
138
+ describe('injectInsertWorkspaceId', () => {
139
+ const ws = 'ws-123';
140
+
141
+ it('should add workspace_id column and value to INSERT', () => {
142
+ const result = injectInsertWorkspaceId(
143
+ 'INSERT INTO agent_logs (agent_id, event_type) VALUES (?, ?)',
144
+ ws,
145
+ ['agent-1', 'AGENT_SPAWNED']
146
+ );
147
+ expect(result.sql).toContain('workspace_id');
148
+ expect(result.params).toEqual(['agent-1', 'AGENT_SPAWNED', ws]);
149
+ });
150
+
151
+ it('should skip injection when workspace_id already present', () => {
152
+ const sql = 'INSERT INTO agent_logs (agent_id, workspace_id) VALUES (?, ?)';
153
+ const result = injectInsertWorkspaceId(sql, ws, ['agent-1', ws]);
154
+ expect(result.sql).toBe(sql);
155
+ expect(result.params).toEqual(['agent-1', ws]);
156
+ });
157
+ });
158
+
74
159
  describe('convertParams edge cases', () => {
75
160
  it('should handle empty string', () => {
76
161
  expect(convertParams('')).toBe('');
@@ -157,7 +157,7 @@ function needsWorkspaceScope(sql: string): boolean {
157
157
  * Transforms: INSERT INTO table (col1, col2) VALUES (?, ?)
158
158
  * Into: INSERT INTO table (col1, col2, workspace_id) VALUES ($1, $2, $3)
159
159
  */
160
- function injectInsertWorkspaceId(
160
+ export function injectInsertWorkspaceId(
161
161
  sql: string,
162
162
  workspaceId: string,
163
163
  params: unknown[]
@@ -187,7 +187,7 @@ function injectInsertWorkspaceId(
187
187
  * When the query uses JOINs, qualifies workspace_id with the primary table alias
188
188
  * to avoid ambiguous column references.
189
189
  */
190
- function injectWhereWorkspaceId(
190
+ export function injectWhereWorkspaceId(
191
191
  sql: string,
192
192
  workspaceId: string,
193
193
  params: unknown[]
@@ -236,9 +236,18 @@ function injectWhereWorkspaceId(
236
236
 
237
237
  const whereBody = after.substring(0, trailingPos);
238
238
  const trailing = after.substring(trailingPos);
239
+
240
+ // Count ? placeholders before the injection point (before + whereBody) to
241
+ // splice workspace_id into the correct position in the params array.
242
+ // Appending to the end is wrong when trailing clauses (LIMIT, OFFSET) have
243
+ // their own positional params.
244
+ const questionsBefore = ((before + whereBody).match(/\?/g) || []).length;
245
+ const newParams = [...params];
246
+ newParams.splice(questionsBefore, 0, workspaceId);
247
+
239
248
  return {
240
249
  sql: `${before}${whereBody} AND ${wsCol} = ?${trailing}`,
241
- params: [...params, workspaceId],
250
+ params: newParams,
242
251
  };
243
252
  }
244
253
 
@@ -136,12 +136,18 @@ export async function getTotalTokens(
136
136
  params
137
137
  );
138
138
 
139
- return (
140
- result || {
141
- total_input_tokens: 0,
142
- total_output_tokens: 0,
143
- total_tokens: 0,
144
- record_count: 0,
145
- }
146
- );
139
+ // Postgres SUM/COUNT return bigint, which node-postgres converts to strings.
140
+ // Coerce to numbers for consistent behavior across SQLite and Postgres.
141
+ const raw = result || {
142
+ total_input_tokens: 0,
143
+ total_output_tokens: 0,
144
+ total_tokens: 0,
145
+ record_count: 0,
146
+ };
147
+ return {
148
+ total_input_tokens: Number(raw.total_input_tokens),
149
+ total_output_tokens: Number(raw.total_output_tokens),
150
+ total_tokens: Number(raw.total_tokens),
151
+ record_count: Number(raw.record_count),
152
+ };
147
153
  }
@@ -8,8 +8,9 @@
8
8
  * Also reads token usage directly from Claude Code's JSONL conversation logs.
9
9
  */
10
10
 
11
- import { readFileSync, readdirSync } from 'fs';
12
- import { homedir } from 'os';
11
+ import { execSync } from 'child_process';
12
+ import { readFileSync, readdirSync, statSync } from 'fs';
13
+ import { homedir, userInfo } from 'os';
13
14
  import { join, resolve } from 'path';
14
15
 
15
16
  export interface ParsedTokenUsage {
@@ -274,12 +275,43 @@ export function getTokenUsageForAgent(workDir: string): ParsedTokenUsage | null
274
275
  return { inputTokens: totalInput, outputTokens: totalOutput, totalTokens };
275
276
  }
276
277
 
278
+ /**
279
+ * Resolve the home directory for the OS user that owns a given path.
280
+ * Falls back to the current process's homedir() if detection fails.
281
+ */
282
+ function resolveHomeDirForPath(dirPath: string): string {
283
+ try {
284
+ const stat = statSync(dirPath);
285
+ const currentUid = userInfo().uid;
286
+
287
+ // If the directory is owned by the current user, just use homedir()
288
+ if (stat.uid === currentUid) {
289
+ return homedir();
290
+ }
291
+
292
+ // Look up the owning user's home directory via getent (POSIX)
293
+ const passwd = execSync(`getent passwd ${stat.uid}`, { encoding: 'utf-8' }).trim();
294
+ const fields = passwd.split(':');
295
+ if (fields.length >= 6 && fields[5]) {
296
+ return fields[5];
297
+ }
298
+ } catch {
299
+ // Fall through to default
300
+ }
301
+
302
+ return homedir();
303
+ }
304
+
277
305
  /**
278
306
  * Find all JSONL session files for a given working directory.
307
+ * Resolves the Claude config directory from the user that owns the workDir,
308
+ * so the manager can read JSONL logs even when running as a different user.
279
309
  */
280
310
  function findAllSessionFiles(workDir: string): string[] {
281
- const projectDir = pathToClaudeProjectDir(resolve(workDir));
282
- const claudeProjectsDir = join(homedir(), '.claude', 'projects', projectDir);
311
+ const resolvedWorkDir = resolve(workDir);
312
+ const projectDir = pathToClaudeProjectDir(resolvedWorkDir);
313
+ const home = resolveHomeDirForPath(resolvedWorkDir);
314
+ const claudeProjectsDir = join(home, '.claude', 'projects', projectDir);
283
315
 
284
316
  try {
285
317
  return readdirSync(claudeProjectsDir)