@stigmer/cli 3.10.0 → 3.11.1-dev.20260812192248

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 (36) hide show
  1. package/commands/connect.d.ts.map +1 -1
  2. package/commands/connect.js +9 -1
  3. package/commands/connect.js.map +1 -1
  4. package/commands/usage.js +7 -4
  5. package/commands/usage.js.map +1 -1
  6. package/package.json +5 -5
  7. package/resources/connect/connect.d.ts +9 -0
  8. package/resources/connect/connect.d.ts.map +1 -1
  9. package/resources/connect/connect.js +30 -2
  10. package/resources/connect/connect.js.map +1 -1
  11. package/resources/list.d.ts +7 -1
  12. package/resources/list.d.ts.map +1 -1
  13. package/resources/list.js +35 -15
  14. package/resources/list.js.map +1 -1
  15. package/resources/run/attachments.d.ts.map +1 -1
  16. package/resources/run/attachments.js +33 -5
  17. package/resources/run/attachments.js.map +1 -1
  18. package/resources/usage.d.ts +1 -1
  19. package/resources/usage.d.ts.map +1 -1
  20. package/resources/usage.js +2 -2
  21. package/resources/usage.js.map +1 -1
  22. package/resources/validate.d.ts +1 -0
  23. package/resources/validate.d.ts.map +1 -1
  24. package/resources/validate.js +5 -1
  25. package/resources/validate.js.map +1 -1
  26. package/src/commands/connect.ts +13 -1
  27. package/src/commands/usage.ts +7 -4
  28. package/src/registry/registry.test.ts +7 -0
  29. package/src/resources/connect/connect.integration.test.ts +45 -1
  30. package/src/resources/connect/connect.ts +48 -2
  31. package/src/resources/list.ts +55 -17
  32. package/src/resources/read-verbs.integration.test.ts +35 -2
  33. package/src/resources/run/attachments.test.ts +22 -0
  34. package/src/resources/run/attachments.ts +44 -5
  35. package/src/resources/usage.ts +2 -1
  36. package/src/resources/validate.ts +5 -1
