@mcoda/core 0.1.36 → 0.1.37

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":"TaskSufficiencyService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/TaskSufficiencyService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskSufficiencyService.d.ts","sourceRoot":"","sources":["../../../src/services/planning/TaskSufficiencyService.ts"],"names":[],"mappings":"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"}
@@ -93,24 +93,88 @@ const dataPathSegments = new Set([
93
93
  ]);
94
94
  const testPathSegments = new Set(["acceptance", "e2e", "integration", "spec", "specs", "test", "tests"]);
95
95
  const opsPathSegments = new Set([
96
+ "automation",
96
97
  "deploy",
97
98
  "deployment",
98
99
  "deployments",
99
- "helm",
100
100
  "infra",
101
- "k8s",
102
101
  "ops",
103
102
  "operation",
104
103
  "operations",
104
+ "orchestration",
105
+ "orchestrations",
106
+ "provision",
107
+ "provisioning",
105
108
  "runbook",
106
109
  "runbooks",
107
110
  "script",
108
111
  "scripts",
109
- "systemd",
110
- "terraform",
111
112
  ]);
112
- const manifestBasenamePattern = /^(package\.json|pnpm-workspace\.yaml|pnpm-lock\.yaml|turbo\.json|tsconfig(?:\.[^.]+)?\.json|cargo\.toml|pyproject\.toml|go\.mod|go\.sum|pom\.xml|build\.gradle(?:\.kts)?|settings\.gradle(?:\.kts)?|requirements\.txt|poetry\.lock|foundry\.toml|hardhat\.config\.[^.]+)$/i;
113
- const serviceArtifactBasenamePattern = /(?:\.service|\.socket|\.timer|(?:^|[.-])compose\.(?:ya?ml|json)$|docker-compose\.(?:ya?ml|json)$)$/i;
113
+ const manifestSignalTokens = new Set([
114
+ "build",
115
+ "config",
116
+ "configuration",
117
+ "dependency",
118
+ "dependencies",
119
+ "environment",
120
+ "lock",
121
+ "lockfile",
122
+ "manifest",
123
+ "package",
124
+ "project",
125
+ "settings",
126
+ "tooling",
127
+ "workspace",
128
+ "worktree",
129
+ ]);
130
+ const manifestMachineFilePattern = /\.(?:cfg|cnf|conf|gradle|ini|json|kts|lock|mod|properties|sum|toml|txt|xml|ya?ml)$/i;
131
+ const nonManifestTokens = new Set([
132
+ "acceptance",
133
+ "archive",
134
+ "changelog",
135
+ "contract",
136
+ "contracts",
137
+ "example",
138
+ "examples",
139
+ "fixture",
140
+ "fixtures",
141
+ "guide",
142
+ "guides",
143
+ "license",
144
+ "manual",
145
+ "manuals",
146
+ "notice",
147
+ "readme",
148
+ "reference",
149
+ "references",
150
+ "sample",
151
+ "samples",
152
+ "schema",
153
+ "schemas",
154
+ "spec",
155
+ "specs",
156
+ "test",
157
+ "tests",
158
+ ]);
159
+ const serviceArtifactSignalPattern = /(?:^|[._-])(compose|daemon|orchestrator|scheduler|service|socket|timer|worker)(?:[._-]|$)|\.(?:service|socket|timer)$/i;
160
+ const tokenizeBasename = (value) => value
161
+ .toLowerCase()
162
+ .split(/[^a-z0-9]+/)
163
+ .map((segment) => segment.trim())
164
+ .filter(Boolean);
165
+ const isManifestLikeBasename = (basename, segments = []) => {
166
+ const normalized = basename.toLowerCase();
167
+ const tokens = tokenizeBasename(normalized);
168
+ if (tokens.some((token) => manifestSignalTokens.has(token)))
169
+ return true;
170
+ if (!manifestMachineFilePattern.test(normalized))
171
+ return false;
172
+ if (segments.length <= 2 && tokens.length <= 3 && !tokens.some((token) => nonManifestTokens.has(token))) {
173
+ return true;
174
+ }
175
+ return false;
176
+ };
177
+ const isServiceArtifactBasename = (basename) => serviceArtifactSignalPattern.test(basename.toLowerCase());
114
178
  const normalizeText = (value) => normalizeCoverageText(value);
115
179
  const normalizeAnchor = normalizeCoverageAnchor;
