@blogic-cz/agent-tools 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session-tool/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAY,OAAO,EAAQ,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,MAAM,EAAiB,MAAM,QAAQ,CAAC;AAQ/C,OAAO,EAAE,aAAa,EAAsB,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAc,cAAc,EAAiC,MAAM,WAAW,CAAC;AAiTtF,eAAO,MAAM,GAAG,8JAEd,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session-tool/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAY,OAAO,EAAQ,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,MAAM,EAAiB,MAAM,QAAQ,CAAC;AAQ/C,OAAO,EAAE,aAAa,EAAsB,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAc,cAAc,EAAuB,MAAM,WAAW,CAAC;AAsT5E,eAAO,MAAM,GAAG,8JAEd,CAAC"}
@@ -3,7 +3,6 @@ import type { MessageSummary, SessionSource, SessionSummary } from "./types";
3
3
  import { ResolvedPaths } from "./config";
4
4
  import { type SessionError } from "./errors";
5
5
  export declare const formatDate: (timestamp: number) => string;
6
- export declare const truncate: (value: string, maxLen: number) => string;
7
6
  declare const SessionService_base: Context.ServiceClass<SessionService, "@agent-tools/SessionService", {
8
7
  readonly getSessionsForProject: (projectDir: string | null, sources?: ReadonlySet<SessionSource>) => Effect.Effect<Set<string>, SessionError>;
9
8
  readonly getPiSessionSummaries: (filterSessions: Set<string> | null) => Effect.Effect<SessionSummary[], SessionError>;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/session-tool/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAIhD,OAAO,KAAK,EAAE,cAAc,EAAe,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAO1F,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAiD,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAU5F,eAAO,MAAM,UAAU,GAAI,WAAW,MAAM,KAAG,MAW9C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,MAMxD,CAAC;;oCA6HkC,CAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,OAAO,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,KACjC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;oCACb,CAC9B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,KAC/B,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC;kCACpB,CAC5B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAClC,OAAO,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,KACjC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC;8BACxB,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,cAAc,EAAE;;AAd9F,qBAAa,cAAe,SAAQ,mBAgBF;IAChC,MAAM,CAAC,QAAQ,CAAC,KAAK,oDAsPnB;CACH;AAED,eAAO,MAAM,mBAAmB,mDAAuB,CAAC"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/session-tool/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAIhD,OAAO,KAAK,EAAE,cAAc,EAAe,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAO1F,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAiD,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAU5F,eAAO,MAAM,UAAU,GAAI,WAAW,MAAM,KAAG,MAW9C,CAAC;;oCA6HkC,CAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,OAAO,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,KACjC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;oCACb,CAC9B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,KAC/B,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC;kCACpB,CAC5B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAClC,OAAO,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,KACjC,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC;8BACxB,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,cAAc,EAAE;;AAd9F,qBAAa,cAAe,SAAQ,mBAgBF;IAChC,MAAM,CAAC,QAAQ,CAAC,KAAK,oDAsPnB;CACH;AAED,eAAO,MAAM,mBAAmB,mDAAuB,CAAC"}
@@ -1,4 +1,16 @@
1
1
  import type { MessageSummary, SessionSummary } from "./types";
2
+ /**
3
+ * Shapes a message body for output. A body silently cut to 500 chars was
4
+ * indistinguishable from a short one, so callers read "no match in this snippet" as
5
+ * "not in this session". When the body is cut, say so and report its real length.
6
+ *
7
+ * maxBodyChars <= 0 returns the full body.
8
+ */
9
+ export declare const shapeBody: (body: string, maxBodyChars: number) => {
10
+ body: string;
11
+ bodyLength?: number;
12
+ truncated?: true;
13
+ };
2
14
  export declare const sessionSummariesFromMessages: (summaries: MessageSummary[]) => SessionSummary[];
3
15
  export declare const projectSessionFilter: (sessionsBySource: ReadonlyMap<SessionSummary["source"], Set<string>>, source: SessionSummary["source"], allProjects: boolean) => Set<string> | null;
4
16
  export declare const sortSessionSummaries: (summaries: SessionSummary[]) => SessionSummary[];
