@ghl-ai/aw 0.1.59 → 0.1.60

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 (2) hide show
  1. package/commands/push.mjs +41 -30
  2. package/package.json +1 -1
package/commands/push.mjs CHANGED
@@ -864,16 +864,14 @@ function collectBatchFiles(folderAbsPath, registrySubDir) {
864
864
  let walkDir = folderAbsPath;
865
865
  let walkBaseName = relPath;
866
866
 
867
- for (let i = 0; i < segments.length; i++) {
868
- if (PUSHABLE_TYPES.includes(segments[i])) {
869
- const namespaceParts = segments.slice(0, i);
870
- walkBaseName = namespaceParts.join('/');
871
- walkDir = join(registrySubDir, ...namespaceParts);
872
- typeFilter = segments[i];
873
- if (i + 1 < segments.length) {
874
- subPathFilter = segments.slice(i + 1).join('/');
875
- }
876
- break;
867
+ const typeIdx = findPushableTypeIndex(segments);
868
+ if (typeIdx !== -1) {
869
+ const namespaceParts = segments.slice(0, typeIdx);
870
+ walkBaseName = namespaceParts.join('/');
871
+ walkDir = join(registrySubDir, ...namespaceParts);
872
+ typeFilter = segments[typeIdx];
873
+ if (typeIdx + 1 < segments.length) {
874
+ subPathFilter = segments.slice(typeIdx + 1).join('/');
877
875
  }
878
876
  }
879
877
 
@@ -881,7 +879,10 @@ function collectBatchFiles(folderAbsPath, registrySubDir) {
881
879
  return entries
882
880
  .filter(entry => {
883
881
  if (typeFilter && entry.type !== typeFilter) return false;
884
- if (subPathFilter && !entry.slug.startsWith(subPathFilter)) return false;
882
+ if (subPathFilter) {
883
+ const prefix = `${subPathFilter}/`;
884
+ if (entry.slug !== subPathFilter && !entry.slug.startsWith(prefix)) return false;
885
+ }
885
886
  return true;
886
887
  })
887
888
  .map(entry => {
@@ -920,29 +921,37 @@ function findSkillSlugParts(namespaceParts, skillParts, registrySubDir) {
920
921
  return [skillParts[0]];
921
922
  }
922
923
 
924
+ function findPushableTypeIndex(parts) {
925
+ for (let i = 0; i < parts.length; i++) {
926
+ if ((parts[i] === 'agents' || parts[i] === 'commands') && parts[i + 1] === 'evals') {
927
+ return i + 1;
928
+ }
929
+ if (PUSHABLE_TYPES.includes(parts[i])) return i;
930
+ }
931
+ return -1;
932
+ }
933
+
923
934
  function parseRegistryPath(relPath, registrySubDir = null) {
924
935
  const parts = relPath.split('/');
925
- for (let i = 0; i < parts.length; i++) {
926
- if (PUSHABLE_TYPES.includes(parts[i]) && i + 1 < parts.length) {
927
- const namespaceParts = parts.slice(0, i);
928
- if (parts[i] === 'skills') {
929
- const skillParts = parts.slice(i + 1).map(part => part.replace(/\.md$/, ''));
930
- const slugParts = findSkillSlugParts(namespaceParts, skillParts, registrySubDir);
931
- return {
932
- type: parts[i],
933
- namespace: namespaceParts.join('/'),
934
- slug: slugParts.join('/'),
935
- };
936
- }
936
+ const typeIdx = findPushableTypeIndex(parts);
937
+ if (typeIdx === -1 || typeIdx + 1 >= parts.length) return null;
937
938
 
938
- return {
939
- type: parts[i],
940
- namespace: namespaceParts.join('/'),
941
- slug: parts[i + 1].replace(/\.md$/, ''),
942
- };
943
- }
939
+ const namespaceParts = parts.slice(0, typeIdx);
940
+ if (parts[typeIdx] === 'skills') {
941
+ const skillParts = parts.slice(typeIdx + 1).map(part => part.replace(/\.md$/, ''));
942
+ const slugParts = findSkillSlugParts(namespaceParts, skillParts, registrySubDir);
943
+ return {
944
+ type: parts[typeIdx],
945
+ namespace: namespaceParts.join('/'),
946
+ slug: slugParts.join('/'),
947
+ };
944
948
  }
945
- return null;
949
+
950
+ return {
951
+ type: parts[typeIdx],
952
+ namespace: namespaceParts.join('/'),
953
+ slug: parts[typeIdx + 1].replace(/\.md$/, ''),
954
+ };
946
955
  }
947
956
 
948
957
  // ── Colocated eval resolution ─────────────────────────────────────────
@@ -1447,6 +1456,8 @@ export async function pushCommand(args) {
1447
1456
  const namespacePath = meta.namespace;
1448
1457
  const isDir = !isDeletedFile && statSync(absPath).isDirectory();
1449
1458
  const registryPathWithExt = resolved.registryPath.endsWith('.md')
1459
+ || (!isDeletedFile && absPath && !absPath.endsWith('.md'))
1460
+ || (isDeletedFile && /\.[^/]+$/.test(resolved.registryPath))
1450
1461
  ? resolved.registryPath
1451
1462
  : `${resolved.registryPath}.md`;
1452
1463
  const registryTarget = isDir
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.59",
3
+ "version": "0.1.60",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
6
  "bin": {