@neobiotechlabs/neobiotech-dev-agent 0.1.40 → 0.1.42

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.
@@ -10,7 +10,7 @@
10
10
  "source": "npm",
11
11
  "package": "@neobiotechlabs/neobiotech-dev-agent",
12
12
  "registry": "https://registry.npmjs.org",
13
- "version": "0.1.40"
13
+ "version": "0.1.42"
14
14
  },
15
15
  "description": "의료기기 SW 규제 개발 자동화 (Jira·Confluence·Risk·CVSS·Xray·IEC 62304/62366·MDR·문서 렌더)",
16
16
  "category": "medical-device",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neobiotech-dev-agent",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "displayName": "NeoBiotech Dev Agent (MedDev)",
5
5
  "description": "의료기기 SW 규제 개발 자동화 — Jira·Confluence·Risk·CVSS·Xray·IEC 62304/62366·MDR·문서 렌더",
6
6
  "author": {
package/dist/doctor.js CHANGED
@@ -3117,6 +3117,7 @@ var require_utils = __commonJS({
3117
3117
  "use strict";
3118
3118
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3119
3119
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
3120
+ var isPort = RegExp.prototype.test.bind(/^\d*$/u);
3120
3121
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
3121
3122
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
3122
3123
  var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
@@ -3582,8 +3583,12 @@ var require_utils = __commonJS({
3582
3583
  uriTokens.push(host);
3583
3584
  }
3584
3585
  if (typeof component.port === "number" || typeof component.port === "string") {
3586
+ const port = String(component.port);
3587
+ if (!isPort(port)) {
3588
+ throw new TypeError("URI port is malformed.");
3589
+ }
3585
3590
  uriTokens.push(":");
3586
- uriTokens.push(String(component.port));
3591
+ uriTokens.push(port);
3587
3592
  }
3588
3593
  return uriTokens.length ? uriTokens.join("") : void 0;
3589
3594
  }
@@ -4026,12 +4031,15 @@ var require_fast_uri = __commonJS({
4026
4031
  }
4027
4032
  return false;
4028
4033
  }
4034
+ function isIPLiteral(host) {
4035
+ return host[0] === "[" && host[host.length - 1] === "]";
4036
+ }
4029
4037
  function hasMalformedComponentPercentEncoding(matches) {
4030
4038
  const host = matches[4];
4031
- return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !(host[0] === "[" && host[host.length - 1] === "]") && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4039
+ return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4032
4040
  }
4033
4041
  function canonicalizeHost(parsed, options, schemeHandler, isIP) {
4034
- if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4042
+ if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4035
4043
  try {
4036
4044
  parsed.host = new URL("http://" + parsed.host).hostname;
4037
4045
  } catch (e) {
@@ -4118,10 +4126,11 @@ var require_fast_uri = __commonJS({
4118
4126
  if (parsed.host) {
4119
4127
  const ipv4result = isIPv4(parsed.host);
4120
4128
  if (ipv4result === false) {
4121
- const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
4129
+ const bracketedIPLiteral = isIPLiteral(parsed.host);
4130
+ const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
4122
4131
  const ipv6result = normalizeIPv6(parsed.host);
4123
4132
  isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
4124
- malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
4133
+ malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
4125
4134
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4126
4135
  if (malformedIPLiteral) {
4127
4136
  parsed.error = parsed.error || "URI host is malformed.";
@@ -4144,7 +4153,9 @@ var require_fast_uri = __commonJS({
4144
4153
  parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
4145
4154
  }
4146
4155
  const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
4147
- malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
4156
+ if (!malformedIPLiteral) {
4157
+ malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
4158
+ }
4148
4159
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4149
4160
  if (uri.indexOf("%") !== -1) {
4150
4161
  if (parsed.host !== void 0 && !malformedIPLiteral) {
@@ -7698,7 +7709,7 @@ var require_cross_spawn = __commonJS({
7698
7709
 
7699
7710
  // src/cli/doctor.ts
7700
7711
  import { execFile } from "child_process";
7701
- import { existsSync, readdirSync } from "fs";
7712
+ import { existsSync, readFileSync, readdirSync } from "fs";
7702
7713
  import path from "path";
7703
7714
  import { promisify } from "util";
7704
7715
  import { fileURLToPath } from "url";
@@ -15054,10 +15065,37 @@ function inspectAssets(pluginRoot) {
15054
15065
  [
15055
15066
  "data/review-criteria.md",
15056
15067
  existsSync(path.join(pluginRoot, "data", "review-criteria.md"))
15068
+ ],
15069
+ [
15070
+ "skills/gate-parallel-review/SKILL.md",
15071
+ existsSync(path.join(pluginRoot, "skills", "gate-parallel-review", "SKILL.md"))
15072
+ ],
15073
+ [
15074
+ "codex-agents/*.toml",
15075
+ directoryHasFiles(path.join(pluginRoot, "codex-agents"), (name) => name.endsWith(".toml"))
15057
15076
  ]
15058
15077
  ];
15059
15078
  return checks.map(([name, available]) => ({ name, required: true, available }));
15060
15079
  }
15080
+ function inspectCodexAgents(pluginRoot, projectDir) {
15081
+ const templatesDir = path.join(pluginRoot, "codex-agents");
15082
+ const targetDir = path.join(projectDir, ".codex", "agents");
15083
+ const expected = existsSync(templatesDir) ? readdirSync(templatesDir).filter((name) => name.endsWith(".toml")).sort() : [];
15084
+ const installed = [];
15085
+ const missing = [];
15086
+ const conflicts = [];
15087
+ for (const name of expected) {
15088
+ const targetPath = path.join(targetDir, name);
15089
+ if (!existsSync(targetPath)) {
15090
+ missing.push(name);
15091
+ } else if (readFileSync(targetPath, "utf8") === readFileSync(path.join(templatesDir, name), "utf8")) {
15092
+ installed.push(name);
15093
+ } else {
15094
+ conflicts.push(name);
15095
+ }
15096
+ }
15097
+ return { expected, installed, missing, conflicts };
15098
+ }
15061
15099
  async function probeJava() {
15062
15100
  try {
15063
15101
  await execFileAsync("java", ["-version"]);
@@ -15069,6 +15107,7 @@ async function probeJava() {
15069
15107
  async function runDoctor(options) {
15070
15108
  const environment = inspectEnvironment(options.env);
15071
15109
  const assets = inspectAssets(options.pluginRoot);
15110
+ const codexAgents = inspectCodexAgents(options.pluginRoot, options.projectDir ?? process.cwd());
15072
15111
  const java = await (options.javaProbe ?? probeJava)();
15073
15112
  const mcp = {};
15074
15113
  try {
@@ -15084,21 +15123,23 @@ async function runDoctor(options) {
15084
15123
  mcp.error = error2 instanceof Error ? error2.message : String(error2);
15085
15124
  }
15086
15125
  return {
15087
- ok: environment.filter((item) => item.required).every((item) => item.configured) && assets.filter((item) => item.required).every((item) => item.available) && !mcp.error,
15126
+ ok: environment.filter((item) => item.required).every((item) => item.configured) && assets.filter((item) => item.required).every((item) => item.available) && codexAgents.expected.length === 5 && codexAgents.missing.length === 0 && codexAgents.conflicts.length === 0 && !mcp.error,
15088
15127
  environment,
15089
15128
  assets,
15090
15129
  java,
15130
+ codexAgents,
15091
15131
  mcp
15092
15132
  };
15093
15133
  }
15094
15134
  if (process.argv[1] === fileURLToPath(import.meta.url)) {
15095
15135
  const pluginRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
15096
- const report = await runDoctor({ pluginRoot, env: process.env });
15136
+ const report = await runDoctor({ pluginRoot, projectDir: process.cwd(), env: process.env });
15097
15137
  process.stdout.write(`${JSON.stringify(report, null, 2)}
15098
15138
  `);
15099
15139
  if (!report.ok) process.exitCode = 1;
15100
15140
  }
15101
15141
  export {
15142
+ inspectCodexAgents,
15102
15143
  inspectEnvironment,
15103
15144
  runDoctor,
15104
15145
  smokeMcpServer