116
180
  const toPlannedGapBundle = (entry) => ({
@@ -172,11 +236,11 @@ const classifyImplementationTarget = (target) => {
172
236
  const normalized = normalizeFolderEntry(target)?.toLowerCase() ?? normalizeText(target);
173
237
  const segments = normalized.split("/").filter(Boolean);
174
238
  const basename = segments[segments.length - 1] ?? normalized;
175
- const isServiceArtifact = serviceArtifactBasenamePattern.test(basename);
239
+ const isServiceArtifact = isServiceArtifactBasename(basename);
176
240
  if (segments.some((segment) => supportRootSegments.has(segment))) {
177
241
  return { normalized, basename, segments, kind: "doc", isServiceArtifact };
178
242
  }
179
- if (manifestBasenamePattern.test(basename) || isServiceArtifact) {
243
+ if (isManifestLikeBasename(basename, segments) || isServiceArtifact) {
180
244
  return { normalized, basename, segments, kind: "manifest", isServiceArtifact };
181
245
  }
182
246
  if (segments.some((segment) => testPathSegments.has(segment))) {
@@ -269,7 +333,81 @@ const inferImplementationTargets = (bundle, availablePaths, limit = 3) => {
269
333
  return false;
270
334
  return true;
271
335
  });
272
- return unique((filtered.length > 0 ? filtered : scored.filter((entry) => entry.score > 0)).map((entry) => entry.candidate)).slice(0, limit);
336
+ const prioritized = (filtered.length > 0 ? filtered : scored.filter((entry) => entry.score > 0)).filter((entry, _, entries) => {
337
+ if (isStructuredFilePath(entry.classification.basename))
338
+ return true;
339
+ return !entries.some((other) => {
340
+ if (other === entry)
341
+ return false;
342
+ if (other.score + 5 < entry.score)
343
+ return false;
344
+ if (!other.candidate.startsWith(`${entry.candidate}/`))
345
+ return false;
346
+ return (other.classification.kind === entry.classification.kind ||
347
+ isStructuredFilePath(other.classification.basename));
348
+ });
349
+ });
350
+ const prioritizedFiles = prioritized.filter((entry) => isStructuredFilePath(entry.classification.basename));
351
+ const fileLifted = prioritized.map((entry) => {
352
+ if (isStructuredFilePath(entry.classification.basename))
353
+ return entry;
354
+ const replacement = prioritizedFiles.find((other) => {
355
+ if (!other.candidate.startsWith(`${entry.candidate}/`))
356
+ return false;
357
+ if (other.score + 10 < entry.score)
358
+ return false;
359
+ return (other.classification.kind === entry.classification.kind ||
360
+ other.classification.kind === "runtime" ||
361
+ entry.classification.kind === "unknown");
362
+ });
363
+ return replacement ?? entry;
364
+ });
365
+ const collapsed = fileLifted.filter((entry, _, entries) => {
366
+ if (isStructuredFilePath(entry.classification.basename))
367
+ return true;
368
+ return !entries.some((other) => {
369
+ if (other === entry)
370
+ return false;
371
+ if (!isStructuredFilePath(other.classification.basename))
372
+ return false;
373
+ return other.candidate.startsWith(`${entry.candidate}/`);
374
+ });
375
+ });
376
+ const descendantFiles = unique(availablePaths
377
+ .map((candidate) => normalizeFolderEntry(candidate))
378
+ .filter((candidate) => Boolean(candidate))
379
+ .filter((candidate) => isStructuredFilePath(path.basename(candidate)))
380
+ .map((candidate) => {
381
+ const classification = classifyImplementationTarget(candidate);
382
+ const normalizedCandidate = classification.normalized.replace(/\//g, " ");
383
+ const overlap = anchorTokens.filter((token) => normalizedCandidate.includes(token)).length;
384
+ const hasDomainMatch = domainNeedle.length > 0 && normalizedCandidate.includes(domainNeedle);
385
+ const semanticBonus = (targetNeeds.wantsVerification && classification.kind === "test" ? 40 : 0) +
386
+ (targetNeeds.wantsOps && classification.kind === "ops" ? 50 : 0) +
387
+ (targetNeeds.wantsInterface && classification.kind === "interface" ? 45 : 0) +
388
+ (targetNeeds.wantsData && classification.kind === "data" ? 45 : 0) +
389
+ (targetNeeds.wantsProvider &&
390
+ (classification.kind === "runtime" || classification.kind === "interface")
391
+ ? 25
392
+ : 0);
393
+ return {
394
+ candidate,
395
+ score: implementationRootWeight(candidate) + overlap * 20 + (hasDomainMatch ? 20 : 0) + semanticBonus,
396
+ };
397
+ })
398
+ .sort((left, right) => right.score - left.score || left.candidate.localeCompare(right.candidate))
399
+ .map((entry) => entry.candidate));
400
+ const promoted = unique(collapsed.map((entry) => {
401
+ if (isStructuredFilePath(entry.classification.basename))
402
+ return entry.candidate;
403
+ const replacement = descendantFiles.find((candidate) => candidate.startsWith(`${entry.candidate}/`) || candidate.startsWith(`${entry.candidate.replace(/\/+$/g, "")}/`));
404
+ return replacement ?? entry.candidate;
405
+ })).filter((candidate, _, entries) => {
406
+ if (isStructuredFilePath(path.basename(candidate)))
407
+ return true;
408
+ return !entries.some((other) => other !== candidate && isStructuredFilePath(path.basename(other)) && other.startsWith(`${candidate}/`));
409
+ });
410
+ return promoted.slice(0, limit);
273
411
  };
274
412
  const summarizeImplementationTargets = (targets) => {
275
413
  if (targets.length === 0)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcoda/core",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "description": "Core services and APIs for the mcoda CLI.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,11 +32,11 @@
32
32
  "dependencies": {
33
33
  "@apidevtools/swagger-parser": "^10.1.0",
34
34
  "yaml": "^2.4.2",
35
- "@mcoda/db": "0.1.36",
36
- "@mcoda/generators": "0.1.36",
37
- "@mcoda/agents": "0.1.36",
38
- "@mcoda/integrations": "0.1.36",
39
- "@mcoda/shared": "0.1.36"
35
+ "@mcoda/db": "0.1.37",
36
+ "@mcoda/shared": "0.1.37",
37
+ "@mcoda/generators": "0.1.37",
38
+ "@mcoda/agents": "0.1.37",
39
+ "@mcoda/integrations": "0.1.37"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "tsc -p tsconfig.json",