@archznn/crewloop-skills 0.4.0 → 0.4.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 (132) hide show
  1. package/package.json +18 -3
  2. package/packages/cli/README.md +55 -0
  3. package/packages/cli/bin/crewloop.js +6 -0
  4. package/packages/cli/dist/agents.d.ts +7 -0
  5. package/packages/cli/dist/agents.d.ts.map +1 -0
  6. package/packages/cli/dist/agents.js +31 -0
  7. package/packages/cli/dist/agents.js.map +1 -0
  8. package/packages/cli/dist/cli.d.ts +14 -0
  9. package/packages/cli/dist/cli.d.ts.map +1 -0
  10. package/packages/cli/dist/cli.js +283 -0
  11. package/packages/cli/dist/cli.js.map +1 -0
  12. package/packages/cli/dist/installer.d.ts +19 -0
  13. package/packages/cli/dist/installer.d.ts.map +1 -0
  14. package/packages/cli/dist/installer.js +89 -0
  15. package/packages/cli/dist/installer.js.map +1 -0
  16. package/packages/cli/dist/mcp.d.ts +20 -0
  17. package/packages/cli/dist/mcp.d.ts.map +1 -0
  18. package/packages/cli/dist/mcp.js +130 -0
  19. package/packages/cli/dist/mcp.js.map +1 -0
  20. package/packages/cli/dist/resolver.d.ts +7 -0
  21. package/packages/cli/dist/resolver.d.ts.map +1 -0
  22. package/packages/cli/dist/resolver.js +57 -0
  23. package/packages/cli/dist/resolver.js.map +1 -0
  24. package/packages/cli/dist/tests/agents.test.d.ts +2 -0
  25. package/packages/cli/dist/tests/agents.test.d.ts.map +1 -0
  26. package/packages/cli/dist/tests/agents.test.js +27 -0
  27. package/packages/cli/dist/tests/agents.test.js.map +1 -0
  28. package/packages/cli/dist/tests/cli.test.d.ts +2 -0
  29. package/packages/cli/dist/tests/cli.test.d.ts.map +1 -0
  30. package/packages/cli/dist/tests/cli.test.js +103 -0
  31. package/packages/cli/dist/tests/cli.test.js.map +1 -0
  32. package/packages/cli/dist/tests/installer.test.d.ts +2 -0
  33. package/packages/cli/dist/tests/installer.test.d.ts.map +1 -0
  34. package/packages/cli/dist/tests/installer.test.js +129 -0
  35. package/packages/cli/dist/tests/installer.test.js.map +1 -0
  36. package/packages/cli/dist/tests/mcp.test.d.ts +2 -0
  37. package/packages/cli/dist/tests/mcp.test.d.ts.map +1 -0
  38. package/packages/cli/dist/tests/mcp.test.js +153 -0
  39. package/packages/cli/dist/tests/mcp.test.js.map +1 -0
  40. package/packages/cli/dist/tests/resolver.test.d.ts +2 -0
  41. package/packages/cli/dist/tests/resolver.test.d.ts.map +1 -0
  42. package/packages/cli/dist/tests/resolver.test.js +41 -0
  43. package/packages/cli/dist/tests/resolver.test.js.map +1 -0
  44. package/servers/dashboard/bin/crewloop-dashboard.js +0 -0
  45. package/servers/dashboard/dist/adapters/codex.d.ts +23 -0
  46. package/servers/dashboard/dist/adapters/codex.d.ts.map +1 -0
  47. package/servers/dashboard/dist/adapters/codex.js +28 -0
  48. package/servers/dashboard/dist/adapters/codex.js.map +1 -0
  49. package/servers/dashboard/dist/adapters/kimi.d.ts +13 -0
  50. package/servers/dashboard/dist/adapters/kimi.d.ts.map +1 -0
  51. package/servers/dashboard/dist/adapters/kimi.js +28 -0
  52. package/servers/dashboard/dist/adapters/kimi.js.map +1 -0
  53. package/servers/dashboard/dist/adapters/opencode.d.ts +9 -0
  54. package/servers/dashboard/dist/adapters/opencode.d.ts.map +1 -0
  55. package/servers/dashboard/dist/adapters/opencode.js +26 -0
  56. package/servers/dashboard/dist/adapters/opencode.js.map +1 -0
  57. package/servers/dashboard/dist/adapters/shim.d.ts +7 -0
  58. package/servers/dashboard/dist/adapters/shim.d.ts.map +1 -0
  59. package/servers/dashboard/dist/adapters/shim.js +107 -0
  60. package/servers/dashboard/dist/adapters/shim.js.map +1 -0
  61. package/servers/dashboard/dist/adapters/shim.test.d.ts +2 -0
  62. package/servers/dashboard/dist/adapters/shim.test.d.ts.map +1 -0
  63. package/servers/dashboard/dist/adapters/shim.test.js +72 -0
  64. package/servers/dashboard/dist/adapters/shim.test.js.map +1 -0
  65. package/servers/dashboard/dist/api/event.d.ts +13 -0
  66. package/servers/dashboard/dist/api/event.d.ts.map +1 -0
  67. package/servers/dashboard/dist/api/event.js +52 -0
  68. package/servers/dashboard/dist/api/event.js.map +1 -0
  69. package/servers/dashboard/dist/api/skills.d.ts +4 -0
  70. package/servers/dashboard/dist/api/skills.d.ts.map +1 -0
  71. package/servers/dashboard/dist/api/skills.js +12 -0
  72. package/servers/dashboard/dist/api/skills.js.map +1 -0
  73. package/servers/dashboard/dist/config.d.ts +11 -0
  74. package/servers/dashboard/dist/config.d.ts.map +1 -0
  75. package/servers/dashboard/dist/config.js +65 -0
  76. package/servers/dashboard/dist/config.js.map +1 -0
  77. package/servers/dashboard/dist/filters/sanitize.d.ts +14 -0
  78. package/servers/dashboard/dist/filters/sanitize.d.ts.map +1 -0
  79. package/servers/dashboard/dist/filters/sanitize.js +64 -0
  80. package/servers/dashboard/dist/filters/sanitize.js.map +1 -0
  81. package/servers/dashboard/dist/filters/sanitize.test.d.ts +2 -0
  82. package/servers/dashboard/dist/filters/sanitize.test.d.ts.map +1 -0
  83. package/servers/dashboard/dist/filters/sanitize.test.js +71 -0
  84. package/servers/dashboard/dist/filters/sanitize.test.js.map +1 -0
  85. package/servers/dashboard/dist/index.d.ts +2 -0
  86. package/servers/dashboard/dist/index.d.ts.map +1 -0
  87. package/servers/dashboard/dist/index.js +22 -0
  88. package/servers/dashboard/dist/index.js.map +1 -0
  89. package/servers/dashboard/dist/presenter.d.ts +7 -0
  90. package/servers/dashboard/dist/presenter.d.ts.map +1 -0
  91. package/servers/dashboard/dist/presenter.js +54 -0
  92. package/servers/dashboard/dist/presenter.js.map +1 -0
  93. package/servers/dashboard/dist/presenter.test.d.ts +2 -0
  94. package/servers/dashboard/dist/presenter.test.d.ts.map +1 -0
  95. package/servers/dashboard/dist/presenter.test.js +66 -0
  96. package/servers/dashboard/dist/presenter.test.js.map +1 -0
  97. package/servers/dashboard/dist/server.d.ts +13 -0
  98. package/servers/dashboard/dist/server.d.ts.map +1 -0
  99. package/servers/dashboard/dist/server.js +162 -0
  100. package/servers/dashboard/dist/server.js.map +1 -0
  101. package/servers/dashboard/dist/server.test.d.ts +2 -0
  102. package/servers/dashboard/dist/server.test.d.ts.map +1 -0
  103. package/servers/dashboard/dist/server.test.js +113 -0
  104. package/servers/dashboard/dist/server.test.js.map +1 -0
  105. package/servers/dashboard/dist/skills/infer.d.ts +8 -0
  106. package/servers/dashboard/dist/skills/infer.d.ts.map +1 -0
  107. package/servers/dashboard/dist/skills/infer.js +48 -0
  108. package/servers/dashboard/dist/skills/infer.js.map +1 -0
  109. package/servers/dashboard/dist/skills/infer.test.d.ts +2 -0
  110. package/servers/dashboard/dist/skills/infer.test.d.ts.map +1 -0
  111. package/servers/dashboard/dist/skills/infer.test.js +82 -0
  112. package/servers/dashboard/dist/skills/infer.test.js.map +1 -0
  113. package/servers/dashboard/dist/skills/mapping.d.ts +5 -0
  114. package/servers/dashboard/dist/skills/mapping.d.ts.map +1 -0
  115. package/servers/dashboard/dist/skills/mapping.js +28 -0
  116. package/servers/dashboard/dist/skills/mapping.js.map +1 -0
  117. package/servers/dashboard/dist/skills/registry.d.ts +11 -0
  118. package/servers/dashboard/dist/skills/registry.d.ts.map +1 -0
  119. package/servers/dashboard/dist/skills/registry.js +59 -0
  120. package/servers/dashboard/dist/skills/registry.js.map +1 -0
  121. package/servers/dashboard/dist/state.d.ts +18 -0
  122. package/servers/dashboard/dist/state.d.ts.map +1 -0
  123. package/servers/dashboard/dist/state.js +91 -0
  124. package/servers/dashboard/dist/state.js.map +1 -0
  125. package/servers/dashboard/dist/state.test.d.ts +2 -0
  126. package/servers/dashboard/dist/state.test.d.ts.map +1 -0
  127. package/servers/dashboard/dist/state.test.js +83 -0
  128. package/servers/dashboard/dist/state.test.js.map +1 -0
  129. package/servers/dashboard/dist/types.d.ts +86 -0
  130. package/servers/dashboard/dist/types.d.ts.map +1 -0
  131. package/servers/dashboard/dist/types.js +3 -0
  132. package/servers/dashboard/dist/types.js.map +1 -0
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createEventHandler = createEventHandler;
4
+ const sanitize_1 = require("../filters/sanitize");
5
+ const presenter_1 = require("../presenter");
6
+ function createEventHandler(deps) {
7
+ return async (req, res) => {
8
+ if (req.method !== 'POST') {
9
+ res.statusCode = 405;
10
+ res.end(JSON.stringify({ error: 'Method not allowed' }));
11
+ return;
12
+ }
13
+ let body = '';
14
+ req.setEncoding('utf8');
15
+ req.on('data', (chunk) => {
16
+ body += chunk;
17
+ });
18
+ await new Promise((resolve) => {
19
+ req.on('end', resolve);
20
+ });
21
+ let event;
22
+ try {
23
+ event = JSON.parse(body);
24
+ }
25
+ catch {
26
+ res.statusCode = 400;
27
+ res.end(JSON.stringify({ error: 'Invalid JSON' }));
28
+ return;
29
+ }
30
+ if (!(0, sanitize_1.sanitizeEventBoundary)(event)) {
31
+ res.statusCode = 400;
32
+ res.end(JSON.stringify({ error: 'Event contains unsafe fields' }));
33
+ return;
34
+ }
35
+ if (!event.session_id || !event.event_type) {
36
+ res.statusCode = 400;
37
+ res.end(JSON.stringify({ error: 'Missing required fields' }));
38
+ return;
39
+ }
40
+ const session = deps.state.applyEvent(event);
41
+ const inferred = deps.inference.infer(event, session);
42
+ if (inferred.skill !== session.active_skill || inferred.confidence !== session.active_confidence) {
43
+ deps.state.setActiveSkill(session.id, inferred.skill, inferred.confidence);
44
+ }
45
+ const updatedSession = deps.state.getSession(session.id);
46
+ deps.setActiveSessionId(updatedSession.id);
47
+ deps.broadcast((0, presenter_1.createUpdateMessage)(updatedSession, deps.getActiveSessionId()));
48
+ res.statusCode = 200;
49
+ res.end(JSON.stringify({ ok: true }));
50
+ };
51
+ }
52
+ //# sourceMappingURL=event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.js","sourceRoot":"","sources":["../../src/api/event.ts"],"names":[],"mappings":";;AAeA,gDAsDC;AAjED,kDAA4D;AAC5D,4CAAmD;AAUnD,SAAgB,kBAAkB,CAAC,IAA8B;IAC/D,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAiB,EAAE;QACxE,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1B,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QAED,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,IAAI,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,IAAI,KAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAA,gCAAqB,EAAC,KAA2C,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YAC3C,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEtD,IAAI,QAAQ,CAAC,KAAK,KAAK,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,UAAU,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC;YACjG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAE,CAAC;QAC1D,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAE3C,IAAI,CAAC,SAAS,CAAC,IAAA,+BAAmB,EAAC,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;QAE/E,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACrB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { SkillRegistry } from '../skills/registry';
3
+ export declare function createSkillsHandler(registry: SkillRegistry): (_req: IncomingMessage, res: ServerResponse) => Promise<void>;
4
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/api/skills.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,IAC3C,MAAM,eAAe,EAAE,KAAK,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CAMzE"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSkillsHandler = createSkillsHandler;
4
+ function createSkillsHandler(registry) {
5
+ return async (_req, res) => {
6
+ const skills = registry.getSkills();
7
+ res.statusCode = 200;
8
+ res.setHeader('Content-Type', 'application/json');
9
+ res.end(JSON.stringify(skills));
10
+ };
11
+ }
12
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/api/skills.ts"],"names":[],"mappings":";;AAGA,kDAOC;AAPD,SAAgB,mBAAmB,CAAC,QAAuB;IACzD,OAAO,KAAK,EAAE,IAAqB,EAAE,GAAmB,EAAiB,EAAE;QACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;QACpC,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;QACrB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ServerConfig } from './types';
2
+ export declare const SAFE_TOOL_INPUT_KEYS: Set<string>;
3
+ export declare const DANGEROUS_TOOL_INPUT_KEYS: Set<string>;
4
+ export declare const DEFAULT_PORT = 7890;
5
+ export declare const DEFAULT_HOST = "127.0.0.1";
6
+ export declare const DEFAULT_MAX_EVENTS = 200;
7
+ export declare const DEFAULT_SESSION_MAX_AGE_MS: number;
8
+ export declare const DEFAULT_PRUNE_INTERVAL_MS: number;
9
+ export declare function loadConfig(): ServerConfig;
10
+ export declare function resolvePackageRoot(): string;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,oBAAoB,aAM/B,CAAC;AAEH,eAAO,MAAM,yBAAyB,aAYpC,CAAC;AAEH,eAAO,MAAM,YAAY,OAAO,CAAC;AACjC,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,0BAA0B,QAAsB,CAAC;AAC9D,eAAO,MAAM,yBAAyB,QAAY,CAAC;AAEnD,wBAAgB,UAAU,IAAI,YAAY,CAYzC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAmB3C"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_PRUNE_INTERVAL_MS = exports.DEFAULT_SESSION_MAX_AGE_MS = exports.DEFAULT_MAX_EVENTS = exports.DEFAULT_HOST = exports.DEFAULT_PORT = exports.DANGEROUS_TOOL_INPUT_KEYS = exports.SAFE_TOOL_INPUT_KEYS = void 0;
7
+ exports.loadConfig = loadConfig;
8
+ exports.resolvePackageRoot = resolvePackageRoot;
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const node_fs_1 = __importDefault(require("node:fs"));
11
+ exports.SAFE_TOOL_INPUT_KEYS = new Set([
12
+ 'path',
13
+ 'file_path',
14
+ 'skill',
15
+ 'subagent_type',
16
+ 'url',
17
+ ]);
18
+ exports.DANGEROUS_TOOL_INPUT_KEYS = new Set([
19
+ 'command',
20
+ 'content',
21
+ 'text',
22
+ 'code',
23
+ 'prompt',
24
+ 'api_key',
25
+ 'token',
26
+ 'password',
27
+ 'secret',
28
+ 'key',
29
+ 'authorization',
30
+ ]);
31
+ exports.DEFAULT_PORT = 7890;
32
+ exports.DEFAULT_HOST = '127.0.0.1';
33
+ exports.DEFAULT_MAX_EVENTS = 200;
34
+ exports.DEFAULT_SESSION_MAX_AGE_MS = 24 * 60 * 60 * 1000;
35
+ exports.DEFAULT_PRUNE_INTERVAL_MS = 60 * 1000;
36
+ function loadConfig() {
37
+ const port = parseInt(process.env.CREWLOOP_DASHBOARD_PORT || String(exports.DEFAULT_PORT), 10);
38
+ const host = process.env.CREWLOOP_DASHBOARD_HOST || exports.DEFAULT_HOST;
39
+ return {
40
+ port,
41
+ host,
42
+ packageRoot: resolvePackageRoot(),
43
+ maxEventsPerSession: exports.DEFAULT_MAX_EVENTS,
44
+ sessionMaxAgeMs: exports.DEFAULT_SESSION_MAX_AGE_MS,
45
+ pruneIntervalMs: exports.DEFAULT_PRUNE_INTERVAL_MS,
46
+ };
47
+ }
48
+ function resolvePackageRoot() {
49
+ try {
50
+ const skillsPackageJson = require.resolve('@archznn/crewloop-skills/package.json');
51
+ return node_path_1.default.dirname(skillsPackageJson);
52
+ }
53
+ catch {
54
+ const cwdNodeModules = node_path_1.default.join(process.cwd(), 'node_modules', '@archznn', 'crewloop-skills');
55
+ if (node_fs_1.default.existsSync(node_path_1.default.join(cwdNodeModules, 'package.json'))) {
56
+ return cwdNodeModules;
57
+ }
58
+ }
59
+ const monorepoRoot = node_path_1.default.resolve(__dirname, '..', '..', '..');
60
+ if (node_fs_1.default.existsSync(node_path_1.default.join(monorepoRoot, 'skills', 'orchestrator', 'SKILL.md'))) {
61
+ return monorepoRoot;
62
+ }
63
+ throw new Error('Could not find CrewLoop skills package. Install @archznn/crewloop-skills or run from the CrewLoop repository.');
64
+ }
65
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAgCA,gCAYC;AAED,gDAmBC;AAjED,0DAA6B;AAC7B,sDAAyB;AAGZ,QAAA,oBAAoB,GAAG,IAAI,GAAG,CAAC;IAC1C,MAAM;IACN,WAAW;IACX,OAAO;IACP,eAAe;IACf,KAAK;CACN,CAAC,CAAC;AAEU,QAAA,yBAAyB,GAAG,IAAI,GAAG,CAAC;IAC/C,SAAS;IACT,SAAS;IACT,MAAM;IACN,MAAM;IACN,QAAQ;IACR,SAAS;IACT,OAAO;IACP,UAAU;IACV,QAAQ;IACR,KAAK;IACL,eAAe;CAChB,CAAC,CAAC;AAEU,QAAA,YAAY,GAAG,IAAI,CAAC;AACpB,QAAA,YAAY,GAAG,WAAW,CAAC;AAC3B,QAAA,kBAAkB,GAAG,GAAG,CAAC;AACzB,QAAA,0BAA0B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACjD,QAAA,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnD,SAAgB,UAAU;IACxB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,MAAM,CAAC,oBAAY,CAAC,EAAE,EAAE,CAAC,CAAC;IACvF,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,oBAAY,CAAC;IAEjE,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,WAAW,EAAE,kBAAkB,EAAE;QACjC,mBAAmB,EAAE,0BAAkB;QACvC,eAAe,EAAE,kCAA0B;QAC3C,eAAe,EAAE,iCAAyB;KAC3C,CAAC;AACJ,CAAC;AAED,SAAgB,kBAAkB;IAChC,IAAI,CAAC;QACH,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACnF,OAAO,mBAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,cAAc,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;QAC/F,IAAI,iBAAE,CAAC,UAAU,CAAC,mBAAI,CAAC,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YAC7D,OAAO,cAAc,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,mBAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/D,IAAI,iBAAE,CAAC,UAAU,CAAC,mBAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QACjF,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { EventStatus } from '../types';
2
+ export interface SanitizeInput {
3
+ tool_name: string;
4
+ tool_input?: Record<string, unknown>;
5
+ tool_response?: Record<string, unknown>;
6
+ }
7
+ export interface SafeDetail {
8
+ detail?: string;
9
+ status?: EventStatus;
10
+ duration_ms?: number;
11
+ }
12
+ export declare function sanitize(input: SanitizeInput, event: 'pre' | 'post'): SafeDetail;
13
+ export declare function sanitizeEventBoundary(payload: Record<string, unknown>): boolean;
14
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/filters/sanitize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAuBD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,CA+BhF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAQ/E"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sanitize = sanitize;
4
+ exports.sanitizeEventBoundary = sanitizeEventBoundary;
5
+ const config_1 = require("../config");
6
+ function extractSafeDetail(input) {
7
+ for (const [key, value] of Object.entries(input)) {
8
+ const lower = key.toLowerCase();
9
+ if (!config_1.SAFE_TOOL_INPUT_KEYS.has(lower)) {
10
+ continue;
11
+ }
12
+ if (typeof value === 'string') {
13
+ if (lower === 'url') {
14
+ try {
15
+ const url = new URL(value);
16
+ return url.hostname;
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ }
22
+ return value;
23
+ }
24
+ }
25
+ return undefined;
26
+ }
27
+ function sanitize(input, event) {
28
+ const result = {};
29
+ if (input.tool_input) {
30
+ const detail = extractSafeDetail(input.tool_input);
31
+ if (detail) {
32
+ result.detail = detail;
33
+ }
34
+ }
35
+ if (event === 'post' && input.tool_response && typeof input.tool_response === 'object') {
36
+ const response = input.tool_response;
37
+ if (typeof response.duration_ms === 'number') {
38
+ result.duration_ms = response.duration_ms;
39
+ }
40
+ else if (typeof response.durationMs === 'number') {
41
+ result.duration_ms = response.durationMs;
42
+ }
43
+ if (response.is_error === true || response.success === false || response.error) {
44
+ result.status = 'error';
45
+ }
46
+ else if (response.success === true || response.is_error === false) {
47
+ result.status = 'success';
48
+ }
49
+ }
50
+ if (event === 'pre') {
51
+ result.status = 'running';
52
+ }
53
+ return result;
54
+ }
55
+ function sanitizeEventBoundary(payload) {
56
+ const keys = Object.keys(payload);
57
+ for (const key of keys) {
58
+ if (config_1.DANGEROUS_TOOL_INPUT_KEYS.has(key.toLowerCase())) {
59
+ return false;
60
+ }
61
+ }
62
+ return true;
63
+ }
64
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/filters/sanitize.ts"],"names":[],"mappings":";;AAoCA,4BA+BC;AAED,sDAQC;AA7ED,sCAA4E;AAe5E,SAAS,iBAAiB,CAAC,KAA8B;IACvD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAChC,IAAI,CAAC,6BAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;gBACpB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;oBAC3B,OAAO,GAAG,CAAC,QAAQ,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,QAAQ,CAAC,KAAoB,EAAE,KAAqB;IAClE,MAAM,MAAM,GAAe,EAAE,CAAC;IAE9B,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QACzB,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QACvF,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAwC,CAAC;QAEhE,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC7C,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;QAC5C,CAAC;aAAM,IAAI,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnD,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC3C,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC/E,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC;QAC1B,CAAC;aAAM,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;YACpE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,qBAAqB,CAAC,OAAgC;IACpE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,kCAAyB,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACrD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sanitize.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.test.d.ts","sourceRoot":"","sources":["../../src/filters/sanitize.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = require("node:test");
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const sanitize_1 = require("./sanitize");
9
+ (0, node_test_1.describe)('sanitize', () => {
10
+ (0, node_test_1.it)('extracts safe path details', () => {
11
+ const result = (0, sanitize_1.sanitize)({
12
+ tool_name: 'Read',
13
+ tool_input: { path: 'README.md' },
14
+ }, 'pre');
15
+ strict_1.default.equal(result.detail, 'README.md');
16
+ strict_1.default.equal(result.status, 'running');
17
+ });
18
+ (0, node_test_1.it)('extracts skill name from Skill tool input', () => {
19
+ const result = (0, sanitize_1.sanitize)({
20
+ tool_name: 'Skill',
21
+ tool_input: { skill: 'architect' },
22
+ }, 'pre');
23
+ strict_1.default.equal(result.detail, 'architect');
24
+ });
25
+ (0, node_test_1.it)('strips dangerous command input', () => {
26
+ const result = (0, sanitize_1.sanitize)({
27
+ tool_name: 'Bash',
28
+ tool_input: { command: 'rm -rf /' },
29
+ }, 'pre');
30
+ strict_1.default.equal(result.detail, undefined);
31
+ strict_1.default.equal(result.status, 'running');
32
+ });
33
+ (0, node_test_1.it)('strips content/text input', () => {
34
+ const result = (0, sanitize_1.sanitize)({
35
+ tool_name: 'Write',
36
+ tool_input: { path: 'secret.env', content: 'API_KEY=123' },
37
+ }, 'pre');
38
+ strict_1.default.equal(result.detail, 'secret.env');
39
+ });
40
+ (0, node_test_1.it)('marks success on post event', () => {
41
+ const result = (0, sanitize_1.sanitize)({
42
+ tool_name: 'Read',
43
+ tool_input: { path: 'README.md' },
44
+ tool_response: { success: true, duration_ms: 12 },
45
+ }, 'post');
46
+ strict_1.default.equal(result.status, 'success');
47
+ strict_1.default.equal(result.duration_ms, 12);
48
+ });
49
+ (0, node_test_1.it)('marks error on post event', () => {
50
+ const result = (0, sanitize_1.sanitize)({
51
+ tool_name: 'Bash',
52
+ tool_response: { success: false, durationMs: 45 },
53
+ }, 'post');
54
+ strict_1.default.equal(result.status, 'error');
55
+ strict_1.default.equal(result.duration_ms, 45);
56
+ });
57
+ (0, node_test_1.it)('extracts hostname from safe url input', () => {
58
+ const result = (0, sanitize_1.sanitize)({
59
+ tool_name: 'FetchURL',
60
+ tool_input: { url: 'https://example.com/path' },
61
+ }, 'pre');
62
+ strict_1.default.equal(result.detail, 'example.com');
63
+ strict_1.default.equal(result.status, 'running');
64
+ });
65
+ (0, node_test_1.it)('rejects events with dangerous keys at boundary', () => {
66
+ strict_1.default.equal((0, sanitize_1.sanitizeEventBoundary)({ command: 'ls' }), false);
67
+ strict_1.default.equal((0, sanitize_1.sanitizeEventBoundary)({ token: 'abc' }), false);
68
+ strict_1.default.equal((0, sanitize_1.sanitizeEventBoundary)({ path: 'README.md' }), true);
69
+ });
70
+ });
71
+ //# sourceMappingURL=sanitize.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.test.js","sourceRoot":"","sources":["../../src/filters/sanitize.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("./config");
4
+ const server_1 = require("./server");
5
+ async function main() {
6
+ const config = (0, config_1.loadConfig)();
7
+ const server = (0, server_1.createDashboardServer)(config);
8
+ process.on('SIGINT', async () => {
9
+ await server.stop();
10
+ process.exit(0);
11
+ });
12
+ process.on('SIGTERM', async () => {
13
+ await server.stop();
14
+ process.exit(0);
15
+ });
16
+ await server.start();
17
+ }
18
+ main().catch((err) => {
19
+ console.error('Failed to start dashboard:', err);
20
+ process.exit(1);
21
+ });
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,qCAAsC;AACtC,qCAAiD;AAEjD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAA,8BAAqB,EAAC,MAAM,CAAC,CAAC;IAE7C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Session, DashboardState, ClientSession, ClientEvent, ClientWebSocketMessage } from './types';
2
+ export declare function presentEvent(event: Session['events'][number]): ClientEvent;
3
+ export declare function presentSession(session: Session): ClientSession;
4
+ export declare function presentState(state: DashboardState): ClientSession[];
5
+ export declare function createSnapshotMessage(sessions: Session[]): ClientWebSocketMessage;
6
+ export declare function createUpdateMessage(session: Session, activeSessionId?: string): ClientWebSocketMessage;
7
+ //# sourceMappingURL=presenter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.d.ts","sourceRoot":"","sources":["../src/presenter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAE3G,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,WAAW,CAW1E;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAkB9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,aAAa,EAAE,CAEnE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,sBAAsB,CAKjF;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,eAAe,CAAC,EAAE,MAAM,GACvB,sBAAsB,CAMxB"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.presentEvent = presentEvent;
4
+ exports.presentSession = presentSession;
5
+ exports.presentState = presentState;
6
+ exports.createSnapshotMessage = createSnapshotMessage;
7
+ exports.createUpdateMessage = createUpdateMessage;
8
+ function presentEvent(event) {
9
+ return {
10
+ id: event.id,
11
+ timestamp: event.timestamp,
12
+ event_type: event.event_type,
13
+ tool: event.tool,
14
+ detail: event.detail,
15
+ status: event.status,
16
+ duration_ms: event.duration_ms,
17
+ skill: event.skill,
18
+ };
19
+ }
20
+ function presentSession(session) {
21
+ return {
22
+ id: session.id,
23
+ source: session.source,
24
+ skill: session.active_skill,
25
+ activeSkill: session.active_skill
26
+ ? {
27
+ name: session.active_skill,
28
+ confidence: session.active_confidence || 'unknown',
29
+ }
30
+ : undefined,
31
+ status: session.status,
32
+ events: session.events.map(presentEvent),
33
+ startTime: session.started_at,
34
+ lastActivity: session.last_event_at,
35
+ toolCounts: session.tool_counts,
36
+ };
37
+ }
38
+ function presentState(state) {
39
+ return Object.values(state.sessions).map(presentSession);
40
+ }
41
+ function createSnapshotMessage(sessions) {
42
+ return {
43
+ type: 'snapshot',
44
+ sessions: sessions.map(presentSession),
45
+ };
46
+ }
47
+ function createUpdateMessage(session, activeSessionId) {
48
+ return {
49
+ type: 'update',
50
+ session: presentSession(session),
51
+ isActive: activeSessionId === session.id,
52
+ };
53
+ }
54
+ //# sourceMappingURL=presenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.js","sourceRoot":"","sources":["../src/presenter.ts"],"names":[],"mappings":";;AAEA,oCAWC;AAED,wCAkBC;AAED,oCAEC;AAED,sDAKC;AAED,kDASC;AArDD,SAAgB,YAAY,CAAC,KAAgC;IAC3D,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC;AAED,SAAgB,cAAc,CAAC,OAAgB;IAC7C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,YAAY;QAC3B,WAAW,EACT,OAAO,CAAC,YAAY;YAClB,CAAC,CAAC;gBACE,IAAI,EAAE,OAAO,CAAC,YAAY;gBAC1B,UAAU,EAAE,OAAO,CAAC,iBAAiB,IAAI,SAAS;aACnD;YACH,CAAC,CAAC,SAAS;QACf,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;QACxC,SAAS,EAAE,OAAO,CAAC,UAAU;QAC7B,YAAY,EAAE,OAAO,CAAC,aAAa;QACnC,UAAU,EAAE,OAAO,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAAC,KAAqB;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC3D,CAAC;AAED,SAAgB,qBAAqB,CAAC,QAAmB;IACvD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,SAAgB,mBAAmB,CACjC,OAAgB,EAChB,eAAwB;IAExB,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC;QAChC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,EAAE;KACzC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=presenter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.test.d.ts","sourceRoot":"","sources":["../src/presenter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = require("node:test");
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const presenter_1 = require("./presenter");
9
+ function makeSession(overrides = {}) {
10
+ return {
11
+ id: 'sess-1',
12
+ source: 'kimi',
13
+ events: [],
14
+ tool_counts: { Read: 2 },
15
+ started_at: 1000,
16
+ last_event_at: 2000,
17
+ active_skill: 'architect',
18
+ active_confidence: 'explicit',
19
+ status: 'running',
20
+ ...overrides,
21
+ };
22
+ }
23
+ (0, node_test_1.describe)('presenter', () => {
24
+ (0, node_test_1.it)('converts session to client shape', () => {
25
+ const session = makeSession();
26
+ const client = (0, presenter_1.presentSession)(session);
27
+ strict_1.default.equal(client.id, 'sess-1');
28
+ strict_1.default.equal(client.source, 'kimi');
29
+ strict_1.default.equal(client.skill, 'architect');
30
+ strict_1.default.deepEqual(client.activeSkill, { name: 'architect', confidence: 'explicit' });
31
+ strict_1.default.equal(client.status, 'running');
32
+ strict_1.default.equal(client.startTime, 1000);
33
+ strict_1.default.equal(client.lastActivity, 2000);
34
+ strict_1.default.deepEqual(client.toolCounts, { Read: 2 });
35
+ });
36
+ (0, node_test_1.it)('omits active skill when not set', () => {
37
+ const client = (0, presenter_1.presentSession)(makeSession({ active_skill: undefined }));
38
+ strict_1.default.equal(client.activeSkill, undefined);
39
+ strict_1.default.equal(client.skill, undefined);
40
+ });
41
+ (0, node_test_1.it)('presents state as client sessions', () => {
42
+ const state = {
43
+ sessions: {
44
+ 'sess-1': makeSession(),
45
+ },
46
+ };
47
+ const sessions = (0, presenter_1.presentState)(state);
48
+ strict_1.default.equal(sessions.length, 1);
49
+ strict_1.default.equal(sessions[0].id, 'sess-1');
50
+ });
51
+ (0, node_test_1.it)('creates snapshot message', () => {
52
+ const message = (0, presenter_1.createSnapshotMessage)([makeSession()]);
53
+ strict_1.default.equal(message.type, 'snapshot');
54
+ strict_1.default.equal(message.sessions.length, 1);
55
+ strict_1.default.equal(message.sessions[0].id, 'sess-1');
56
+ });
57
+ (0, node_test_1.it)('creates update message with isActive flag', () => {
58
+ const message = (0, presenter_1.createUpdateMessage)(makeSession(), 'sess-1');
59
+ strict_1.default.equal(message.type, 'update');
60
+ strict_1.default.equal(message.session.id, 'sess-1');
61
+ strict_1.default.equal(message.isActive, true);
62
+ const inactive = (0, presenter_1.createUpdateMessage)(makeSession(), 'sess-2');
63
+ strict_1.default.equal(inactive.isActive, false);
64
+ });
65
+ });
66
+ //# sourceMappingURL=presenter.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.test.js","sourceRoot":"","sources":["../src/presenter.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import http from 'node:http';
2
+ import { WebSocketServer } from 'ws';
3
+ import type { ServerConfig } from './types';
4
+ import { StateStore } from './state';
5
+ export interface DashboardServer {
6
+ httpServer: http.Server;
7
+ wss: WebSocketServer;
8
+ state: StateStore;
9
+ start: () => Promise<void>;
10
+ stop: () => Promise<void>;
11
+ }
12
+ export declare function createDashboardServer(config: ServerConfig): DashboardServer;
13
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAa,MAAM,IAAI,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAA0B,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAOrC,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;IACxB,GAAG,EAAE,eAAe,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAgK3E"}