@@ -55,6 +55,7 @@ export async function processAttachments(
55
55
  const workspaceFileRefs: string[] = [];
56
56
  if (paths.length === 0) return { attachments, workspaceFileRefs };
57
57
 
58
+ const takenDirNames = new Set<string>();
58
59
  for (const path of paths) {
59
60
  const rel = matchWorkspaceRoot(path, workspaceRoots);
60
61
  if (rel !== null) {
@@ -62,7 +63,7 @@ export async function processAttachments(
62
63
  workspaceFileRefs.push(rel);
63
64
  continue;
64
65
  }
65
- attachments.push(await processFile(uploader, path, progress));
66
+ attachments.push(await processFile(uploader, path, takenDirNames, progress));
66
67
  }
67
68
 
68
69
  return { attachments, workspaceFileRefs };
@@ -90,7 +91,12 @@ function matchWorkspaceRoot(path: string, roots: readonly string[]): string | nu
90
91
 
91
92
  // Stat the path, then upload a file or zip+upload a directory. Mirrors Go's
92
93
  // processFile.
93
- async function processFile(uploader: AttachmentUploader, path: string, progress?: ProgressSink): Promise<Attachment> {
94
+ async function processFile(
95
+ uploader: AttachmentUploader,
96
+ path: string,
97
+ takenDirNames: Set<string>,
98
+ progress?: ProgressSink,
99
+ ): Promise<Attachment> {
94
100
  let stat: ReturnType<typeof statSync>;
95
101
  try {
96
102
  stat = statSync(path);
@@ -100,7 +106,7 @@ async function processFile(uploader: AttachmentUploader, path: string, progress?
100
106
  throw new UsageError(`failed to stat attachment "${path}": ${e.message}`);
101
107
  }
102
108
 
103
- if (stat.isDirectory()) return processDirectory(uploader, path, progress);
109
+ if (stat.isDirectory()) return processDirectory(uploader, path, takenDirNames, progress);
104
110
 
105
111
  const absPath = resolve(path);
106
112
  const filename = basenameOf(path);
@@ -113,9 +119,29 @@ async function processFile(uploader: AttachmentUploader, path: string, progress?
113
119
 
114
120
  // Zip a directory (extract=true so the runner unpacks it at mount_path) and
115
121
  // upload it as one archive. Mirrors Go's processDirectory.
116
- async function processDirectory(uploader: AttachmentUploader, path: string, progress?: ProgressSink): Promise<Attachment> {
122
+ async function processDirectory(
123
+ uploader: AttachmentUploader,
124
+ path: string,
125
+ takenDirNames: Set<string>,
126
+ progress?: ProgressSink,
127
+ ): Promise<Attachment> {
117
128
  const absPath = resolve(path);
118
- const dirname = basenameOf(absPath);
129
+ // Two same-named directories (`--attach a/data --attach b/data`) would
130
+ // derive the SAME explicit mount path, which the runner rejects as a user
131
+ // contradiction (attachment-injector.ts resolveMountPaths). The CLI derives
132
+ // these names mechanically from basenames, so it owns the rename — the same
133
+ // principle as the React composer's client-side uniquify (sdk/react
134
+ // attachment-utils.ts). Duplicate FILE attachments need no CLI handling:
135
+ // they carry no mountPath, so the runner renames them itself.
136
+ const requestedName = basenameOf(absPath);
137
+ const dirname = uniquifyDirName(requestedName, takenDirNames);
138
+ takenDirNames.add(dirname);
139
+ if (dirname !== requestedName) {
140
+ progress?.(
141
+ `Attaching second '${requestedName}/' as '${dirname}/' (a directory ` +
142
+ `named '${requestedName}' is already attached)`,
143
+ );
144
+ }
119
145
 
120
146
  const { bytes, fileCount, originalSize } = zipDirectory(absPath, progress);
121
147
  const zipSize = bytes.byteLength;
@@ -248,6 +274,19 @@ function formatFileSize(bytes: number): string {
248
274
  return `${bytes} B`;
249
275
  }
250
276
 
277
+ // Returns `name` unchanged when free, otherwise the first free `name-2`,
278
+ // `name-3`, … variant. Deliberately extension-blind — directory names have no
279
+ // extension semantics ("reports.2024" becomes "reports.2024-2", not
280
+ // "reports-2.2024"), unlike the filename uniquify in the runner and React SDK
281
+ // (shared/attachment-naming.ts / attachment-utils.ts) this mirrors.
282
+ function uniquifyDirName(name: string, taken: ReadonlySet<string>): string {
283
+ if (!taken.has(name)) return name;
284
+ for (let n = 2; ; n++) {
285
+ const candidate = `${name}-${n}`;
286
+ if (!taken.has(candidate)) return candidate;
287
+ }
288
+ }
289
+
251
290
  // path.basename, but resilient to trailing slashes (matches Go filepath.Base
252
291
  // semantics closely enough for display/name derivation).
253
292
  function basenameOf(p: string): string {
@@ -41,10 +41,11 @@ export async function getSessionUsageReport(client: Stigmer, sessionId: string):
41
41
  export async function getAgentUsageReport(
42
42
  client: Stigmer,
43
43
  agentId: string,
44
+ orgId: string,
44
45
  range: DateRange,
45
46
  ): Promise<GetAgentUsageReportOutput> {
46
47
  return client.agentExecution.getAgentUsageReport(
47
- create(GetAgentUsageReportInputSchema, { agentId, fromDate: range.from, toDate: range.to }),
48
+ create(GetAgentUsageReportInputSchema, { agentId, orgId, fromDate: range.from, toDate: range.to }),
48
49
  );
49
50
  }
50
51
 
@@ -13,7 +13,11 @@ import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/a
13
13
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
14
14
  import { ProjectSchema } from "@stigmer/protos/ai/stigmer/tenancy/project/v1/api_pb";
15
15
 
16
- const VALIDATE_SCHEMAS: ReadonlyMap<ApiResourceKind, DescMessage> = new Map<ApiResourceKind, DescMessage>([
16
+ // Exported for the verb/dispatch conformance suite (registry/registry.test.ts),
17
+ // which holds this map and the matrix's Verb.Validate promises to strict
18
+ // bidirectional equality — the stigmer/stigmer#353 drift class. Command code
19
+ // resolves schemas through `schemaForValidate`, never this map directly.
20
+ export const VALIDATE_SCHEMAS: ReadonlyMap<ApiResourceKind, DescMessage> = new Map<ApiResourceKind, DescMessage>([
17
21
  [ApiResourceKind.agent, AgentSchema],
18
22
  [ApiResourceKind.workflow, WorkflowSchema],
19
23
  [ApiResourceKind.mcp_server, McpServerSchema],