@kb-labs/agent-cli 0.5.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.
Files changed (136) hide show
  1. package/README.md +56 -0
  2. package/dist/cli/commands/diff.d.ts +17 -0
  3. package/dist/cli/commands/diff.js +182 -0
  4. package/dist/cli/commands/diff.js.map +1 -0
  5. package/dist/cli/commands/history.d.ts +16 -0
  6. package/dist/cli/commands/history.js +216 -0
  7. package/dist/cli/commands/history.js.map +1 -0
  8. package/dist/cli/commands/quality-report.d.ts +21 -0
  9. package/dist/cli/commands/quality-report.js +457 -0
  10. package/dist/cli/commands/quality-report.js.map +1 -0
  11. package/dist/cli/commands/rollback.d.ts +27 -0
  12. package/dist/cli/commands/rollback.js +109 -0
  13. package/dist/cli/commands/rollback.js.map +1 -0
  14. package/dist/cli/commands/run.d.ts +42 -0
  15. package/dist/cli/commands/run.js +923 -0
  16. package/dist/cli/commands/run.js.map +1 -0
  17. package/dist/cli/commands/trace-context.d.ts +22 -0
  18. package/dist/cli/commands/trace-context.js +131 -0
  19. package/dist/cli/commands/trace-context.js.map +1 -0
  20. package/dist/cli/commands/trace-diagnose.d.ts +20 -0
  21. package/dist/cli/commands/trace-diagnose.js +434 -0
  22. package/dist/cli/commands/trace-diagnose.js.map +1 -0
  23. package/dist/cli/commands/trace-event-normalizer.d.ts +13 -0
  24. package/dist/cli/commands/trace-event-normalizer.js +39 -0
  25. package/dist/cli/commands/trace-event-normalizer.js.map +1 -0
  26. package/dist/cli/commands/trace-filter.d.ts +19 -0
  27. package/dist/cli/commands/trace-filter.js +153 -0
  28. package/dist/cli/commands/trace-filter.js.map +1 -0
  29. package/dist/cli/commands/trace-iteration.d.ts +18 -0
  30. package/dist/cli/commands/trace-iteration.js +192 -0
  31. package/dist/cli/commands/trace-iteration.js.map +1 -0
  32. package/dist/cli/commands/trace-stats.d.ts +17 -0
  33. package/dist/cli/commands/trace-stats.js +247 -0
  34. package/dist/cli/commands/trace-stats.js.map +1 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +473 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/manifest.d.ts +184 -0
  39. package/dist/manifest.js +473 -0
  40. package/dist/manifest.js.map +1 -0
  41. package/dist/rest/handlers/approve-handler.d.ts +15 -0
  42. package/dist/rest/handlers/approve-handler.js +60 -0
  43. package/dist/rest/handlers/approve-handler.js.map +1 -0
  44. package/dist/rest/handlers/approve-session-plan-handler.d.ts +10 -0
  45. package/dist/rest/handlers/approve-session-plan-handler.js +52 -0
  46. package/dist/rest/handlers/approve-session-plan-handler.js.map +1 -0
  47. package/dist/rest/handlers/correct-handler.d.ts +7 -0
  48. package/dist/rest/handlers/correct-handler.js +326 -0
  49. package/dist/rest/handlers/correct-handler.js.map +1 -0
  50. package/dist/rest/handlers/create-session-handler.d.ts +7 -0
  51. package/dist/rest/handlers/create-session-handler.js +25 -0
  52. package/dist/rest/handlers/create-session-handler.js.map +1 -0
  53. package/dist/rest/handlers/execute-session-plan-handler.d.ts +10 -0
  54. package/dist/rest/handlers/execute-session-plan-handler.js +635 -0
  55. package/dist/rest/handlers/execute-session-plan-handler.js.map +1 -0
  56. package/dist/rest/handlers/generate-spec-handler.d.ts +10 -0
  57. package/dist/rest/handlers/generate-spec-handler.js +389 -0
  58. package/dist/rest/handlers/generate-spec-handler.js.map +1 -0
  59. package/dist/rest/handlers/get-file-diff-handler.d.ts +24 -0
  60. package/dist/rest/handlers/get-file-diff-handler.js +44 -0
  61. package/dist/rest/handlers/get-file-diff-handler.js.map +1 -0
  62. package/dist/rest/handlers/get-session-handler.d.ts +10 -0
  63. package/dist/rest/handlers/get-session-handler.js +23 -0
  64. package/dist/rest/handlers/get-session-handler.js.map +1 -0
  65. package/dist/rest/handlers/get-session-plan-handler.d.ts +10 -0
  66. package/dist/rest/handlers/get-session-plan-handler.js +53 -0
  67. package/dist/rest/handlers/get-session-plan-handler.js.map +1 -0
  68. package/dist/rest/handlers/get-session-turns-handler.d.ts +16 -0
  69. package/dist/rest/handlers/get-session-turns-handler.js +35 -0
  70. package/dist/rest/handlers/get-session-turns-handler.js.map +1 -0
  71. package/dist/rest/handlers/get-spec-handler.d.ts +10 -0
  72. package/dist/rest/handlers/get-spec-handler.js +39 -0
  73. package/dist/rest/handlers/get-spec-handler.js.map +1 -0
  74. package/dist/rest/handlers/list-file-changes-handler.d.ts +13 -0
  75. package/dist/rest/handlers/list-file-changes-handler.js +34 -0
  76. package/dist/rest/handlers/list-file-changes-handler.js.map +1 -0
  77. package/dist/rest/handlers/list-sessions-handler.d.ts +7 -0
  78. package/dist/rest/handlers/list-sessions-handler.js +23 -0
  79. package/dist/rest/handlers/list-sessions-handler.js.map +1 -0
  80. package/dist/rest/handlers/rollback-handler.d.ts +22 -0
  81. package/dist/rest/handlers/rollback-handler.js +91 -0
  82. package/dist/rest/handlers/rollback-handler.js.map +1 -0
  83. package/dist/rest/handlers/run-handler.d.ts +7 -0
  84. package/dist/rest/handlers/run-handler.js +516 -0
  85. package/dist/rest/handlers/run-handler.js.map +1 -0
  86. package/dist/rest/handlers/sessions-handler.d.ts +18 -0
  87. package/dist/rest/handlers/sessions-handler.js +56 -0
  88. package/dist/rest/handlers/sessions-handler.js.map +1 -0
  89. package/dist/rest/handlers/status-handler.d.ts +7 -0
  90. package/dist/rest/handlers/status-handler.js +313 -0
  91. package/dist/rest/handlers/status-handler.js.map +1 -0
  92. package/dist/rest/handlers/stop-handler.d.ts +7 -0
  93. package/dist/rest/handlers/stop-handler.js +317 -0
  94. package/dist/rest/handlers/stop-handler.js.map +1 -0
  95. package/dist/widgets/220.js +446 -0
  96. package/dist/widgets/220.js.map +1 -0
  97. package/dist/widgets/331.js +2 -0
  98. package/dist/widgets/331.js.map +1 -0
  99. package/dist/widgets/403.js +2 -0
  100. package/dist/widgets/403.js.map +1 -0
  101. package/dist/widgets/406.js +35 -0
  102. package/dist/widgets/406.js.map +1 -0
  103. package/dist/widgets/455.js +2 -0
  104. package/dist/widgets/455.js.map +1 -0
  105. package/dist/widgets/482.js +2 -0
  106. package/dist/widgets/482.js.map +1 -0
  107. package/dist/widgets/485.js +2 -0
  108. package/dist/widgets/485.js.map +1 -0
  109. package/dist/widgets/527.js +2 -0
  110. package/dist/widgets/527.js.map +1 -0
  111. package/dist/widgets/628.js +2 -0
  112. package/dist/widgets/628.js.map +1 -0
  113. package/dist/widgets/694.js +2 -0
  114. package/dist/widgets/694.js.map +1 -0
  115. package/dist/widgets/712.js +2 -0
  116. package/dist/widgets/712.js.map +1 -0
  117. package/dist/widgets/866.js +2 -0
  118. package/dist/widgets/866.js.map +1 -0
  119. package/dist/widgets/915.js +39 -0
  120. package/dist/widgets/915.js.map +1 -0
  121. package/dist/widgets/957.js +10 -0
  122. package/dist/widgets/957.js.map +1 -0
  123. package/dist/widgets/983.js +2 -0
  124. package/dist/widgets/983.js.map +1 -0
  125. package/dist/widgets/@mf-types.d.ts +3 -0
  126. package/dist/widgets/@mf-types.zip +0 -0
  127. package/dist/widgets/__federation_expose_AgentsPage.js +2 -0
  128. package/dist/widgets/__federation_expose_AgentsPage.js.map +1 -0
  129. package/dist/widgets/mf-manifest.json +260 -0
  130. package/dist/widgets/mf-stats.json +305 -0
  131. package/dist/widgets/remoteEntry.js +7 -0
  132. package/dist/widgets/remoteEntry.js.map +1 -0
  133. package/dist/ws/session-stream-handler.d.ts +8 -0
  134. package/dist/ws/session-stream-handler.js +409 -0
  135. package/dist/ws/session-stream-handler.js.map +1 -0
  136. package/package.json +83 -0
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # @kb-labs/agent-cli
2
+
3
+ CLI plugin for the KB Labs agent system. Provides the `agent:run` command and REST/WebSocket handlers for agent execution through the KB Labs platform.
4
+
5
+ ## Surfaces
6
+
7
+ ### CLI
8
+
9
+ ```bash
10
+ # Execute a task
11
+ pnpm kb agent:run --task="Add input validation to the login form"
12
+
13
+ # Plan mode (analyze without executing)
14
+ pnpm kb agent:run --task="Refactor auth module" --mode=plan
15
+
16
+ # Edit mode (targeted file changes)
17
+ pnpm kb agent:run --task="Fix types in auth.ts" --mode=edit --files=src/auth.ts
18
+
19
+ # Debug mode (replay a trace)
20
+ pnpm kb agent:run --mode=debug --trace=./trace.ndjson
21
+
22
+ # Dry run
23
+ pnpm kb agent:run --task="Add tests" --dry-run
24
+ ```
25
+
26
+ ### REST API
27
+
28
+ Handlers registered as KB Labs plugin routes under `/api/v1/agents/*`.
29
+
30
+ ### WebSocket
31
+
32
+ Real-time streaming of agent events (iterations, tool calls, completions) for Studio UI.
33
+
34
+ ## Flags
35
+
36
+ | Flag | Type | Description |
37
+ |------|------|-------------|
38
+ | `--task` | string | Task description in natural language |
39
+ | `--mode` | enum | `execute` (default), `plan`, `edit`, `debug` |
40
+ | `--session-id` | string | Session ID (auto-generated if omitted) |
41
+ | `--complexity` | enum | `simple`, `medium`, `complex` |
42
+ | `--files` | string[] | Target files (edit mode) |
43
+ | `--trace` | string | Trace file path (debug mode) |
44
+ | `--dry-run` | boolean | Preview changes without applying |
45
+
46
+ ## Plugin Manifest
47
+
48
+ Follows KB Labs V3 plugin manifest format. Exported from `src/manifest.ts` — declares commands, REST routes, WebSocket handlers, and permission requirements.
49
+
50
+ ## Dependencies
51
+
52
+ - `@kb-labs/agent-core` — agent engine
53
+ - `@kb-labs/agent-contracts` — shared types
54
+ - `@kb-labs/agent-tools` — tool registry
55
+ - `@kb-labs/agent-tracing` — trace loading for debug mode
56
+ - `@kb-labs/sdk` — platform SDK
@@ -0,0 +1,17 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+
3
+ /**
4
+ * agent:diff - Show diff for specific file change
5
+ *
6
+ * Usage:
7
+ * pnpm kb agent:diff --change-id={id}
8
+ * pnpm kb agent:diff --change-id={id} --json
9
+ */
10
+ type DiffInput = {
11
+ changeId?: string;
12
+ 'change-id'?: string;
13
+ json?: boolean;
14
+ };
15
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, DiffInput, unknown>;
16
+
17
+ export { _default as default };
@@ -0,0 +1,182 @@
1
+ import { defineCommand, useLogger } from '@kb-labs/sdk';
2
+ import { promises } from 'fs';
3
+ import path from 'path';
4
+
5
+ // src/cli/commands/diff.ts
6
+ var diff_default = defineCommand({
7
+ id: "diff",
8
+ description: "Show diff for specific file change",
9
+ handler: {
10
+ async execute(ctx, input) {
11
+ const logger = useLogger();
12
+ const flags = input.flags ?? input;
13
+ const changeId = flags["change-id"] ?? flags.changeId;
14
+ if (!changeId) {
15
+ const err = { success: false, error: "Missing required --change-id flag" };
16
+ ctx.ui.write(JSON.stringify(err, null, 2) + "\n");
17
+ return { exitCode: 1, response: err };
18
+ }
19
+ try {
20
+ const basePath = path.join(process.cwd(), ".kb", "agents", "sessions");
21
+ const sessions = await promises.readdir(basePath);
22
+ let snapshot = null;
23
+ let foundSessionId = null;
24
+ for (const sessionId of sessions) {
25
+ const snapshotPath = path.join(basePath, sessionId, "snapshots", `${changeId}.json`);
26
+ try {
27
+ const content = await promises.readFile(snapshotPath, "utf-8");
28
+ snapshot = JSON.parse(content);
29
+ foundSessionId = sessionId;
30
+ break;
31
+ } catch {
32
+ continue;
33
+ }
34
+ }
35
+ if (!snapshot) {
36
+ const err = { success: false, error: `Change not found: ${changeId}` };
37
+ ctx.ui.write(JSON.stringify(err, null, 2) + "\n");
38
+ return { exitCode: 1, response: err };
39
+ }
40
+ const diff = calculateDiff(snapshot);
41
+ const response = {
42
+ success: true,
43
+ changeId,
44
+ sessionId: foundSessionId,
45
+ data: {
46
+ ...snapshot,
47
+ diff
48
+ }
49
+ };
50
+ if (flags.json) {
51
+ ctx.ui.write(JSON.stringify(response, null, 2) + "\n");
52
+ } else {
53
+ printDiff(ctx, snapshot, diff);
54
+ }
55
+ return { exitCode: 0, response };
56
+ } catch (err) {
57
+ logger.error("agent:diff error:", err instanceof Error ? err : void 0);
58
+ const errResponse = {
59
+ success: false,
60
+ error: err instanceof Error ? err.message : String(err)
61
+ };
62
+ ctx.ui.write(JSON.stringify(errResponse, null, 2) + "\n");
63
+ return { exitCode: 1, response: errResponse };
64
+ }
65
+ }
66
+ }
67
+ });
68
+ function calculateDiff(snapshot) {
69
+ const beforeContent = snapshot.before?.content || "";
70
+ const afterContent = snapshot.after?.content || "";
71
+ const beforeLines = beforeContent.split("\n");
72
+ const afterLines = afterContent.split("\n");
73
+ const diff = {
74
+ additions: 0,
75
+ deletions: 0,
76
+ changes: []
77
+ };
78
+ const maxLines = Math.max(beforeLines.length, afterLines.length);
79
+ for (let i = 0; i < maxLines; i++) {
80
+ const before = beforeLines[i];
81
+ const after = afterLines[i];
82
+ if (before === void 0 && after !== void 0) {
83
+ diff.additions++;
84
+ diff.changes.push({
85
+ type: "add",
86
+ line: i + 1,
87
+ content: after
88
+ });
89
+ } else if (before !== void 0 && after === void 0) {
90
+ diff.deletions++;
91
+ diff.changes.push({
92
+ type: "delete",
93
+ line: i + 1,
94
+ content: before
95
+ });
96
+ } else if (before !== after) {
97
+ diff.deletions++;
98
+ diff.additions++;
99
+ diff.changes.push({
100
+ type: "change",
101
+ line: i + 1,
102
+ before,
103
+ after
104
+ });
105
+ }
106
+ }
107
+ return diff;
108
+ }
109
+ function printDiff(ctx, snapshot, diff) {
110
+ ctx.ui.write("\n");
111
+ ctx.ui.write("\u{1F4DD} File Change Diff\n");
112
+ ctx.ui.write("\n");
113
+ const timestamp = new Date(snapshot.timestamp).toLocaleString();
114
+ const operation = snapshot.operation.toUpperCase();
115
+ ctx.ui.write(`Change ID: ${snapshot.id}
116
+ `);
117
+ ctx.ui.write(`File: ${snapshot.filePath}
118
+ `);
119
+ ctx.ui.write(`Operation: ${operation}
120
+ `);
121
+ ctx.ui.write(`Agent: ${snapshot.agentId}
122
+ `);
123
+ ctx.ui.write(`Timestamp: ${timestamp}
124
+ `);
125
+ ctx.ui.write("\n");
126
+ if (snapshot.metadata) {
127
+ if (snapshot.metadata.startLine !== void 0) {
128
+ ctx.ui.write(
129
+ `Patch: lines ${snapshot.metadata.startLine}-${snapshot.metadata.endLine}
130
+ `
131
+ );
132
+ }
133
+ if (snapshot.metadata.linesAdded !== void 0) {
134
+ ctx.ui.write(
135
+ `Changes: +${snapshot.metadata.linesAdded} -${snapshot.metadata.linesRemoved}
136
+ `
137
+ );
138
+ }
139
+ if (snapshot.metadata.isOverwrite) {
140
+ ctx.ui.write("Overwrote existing file\n");
141
+ }
142
+ ctx.ui.write("\n");
143
+ }
144
+ ctx.ui.write(`Summary: +${diff.additions} -${diff.deletions}
145
+ `);
146
+ ctx.ui.write("\n");
147
+ ctx.ui.write("\u2500".repeat(60) + "\n");
148
+ if (snapshot.operation === "write" && !snapshot.before) {
149
+ ctx.ui.write("New file created:\n");
150
+ ctx.ui.write("\n");
151
+ const lines = snapshot.after.content.split("\n");
152
+ for (let i = 0; i < Math.min(lines.length, 50); i++) {
153
+ ctx.ui.write(`+ ${(i + 1).toString().padStart(4)} | ${lines[i]}
154
+ `);
155
+ }
156
+ if (lines.length > 50) {
157
+ ctx.ui.write(`... (${lines.length - 50} more lines)
158
+ `);
159
+ }
160
+ } else {
161
+ for (const change of diff.changes) {
162
+ if (change.type === "add") {
163
+ ctx.ui.write(`+ ${change.line.toString().padStart(4)} | ${change.content}
164
+ `);
165
+ } else if (change.type === "delete") {
166
+ ctx.ui.write(`- ${change.line.toString().padStart(4)} | ${change.content}
167
+ `);
168
+ } else if (change.type === "change") {
169
+ ctx.ui.write(`- ${change.line.toString().padStart(4)} | ${change.before}
170
+ `);
171
+ ctx.ui.write(`+ ${change.line.toString().padStart(4)} | ${change.after}
172
+ `);
173
+ }
174
+ }
175
+ }
176
+ ctx.ui.write("\u2500".repeat(60) + "\n");
177
+ ctx.ui.write("\n");
178
+ }
179
+
180
+ export { diff_default as default };
181
+ //# sourceMappingURL=diff.js.map
182
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/diff.ts"],"names":["fs"],"mappings":"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","file":"diff.js","sourcesContent":["/**\n * agent:diff - Show diff for specific file change\n *\n * Usage:\n * pnpm kb agent:diff --change-id={id}\n * pnpm kb agent:diff --change-id={id} --json\n */\n\nimport { defineCommand, useLogger } from '@kb-labs/sdk';\nimport type { PluginContextV3 } from '@kb-labs/sdk';\nimport { promises as fs } from 'fs';\nimport path from 'path';\n\ntype DiffInput = {\n changeId?: string;\n 'change-id'?: string;\n json?: boolean;\n};\n\ntype DiffResult = { exitCode: number; response?: any };\n\nexport default defineCommand({\n id: 'diff',\n description: 'Show diff for specific file change',\n\n handler: {\n async execute(ctx: PluginContextV3, input: DiffInput): Promise<DiffResult> {\n const logger = useLogger();\n const flags = (input as any).flags ?? input;\n\n const changeId = flags['change-id'] ?? flags.changeId;\n if (!changeId) {\n const err = { success: false, error: 'Missing required --change-id flag' };\n ctx.ui.write(JSON.stringify(err, null, 2) + '\\n');\n return { exitCode: 1, response: err };\n }\n\n try {\n const basePath = path.join(process.cwd(), '.kb', 'agents', 'sessions');\n\n // Search all sessions for this change ID\n const sessions = await fs.readdir(basePath);\n let snapshot = null;\n let foundSessionId = null;\n\n for (const sessionId of sessions) {\n const snapshotPath = path.join(basePath, sessionId, 'snapshots', `${changeId}.json`);\n\n try {\n const content = await fs.readFile(snapshotPath, 'utf-8');\n snapshot = JSON.parse(content);\n foundSessionId = sessionId;\n break;\n } catch {\n // Try next session\n continue;\n }\n }\n\n if (!snapshot) {\n const err = { success: false, error: `Change not found: ${changeId}` };\n ctx.ui.write(JSON.stringify(err, null, 2) + '\\n');\n return { exitCode: 1, response: err };\n }\n\n // Calculate diff\n const diff = calculateDiff(snapshot);\n\n const response = {\n success: true,\n changeId,\n sessionId: foundSessionId,\n data: {\n ...snapshot,\n diff,\n },\n };\n\n if (flags.json) {\n ctx.ui.write(JSON.stringify(response, null, 2) + '\\n');\n } else {\n printDiff(ctx, snapshot, diff);\n }\n\n return { exitCode: 0, response };\n } catch (err) {\n logger.error('agent:diff error:', err instanceof Error ? err : undefined);\n const errResponse = {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n ctx.ui.write(JSON.stringify(errResponse, null, 2) + '\\n');\n return { exitCode: 1, response: errResponse };\n }\n },\n },\n});\n\n/**\n * Calculate line-by-line diff\n */\nfunction calculateDiff(snapshot: any): any {\n const beforeContent = snapshot.before?.content || '';\n const afterContent = snapshot.after?.content || '';\n\n const beforeLines = beforeContent.split('\\n');\n const afterLines = afterContent.split('\\n');\n\n const diff = {\n additions: 0,\n deletions: 0,\n changes: [] as any[],\n };\n\n // Simple line-by-line comparison\n const maxLines = Math.max(beforeLines.length, afterLines.length);\n\n for (let i = 0; i < maxLines; i++) {\n const before = beforeLines[i];\n const after = afterLines[i];\n\n if (before === undefined && after !== undefined) {\n // Line added\n diff.additions++;\n diff.changes.push({\n type: 'add',\n line: i + 1,\n content: after,\n });\n } else if (before !== undefined && after === undefined) {\n // Line deleted\n diff.deletions++;\n diff.changes.push({\n type: 'delete',\n line: i + 1,\n content: before,\n });\n } else if (before !== after) {\n // Line changed\n diff.deletions++;\n diff.additions++;\n diff.changes.push({\n type: 'change',\n line: i + 1,\n before,\n after,\n });\n }\n }\n\n return diff;\n}\n\n/**\n * Print diff in human-readable format\n */\nfunction printDiff(ctx: PluginContextV3, snapshot: any, diff: any): void {\n ctx.ui.write('\\n');\n ctx.ui.write('📝 File Change Diff\\n');\n ctx.ui.write('\\n');\n\n const timestamp = new Date(snapshot.timestamp).toLocaleString();\n const operation = snapshot.operation.toUpperCase();\n\n ctx.ui.write(`Change ID: ${snapshot.id}\\n`);\n ctx.ui.write(`File: ${snapshot.filePath}\\n`);\n ctx.ui.write(`Operation: ${operation}\\n`);\n ctx.ui.write(`Agent: ${snapshot.agentId}\\n`);\n ctx.ui.write(`Timestamp: ${timestamp}\\n`);\n ctx.ui.write('\\n');\n\n if (snapshot.metadata) {\n if (snapshot.metadata.startLine !== undefined) {\n ctx.ui.write(\n `Patch: lines ${snapshot.metadata.startLine}-${snapshot.metadata.endLine}\\n`\n );\n }\n if (snapshot.metadata.linesAdded !== undefined) {\n ctx.ui.write(\n `Changes: +${snapshot.metadata.linesAdded} -${snapshot.metadata.linesRemoved}\\n`\n );\n }\n if (snapshot.metadata.isOverwrite) {\n ctx.ui.write('Overwrote existing file\\n');\n }\n ctx.ui.write('\\n');\n }\n\n ctx.ui.write(`Summary: +${diff.additions} -${diff.deletions}\\n`);\n ctx.ui.write('\\n');\n\n // Print diff\n ctx.ui.write('─'.repeat(60) + '\\n');\n\n if (snapshot.operation === 'write' && !snapshot.before) {\n // New file - show full content\n ctx.ui.write('New file created:\\n');\n ctx.ui.write('\\n');\n const lines = snapshot.after.content.split('\\n');\n for (let i = 0; i < Math.min(lines.length, 50); i++) {\n ctx.ui.write(`+ ${(i + 1).toString().padStart(4)} | ${lines[i]}\\n`);\n }\n if (lines.length > 50) {\n ctx.ui.write(`... (${lines.length - 50} more lines)\\n`);\n }\n } else {\n // Show diff\n for (const change of diff.changes) {\n if (change.type === 'add') {\n ctx.ui.write(`+ ${change.line.toString().padStart(4)} | ${change.content}\\n`);\n } else if (change.type === 'delete') {\n ctx.ui.write(`- ${change.line.toString().padStart(4)} | ${change.content}\\n`);\n } else if (change.type === 'change') {\n ctx.ui.write(`- ${change.line.toString().padStart(4)} | ${change.before}\\n`);\n ctx.ui.write(`+ ${change.line.toString().padStart(4)} | ${change.after}\\n`);\n }\n }\n }\n\n ctx.ui.write('─'.repeat(60) + '\\n');\n ctx.ui.write('\\n');\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+
3
+ /**
4
+ * agent:history - Show file change history for agent sessions
5
+ */
6
+ type HistoryInput = {
7
+ sessionId?: string;
8
+ 'session-id'?: string;
9
+ file?: string;
10
+ agentId?: string;
11
+ 'agent-id'?: string;
12
+ json?: boolean;
13
+ };
14
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, HistoryInput, unknown>;
15
+
16
+ export { _default as default };
@@ -0,0 +1,216 @@
1
+ import { defineCommand } from '@kb-labs/sdk';
2
+ import { SessionManager } from '@kb-labs/agent-core';
3
+
4
+ // src/cli/commands/history.ts
5
+ var history_default = defineCommand({
6
+ id: "history",
7
+ description: "Show file change history for agent sessions",
8
+ handler: {
9
+ async execute(ctx, input) {
10
+ const flags = input.flags ?? input;
11
+ const manager = new SessionManager(process.cwd());
12
+ try {
13
+ const sessionId = flags["session-id"] ?? flags.sessionId;
14
+ const agentId = flags["agent-id"] ?? flags.agentId;
15
+ if (sessionId) {
16
+ return showSessionHistory(ctx, manager, String(sessionId), Boolean(flags.json));
17
+ }
18
+ if (flags.file) {
19
+ return showFileHistory(ctx, manager, String(flags.file), Boolean(flags.json));
20
+ }
21
+ if (agentId) {
22
+ return showAgentHistory(ctx, manager, String(agentId), Boolean(flags.json));
23
+ }
24
+ return listAllSessions(ctx, manager, Boolean(flags.json));
25
+ } catch (error) {
26
+ const response = {
27
+ success: false,
28
+ error: error instanceof Error ? error.message : String(error)
29
+ };
30
+ ctx.ui.write(JSON.stringify(response, null, 2) + "\n");
31
+ return { exitCode: 1, response };
32
+ }
33
+ }
34
+ }
35
+ });
36
+ async function showSessionHistory(ctx, manager, sessionId, asJson) {
37
+ const info = await manager.getSessionInfo(sessionId);
38
+ if (!info) {
39
+ const err = { success: false, error: `Session not found: ${sessionId}` };
40
+ ctx.ui.write(JSON.stringify(err, null, 2) + "\n");
41
+ return { exitCode: 1, response: err };
42
+ }
43
+ const turns = await manager.getTurns(sessionId);
44
+ const changes = collectChanges(sessionId, turns);
45
+ changes.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
46
+ const response = {
47
+ success: true,
48
+ sessionId,
49
+ runCount: info.runCount,
50
+ changes: changes.length,
51
+ data: changes
52
+ };
53
+ if (asJson) {
54
+ ctx.ui.write(JSON.stringify(response, null, 2) + "\n");
55
+ } else {
56
+ ctx.ui.write(`Session: ${sessionId}
57
+ `);
58
+ ctx.ui.write(`Runs: ${info.runCount} | Changes: ${changes.length}
59
+
60
+ `);
61
+ for (const c of changes) {
62
+ const ts = new Date(c.timestamp).toLocaleString();
63
+ ctx.ui.write(`[${ts}] ${c.operation.toUpperCase()} ${c.filePath}
64
+ `);
65
+ ctx.ui.write(` Agent: ${c.agentId} | Turn: #${c.turnSequence}
66
+ `);
67
+ ctx.ui.write(` Change ID: ${c.changeId}
68
+
69
+ `);
70
+ }
71
+ }
72
+ return { exitCode: 0, response };
73
+ }
74
+ async function showFileHistory(ctx, manager, filePath, asJson) {
75
+ const sessions = await manager.listSessions({ limit: 1e3, offset: 0 });
76
+ const allChanges = [];
77
+ for (const s of sessions.sessions) {
78
+ const turns = await manager.getTurns(s.id);
79
+ const changes = collectChanges(s.id, turns).filter((c) => c.filePath === filePath);
80
+ allChanges.push(...changes);
81
+ }
82
+ allChanges.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
83
+ const response = {
84
+ success: true,
85
+ filePath,
86
+ changes: allChanges.length,
87
+ data: allChanges
88
+ };
89
+ if (asJson) {
90
+ ctx.ui.write(JSON.stringify(response, null, 2) + "\n");
91
+ } else {
92
+ ctx.ui.write(`File: ${filePath}
93
+ `);
94
+ ctx.ui.write(`Changes: ${allChanges.length}
95
+
96
+ `);
97
+ for (const c of allChanges) {
98
+ const ts = new Date(c.timestamp).toLocaleString();
99
+ ctx.ui.write(`[${ts}] ${c.operation.toUpperCase()} (${c.sessionId})
100
+ `);
101
+ ctx.ui.write(` Agent: ${c.agentId} | Change ID: ${c.changeId}
102
+
103
+ `);
104
+ }
105
+ }
106
+ return { exitCode: 0, response };
107
+ }
108
+ async function showAgentHistory(ctx, manager, agentId, asJson) {
109
+ const sessions = await manager.listSessions({ limit: 1e3, offset: 0 });
110
+ const allChanges = [];
111
+ for (const s of sessions.sessions) {
112
+ const turns = await manager.getTurns(s.id);
113
+ const changes = collectChanges(s.id, turns).filter((c) => c.agentId === agentId);
114
+ allChanges.push(...changes);
115
+ }
116
+ allChanges.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
117
+ const response = {
118
+ success: true,
119
+ agentId,
120
+ changes: allChanges.length,
121
+ data: allChanges
122
+ };
123
+ if (asJson) {
124
+ ctx.ui.write(JSON.stringify(response, null, 2) + "\n");
125
+ } else {
126
+ ctx.ui.write(`Agent: ${agentId}
127
+ `);
128
+ ctx.ui.write(`Changes: ${allChanges.length}
129
+
130
+ `);
131
+ for (const c of allChanges) {
132
+ const ts = new Date(c.timestamp).toLocaleString();
133
+ ctx.ui.write(`[${ts}] ${c.operation.toUpperCase()} ${c.filePath} (${c.sessionId})
134
+ `);
135
+ }
136
+ ctx.ui.write("\n");
137
+ }
138
+ return { exitCode: 0, response };
139
+ }
140
+ async function listAllSessions(ctx, manager, asJson) {
141
+ const sessions = await manager.listSessions({ limit: 1e3, offset: 0 });
142
+ const uniqueSessions = dedupeSessionsById(sessions.sessions);
143
+ const data = await Promise.all(
144
+ uniqueSessions.map(async (s) => {
145
+ const turns = await manager.getTurns(s.id);
146
+ return {
147
+ sessionId: s.id,
148
+ status: s.status,
149
+ runCount: s.runCount,
150
+ lastActivityAt: s.lastActivityAt,
151
+ changes: collectChanges(s.id, turns).length
152
+ };
153
+ })
154
+ );
155
+ const response = {
156
+ success: true,
157
+ sessions: data.length,
158
+ data
159
+ };
160
+ if (asJson) {
161
+ ctx.ui.write(JSON.stringify(response, null, 2) + "\n");
162
+ } else {
163
+ ctx.ui.write(`Sessions: ${data.length}
164
+
165
+ `);
166
+ for (const s of data) {
167
+ ctx.ui.write(`${s.sessionId}
168
+ `);
169
+ ctx.ui.write(` Runs: ${s.runCount} | Changes: ${s.changes} | Status: ${s.status}
170
+ `);
171
+ ctx.ui.write(` Last activity: ${new Date(s.lastActivityAt).toLocaleString()}
172
+
173
+ `);
174
+ }
175
+ }
176
+ return { exitCode: 0, response };
177
+ }
178
+ function dedupeSessionsById(sessions) {
179
+ const byId = /* @__PURE__ */ new Map();
180
+ for (const session of sessions) {
181
+ const existing = byId.get(session.id);
182
+ if (!existing) {
183
+ byId.set(session.id, session);
184
+ continue;
185
+ }
186
+ const existingTs = Date.parse(existing.lastActivityAt);
187
+ const incomingTs = Date.parse(session.lastActivityAt);
188
+ if (incomingTs > existingTs || incomingTs === existingTs && session.runCount > existing.runCount) {
189
+ byId.set(session.id, session);
190
+ }
191
+ }
192
+ return Array.from(byId.values()).sort((a, b) => Date.parse(b.lastActivityAt) - Date.parse(a.lastActivityAt));
193
+ }
194
+ function collectChanges(sessionId, turns) {
195
+ const rows = [];
196
+ for (const turn of turns) {
197
+ if (turn.type !== "assistant") {
198
+ continue;
199
+ }
200
+ const changes = turn.metadata.fileChanges ?? [];
201
+ for (const change of changes) {
202
+ rows.push({
203
+ ...change,
204
+ sessionId,
205
+ turnId: turn.id,
206
+ turnSequence: turn.sequence,
207
+ agentId: turn.metadata.agentId
208
+ });
209
+ }
210
+ }
211
+ return rows;
212
+ }
213
+
214
+ export { history_default as default };
215
+ //# sourceMappingURL=history.js.map
216
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/cli/commands/history.ts"],"names":[],"mappings":"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","file":"history.js","sourcesContent":["/**\n * agent:history - Show file change history for agent sessions\n */\n\nimport { defineCommand, type PluginContextV3 } from '@kb-labs/sdk';\nimport { SessionManager } from '@kb-labs/agent-core';\nimport type { FileChangeSummary, Turn } from '@kb-labs/agent-contracts';\n\ntype HistoryInput = {\n sessionId?: string;\n 'session-id'?: string;\n file?: string;\n agentId?: string;\n 'agent-id'?: string;\n json?: boolean;\n};\n\ntype HistoryResult = { exitCode: number; response?: unknown };\n\ntype ChangeRow = FileChangeSummary & {\n sessionId: string;\n turnId: string;\n turnSequence: number;\n agentId: string;\n};\n\nexport default defineCommand({\n id: 'history',\n description: 'Show file change history for agent sessions',\n\n handler: {\n async execute(ctx: PluginContextV3, input: HistoryInput): Promise<HistoryResult> {\n const flags = (input as any).flags ?? input;\n const manager = new SessionManager(process.cwd());\n\n try {\n const sessionId = flags['session-id'] ?? flags.sessionId;\n const agentId = flags['agent-id'] ?? flags.agentId;\n if (sessionId) {\n return showSessionHistory(ctx, manager, String(sessionId), Boolean(flags.json));\n }\n if (flags.file) {\n return showFileHistory(ctx, manager, String(flags.file), Boolean(flags.json));\n }\n if (agentId) {\n return showAgentHistory(ctx, manager, String(agentId), Boolean(flags.json));\n }\n return listAllSessions(ctx, manager, Boolean(flags.json));\n } catch (error) {\n const response = {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n ctx.ui.write(JSON.stringify(response, null, 2) + '\\n');\n return { exitCode: 1, response };\n }\n },\n },\n});\n\nasync function showSessionHistory(\n ctx: PluginContextV3,\n manager: SessionManager,\n sessionId: string,\n asJson: boolean\n): Promise<HistoryResult> {\n const info = await manager.getSessionInfo(sessionId);\n if (!info) {\n const err = { success: false, error: `Session not found: ${sessionId}` };\n ctx.ui.write(JSON.stringify(err, null, 2) + '\\n');\n return { exitCode: 1, response: err };\n }\n\n const turns = await manager.getTurns(sessionId);\n const changes = collectChanges(sessionId, turns);\n changes.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n\n const response = {\n success: true,\n sessionId,\n runCount: info.runCount,\n changes: changes.length,\n data: changes,\n };\n\n if (asJson) {\n ctx.ui.write(JSON.stringify(response, null, 2) + '\\n');\n } else {\n ctx.ui.write(`Session: ${sessionId}\\n`);\n ctx.ui.write(`Runs: ${info.runCount} | Changes: ${changes.length}\\n\\n`);\n for (const c of changes) {\n const ts = new Date(c.timestamp).toLocaleString();\n ctx.ui.write(`[${ts}] ${c.operation.toUpperCase()} ${c.filePath}\\n`);\n ctx.ui.write(` Agent: ${c.agentId} | Turn: #${c.turnSequence}\\n`);\n ctx.ui.write(` Change ID: ${c.changeId}\\n\\n`);\n }\n }\n\n return { exitCode: 0, response };\n}\n\nasync function showFileHistory(\n ctx: PluginContextV3,\n manager: SessionManager,\n filePath: string,\n asJson: boolean\n): Promise<HistoryResult> {\n const sessions = await manager.listSessions({ limit: 1000, offset: 0 });\n const allChanges: ChangeRow[] = [];\n\n for (const s of sessions.sessions) {\n const turns = await manager.getTurns(s.id);\n const changes = collectChanges(s.id, turns).filter((c) => c.filePath === filePath);\n allChanges.push(...changes);\n }\n\n allChanges.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n const response = {\n success: true,\n filePath,\n changes: allChanges.length,\n data: allChanges,\n };\n\n if (asJson) {\n ctx.ui.write(JSON.stringify(response, null, 2) + '\\n');\n } else {\n ctx.ui.write(`File: ${filePath}\\n`);\n ctx.ui.write(`Changes: ${allChanges.length}\\n\\n`);\n for (const c of allChanges) {\n const ts = new Date(c.timestamp).toLocaleString();\n ctx.ui.write(`[${ts}] ${c.operation.toUpperCase()} (${c.sessionId})\\n`);\n ctx.ui.write(` Agent: ${c.agentId} | Change ID: ${c.changeId}\\n\\n`);\n }\n }\n\n return { exitCode: 0, response };\n}\n\nasync function showAgentHistory(\n ctx: PluginContextV3,\n manager: SessionManager,\n agentId: string,\n asJson: boolean\n): Promise<HistoryResult> {\n const sessions = await manager.listSessions({ limit: 1000, offset: 0 });\n const allChanges: ChangeRow[] = [];\n\n for (const s of sessions.sessions) {\n const turns = await manager.getTurns(s.id);\n const changes = collectChanges(s.id, turns).filter((c) => c.agentId === agentId);\n allChanges.push(...changes);\n }\n\n allChanges.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n const response = {\n success: true,\n agentId,\n changes: allChanges.length,\n data: allChanges,\n };\n\n if (asJson) {\n ctx.ui.write(JSON.stringify(response, null, 2) + '\\n');\n } else {\n ctx.ui.write(`Agent: ${agentId}\\n`);\n ctx.ui.write(`Changes: ${allChanges.length}\\n\\n`);\n for (const c of allChanges) {\n const ts = new Date(c.timestamp).toLocaleString();\n ctx.ui.write(`[${ts}] ${c.operation.toUpperCase()} ${c.filePath} (${c.sessionId})\\n`);\n }\n ctx.ui.write('\\n');\n }\n\n return { exitCode: 0, response };\n}\n\nasync function listAllSessions(\n ctx: PluginContextV3,\n manager: SessionManager,\n asJson: boolean\n): Promise<HistoryResult> {\n const sessions = await manager.listSessions({ limit: 1000, offset: 0 });\n const uniqueSessions = dedupeSessionsById(sessions.sessions);\n const data = await Promise.all(\n uniqueSessions.map(async (s) => {\n const turns = await manager.getTurns(s.id);\n return {\n sessionId: s.id,\n status: s.status,\n runCount: s.runCount,\n lastActivityAt: s.lastActivityAt,\n changes: collectChanges(s.id, turns).length,\n };\n }),\n );\n\n const response = {\n success: true,\n sessions: data.length,\n data,\n };\n\n if (asJson) {\n ctx.ui.write(JSON.stringify(response, null, 2) + '\\n');\n } else {\n ctx.ui.write(`Sessions: ${data.length}\\n\\n`);\n for (const s of data) {\n ctx.ui.write(`${s.sessionId}\\n`);\n ctx.ui.write(` Runs: ${s.runCount} | Changes: ${s.changes} | Status: ${s.status}\\n`);\n ctx.ui.write(` Last activity: ${new Date(s.lastActivityAt).toLocaleString()}\\n\\n`);\n }\n }\n\n return { exitCode: 0, response };\n}\n\nfunction dedupeSessionsById<T extends { id: string; status?: string; runCount: number; lastActivityAt: string }>(sessions: T[]): T[] {\n const byId = new Map<string, T>();\n for (const session of sessions) {\n const existing = byId.get(session.id);\n if (!existing) {\n byId.set(session.id, session);\n continue;\n }\n\n const existingTs = Date.parse(existing.lastActivityAt);\n const incomingTs = Date.parse(session.lastActivityAt);\n if (incomingTs > existingTs || (incomingTs === existingTs && session.runCount > existing.runCount)) {\n byId.set(session.id, session);\n }\n }\n return Array.from(byId.values()).sort((a, b) => Date.parse(b.lastActivityAt) - Date.parse(a.lastActivityAt));\n}\n\nfunction collectChanges(sessionId: string, turns: Turn[]): ChangeRow[] {\n const rows: ChangeRow[] = [];\n for (const turn of turns) {\n if (turn.type !== 'assistant') {\n continue;\n }\n const changes = turn.metadata.fileChanges ?? [];\n for (const change of changes) {\n rows.push({\n ...change,\n sessionId,\n turnId: turn.id,\n turnSequence: turn.sequence,\n agentId: turn.metadata.agentId,\n });\n }\n }\n return rows;\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+
3
+ /**
4
+ * agent:quality:report - Agent execution quality control report
5
+ *
6
+ * Usage:
7
+ * pnpm kb agent quality report
8
+ * pnpm kb agent quality report --days=3
9
+ * pnpm kb agent quality report --session-id=session-123
10
+ * pnpm kb agent quality report --json
11
+ */
12
+ type QualityReportInput = {
13
+ days?: number;
14
+ limit?: number;
15
+ sessionId?: string;
16
+ 'session-id'?: string;
17
+ json?: boolean;
18
+ };
19
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, QualityReportInput, unknown>;
20
+
21
+ export { _default as default };