@@ -1 +1 @@
1
- {"version":3,"file":"summaries.d.ts","sourceRoot":"","sources":["../../src/session-tool/summaries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9D,eAAO,MAAM,4BAA4B,GAAI,WAAW,cAAc,EAAE,KAAG,cAAc,EAwBxF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,kBAAkB,WAAW,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACpE,QAAQ,cAAc,CAAC,QAAQ,CAAC,EAChC,aAAa,OAAO,KACnB,GAAG,CAAC,MAAM,CAAC,GAAG,IAA0E,CAAC;AAE5F,eAAO,MAAM,oBAAoB,GAAI,WAAW,cAAc,EAAE,KAAG,cAAc,EAO9E,CAAC"}
1
+ {"version":3,"file":"summaries.d.ts","sourceRoot":"","sources":["../../src/session-tool/summaries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GACpB,MAAM,MAAM,EACZ,cAAc,MAAM,KACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,IAAI,CAAA;CAOvD,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,WAAW,cAAc,EAAE,KAAG,cAAc,EAwBxF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,kBAAkB,WAAW,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACpE,QAAQ,cAAc,CAAC,QAAQ,CAAC,EAChC,aAAa,OAAO,KACnB,GAAG,CAAC,MAAM,CAAC,GAAG,IAA0E,CAAC;AAE5F,eAAO,MAAM,oBAAoB,GAAI,WAAW,cAAc,EAAE,KAAG,cAAc,EAO9E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blogic-cz/agent-tools",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "CLI tools for AI coding agent workflows — GitHub, database, Kubernetes, Azure platform, Azure DevOps, logs, sessions, and audit",
5
5
  "keywords": [
6
6
  "agent",
@@ -19,9 +19,10 @@ import { makeSchemaCommand, formatOption, formatOutput, logText, VERSION } from
19
19
  import { AuditServiceLayer, withAudit } from "#shared/audit";
20
20
  import { ResolvedPaths, ResolvedPathsLayer } from "./config";
21
21
  import { SessionStorageNotFoundError } from "./errors";
22
- import { formatDate, SessionService, SessionServiceLayer, truncate } from "./service";
22
+ import { formatDate, SessionService, SessionServiceLayer } from "./service";
23
23
  import {
24
24
  projectSessionFilter,
25
+ shapeBody,
25
26
  sessionSummariesFromMessages,
26
27
  sortSessionSummaries,
27
28
  } from "./summaries";
@@ -50,14 +51,14 @@ const buildScopeLabel = (searchAll: boolean, currentDir: string) => {
50
51
  return `current project (${projectName})`;
51
52
  };
52
53
 
53
- const mapSummary = (summary: MessageSummary) => {
54
+ const mapSummary = (maxBodyChars: number) => (summary: MessageSummary) => {
54
55
  return Effect.gen(function* () {
55
56
  const paths = yield* ResolvedPaths;
56
57
  return {
57
58
  sessionID: summary.sessionID,
58
59
  messageID: summary.id,
59
60
  title: summary.title,
60
- body: truncate(summary.body, 500),
61
+ ...shapeBody(summary.body, maxBodyChars),
61
62
  created: formatDate(summary.created),
62
63
  ...(summary.source === "opencode"
63
64
  ? {
@@ -184,13 +185,17 @@ const searchCommand = Command.make(
184
185
  Flag.withDefault(false),
185
186
  ),
186
187
  format: formatOption,
188
+ bodyChars: Flag.integer("body-chars").pipe(
189
+ Flag.withDescription("Max message body characters per result (0 = full bodies)"),
190
+ Flag.withDefault(500),
191
+ ),
187
192
  limit: Flag.integer("limit").pipe(
188
193
  Flag.withDescription("Limit result count"),
189
194
  Flag.withDefault(10),
190
195
  ),
191
196
  source: sourceOption,
192
197
  },
193
- ({ all, format, limit, query, source }) =>
198
+ ({ all, bodyChars, format, limit, query, source }) =>
194
199
  Effect.gen(function* () {
195
200
  const sessionService = yield* SessionService;
196
201
  const startTime = Date.now();
@@ -218,7 +223,7 @@ const searchCommand = Command.make(
218
223
  const allSummaries = yield* sessionService.getMessageSummaries(sessionFilter);
219
224
  const summaries = filterBySource(allSummaries, source);
220
225
  const matched = sessionService.searchSummaries(summaries, query);
221
- const mappedResults = yield* Effect.all(matched.slice(0, limit).map(mapSummary));
226
+ const mappedResults = yield* Effect.all(matched.slice(0, limit).map(mapSummary(bodyChars)));
222
227
 
223
228
  return {
224
229
  success: true,
@@ -287,7 +292,7 @@ const readCommand = Command.make(
287
292
  onSuccess: (summaries) => {
288
293
  const filtered = filterBySource(summaries, source);
289
294
  const sessionResults = filtered.filter((summary) => summary.sessionID === session);
290
- return Effect.all(sessionResults.map(mapSummary)).pipe(
295
+ return Effect.all(sessionResults.map(mapSummary(0))).pipe(
291
296
  Effect.map(
292
297
  (mapped) =>
293
298
  ({
@@ -33,14 +33,6 @@ export const formatDate = (timestamp: number): string => {
33
33
  });
34
34
  };
35
35
 
36
- export const truncate = (value: string, maxLen: number): string => {
37
- if (value.length <= maxLen) {
38
- return value;
39
- }
40
-
41
- return `${value.slice(0, maxLen - 3)}...`;
42
- };
43
-
44
36
  type FileEntry = { filePath: string; content: string };
45
37
 
46
38
  type SourceFilter = ReadonlySet<SessionSource>;
@@ -1,5 +1,24 @@
1
1
  import type { MessageSummary, SessionSummary } from "./types";
2
2
 
3
+ /**
4
+ * Shapes a message body for output. A body silently cut to 500 chars was
5
+ * indistinguishable from a short one, so callers read "no match in this snippet" as
6
+ * "not in this session". When the body is cut, say so and report its real length.
7
+ *
8
+ * maxBodyChars <= 0 returns the full body.
9
+ */
10
+ export const shapeBody = (
11
+ body: string,
12
+ maxBodyChars: number,
13
+ ): { body: string; bodyLength?: number; truncated?: true } => {
14
+ if (maxBodyChars <= 0 || body.length <= maxBodyChars) {
15
+ return { body };
16
+ }
17
+
18
+ const kept = body.slice(0, Math.max(0, maxBodyChars - 3));
19
+ return { body: `${kept}...`, bodyLength: body.length, truncated: true };
20
+ };
21
+
3
22
  export const sessionSummariesFromMessages = (summaries: MessageSummary[]): SessionSummary[] => {
4
23
  const bySession = new Map<string, SessionSummary>();
5
24