@dusky-bluehour/agent-service 0.6.6 → 0.6.7

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 (98) hide show
  1. package/README.md +20 -28
  2. package/antigravity/README.md +7 -0
  3. package/antigravity/commands/definitions/cmd-dev-be-api.md +43 -0
  4. package/antigravity/commands/definitions/cmd-dev-fe-hook-separate.md +43 -0
  5. package/antigravity/commands/definitions/cmd-dev-fe-ui-componentize.md +43 -0
  6. package/antigravity/commands/definitions/cmd-dev-perf-optimize.md +43 -0
  7. package/antigravity/commands/definitions/cmd-dev-sequential-autorun.md +43 -0
  8. package/antigravity/commands/definitions/cmd-doc-handoff.md +44 -0
  9. package/antigravity/commands/definitions/cmd-improve-techdebt.md +43 -0
  10. package/antigravity/commands/definitions/cmd-incident-triage.md +43 -0
  11. package/antigravity/commands/definitions/cmd-ops-ci-cd-gate.md +43 -0
  12. package/antigravity/commands/definitions/cmd-ops-deploy.md +43 -0
  13. package/antigravity/commands/definitions/cmd-ops-monitoring.md +43 -0
  14. package/antigravity/commands/definitions/cmd-plan-arch-decision.md +43 -0
  15. package/antigravity/commands/definitions/cmd-plan-implementation-bootstrap.md +43 -0
  16. package/antigravity/commands/definitions/cmd-plan-prd-details.md +43 -0
  17. package/antigravity/commands/definitions/cmd-plan-prd-master.md +44 -0
  18. package/antigravity/commands/definitions/cmd-plan-req-lock.md +44 -0
  19. package/antigravity/commands/definitions/cmd-review-code.md +43 -0
  20. package/antigravity/commands/definitions/cmd-sec-dependency-audit.md +43 -0
  21. package/antigravity/commands/definitions/cmd-sec-threat-model.md +43 -0
  22. package/antigravity/commands/definitions/cmd-test-unit-integration.md +43 -0
  23. package/antigravity/instructions/WORKSPACE-RULES.template.md +34 -0
  24. package/antigravity/settings/editor-policy.json +193 -0
  25. package/catalog/tool-catalog.ko.json +77 -16
  26. package/claude-code/README.md +27 -0
  27. package/claude-code/commands/native/cmd-dev-be-api.md +51 -0
  28. package/claude-code/commands/native/cmd-dev-fe-hook-separate.md +51 -0
  29. package/claude-code/commands/native/cmd-dev-fe-ui-componentize.md +51 -0
  30. package/claude-code/commands/native/cmd-dev-perf-optimize.md +51 -0
  31. package/claude-code/commands/native/cmd-dev-sequential-autorun.md +51 -0
  32. package/claude-code/commands/native/cmd-doc-handoff.md +52 -0
  33. package/claude-code/commands/native/cmd-improve-techdebt.md +51 -0
  34. package/claude-code/commands/native/cmd-incident-triage.md +51 -0
  35. package/claude-code/commands/native/cmd-ops-ci-cd-gate.md +51 -0
  36. package/claude-code/commands/native/cmd-ops-deploy.md +51 -0
  37. package/claude-code/commands/native/cmd-ops-monitoring.md +51 -0
  38. package/claude-code/commands/native/cmd-plan-arch-decision.md +51 -0
  39. package/claude-code/commands/native/cmd-plan-implementation-bootstrap.md +51 -0
  40. package/claude-code/commands/native/cmd-plan-prd-details.md +51 -0
  41. package/claude-code/commands/native/cmd-plan-prd-master.md +52 -0
  42. package/claude-code/commands/native/cmd-plan-req-lock.md +52 -0
  43. package/claude-code/commands/native/cmd-review-code.md +51 -0
  44. package/claude-code/commands/native/cmd-sec-dependency-audit.md +51 -0
  45. package/claude-code/commands/native/cmd-sec-threat-model.md +51 -0
  46. package/claude-code/commands/native/cmd-test-unit-integration.md +51 -0
  47. package/claude-code/instructions/CLAUDE.template.md +42 -0
  48. package/claude-code/settings/settings.json +183 -0
  49. package/claude-code/settings/settings.local.json +10 -0
  50. package/codex/README.md +13 -1
  51. package/codex/instructions/AGENTS.permissions.generated.md +121 -0
  52. package/codex/instructions/AGENTS.template.md +18 -3
  53. package/codex/settings/runtime-policy.json +188 -0
  54. package/codex/skills/cmd-dev-be-api/SKILL.md +43 -0
  55. package/codex/skills/cmd-dev-be-api/agents/openai.yaml +4 -0
  56. package/codex/skills/cmd-dev-fe-hook-separate/SKILL.md +43 -0
  57. package/codex/skills/cmd-dev-fe-hook-separate/agents/openai.yaml +4 -0
  58. package/codex/skills/cmd-dev-fe-ui-componentize/SKILL.md +43 -0
  59. package/codex/skills/cmd-dev-fe-ui-componentize/agents/openai.yaml +4 -0
  60. package/codex/skills/cmd-dev-perf-optimize/SKILL.md +43 -0
  61. package/codex/skills/cmd-dev-perf-optimize/agents/openai.yaml +4 -0
  62. package/codex/skills/cmd-dev-sequential-autorun/SKILL.md +43 -0
  63. package/codex/skills/cmd-dev-sequential-autorun/agents/openai.yaml +4 -0
  64. package/codex/skills/cmd-doc-handoff/SKILL.md +43 -0
  65. package/codex/skills/cmd-doc-handoff/agents/openai.yaml +4 -0
  66. package/codex/skills/cmd-improve-techdebt/SKILL.md +43 -0
  67. package/codex/skills/cmd-improve-techdebt/agents/openai.yaml +4 -0
  68. package/codex/skills/cmd-incident-triage/SKILL.md +43 -0
  69. package/codex/skills/cmd-incident-triage/agents/openai.yaml +4 -0
  70. package/codex/skills/cmd-ops-ci-cd-gate/SKILL.md +43 -0
  71. package/codex/skills/cmd-ops-ci-cd-gate/agents/openai.yaml +4 -0
  72. package/codex/skills/cmd-ops-deploy/SKILL.md +43 -0
  73. package/codex/skills/cmd-ops-deploy/agents/openai.yaml +4 -0
  74. package/codex/skills/cmd-ops-monitoring/SKILL.md +43 -0
  75. package/codex/skills/cmd-ops-monitoring/agents/openai.yaml +4 -0
  76. package/codex/skills/cmd-plan-arch-decision/SKILL.md +43 -0
  77. package/codex/skills/cmd-plan-arch-decision/agents/openai.yaml +4 -0
  78. package/codex/skills/cmd-plan-implementation-bootstrap/SKILL.md +43 -0
  79. package/codex/skills/cmd-plan-implementation-bootstrap/agents/openai.yaml +4 -0
  80. package/codex/skills/cmd-plan-prd-details/SKILL.md +43 -0
  81. package/codex/skills/cmd-plan-prd-details/agents/openai.yaml +4 -0
  82. package/codex/skills/cmd-plan-prd-master/SKILL.md +44 -0
  83. package/codex/skills/cmd-plan-prd-master/agents/openai.yaml +4 -0
  84. package/codex/skills/cmd-plan-req-lock/SKILL.md +44 -0
  85. package/codex/skills/cmd-plan-req-lock/agents/openai.yaml +4 -0
  86. package/codex/skills/cmd-review-code/SKILL.md +43 -0
  87. package/codex/skills/cmd-review-code/agents/openai.yaml +4 -0
  88. package/codex/skills/cmd-sec-dependency-audit/SKILL.md +43 -0
  89. package/codex/skills/cmd-sec-dependency-audit/agents/openai.yaml +4 -0
  90. package/codex/skills/cmd-sec-threat-model/SKILL.md +43 -0
  91. package/codex/skills/cmd-sec-threat-model/agents/openai.yaml +4 -0
  92. package/codex/skills/cmd-test-unit-integration/SKILL.md +43 -0
  93. package/codex/skills/cmd-test-unit-integration/agents/openai.yaml +4 -0
  94. package/common/settings/security-policy.json +221 -0
  95. package/package.json +1 -1
  96. package/scripts/generate-from-common.mjs +489 -4
  97. package/scripts/init.mjs +285 -36
  98. package/scripts/validate.mjs +208 -9
@@ -51,6 +51,18 @@ function parseFrontmatter(content) {
51
51
  return result;
52
52
  }
53
53
 
54
+ function normalizeCommandBasename(commandId) {
55
+ const normalized = String(commandId ?? '')
56
+ .trim()
57
+ .toLowerCase()
58
+ .replace(/[^a-z0-9-]+/g, '-')
59
+ .replace(/^-+|-+$/g, '');
60
+ if (!normalized) {
61
+ throw new Error(`invalid command id: ${commandId}`);
62
+ }
63
+ return normalized;
64
+ }
65
+
54
66
  async function validateCatalog() {
55
67
  const catalogPath = path.join(rootDir, 'catalog', 'tool-catalog.ko.json');
56
68
  if (!(await exists(catalogPath))) {
@@ -193,6 +205,7 @@ async function validateCommonSources() {
193
205
  'common/commands/command-catalog.json',
194
206
  'common/workflows/workflow-catalog.json',
195
207
  'common/skills/skill-catalog.json',
208
+ 'common/settings/security-policy.json',
196
209
  'common/claude/subagent-catalog.json',
197
210
  'common/claude/team-catalog.json',
198
211
  'common/antigravity/agent-catalog.json',
@@ -369,6 +382,30 @@ async function validateCommonSources() {
369
382
  }
370
383
  }
371
384
  }
385
+
386
+ const securityPolicy = commonData['common/settings/security-policy.json'];
387
+ if (securityPolicy) {
388
+ if (!securityPolicy.policy_id || !securityPolicy.shared_permissions) {
389
+ fail('[common/settings] policy_id/shared_permissions 누락');
390
+ }
391
+ const shared = securityPolicy.shared_permissions ?? {};
392
+ for (const field of [
393
+ 'allow_bash',
394
+ 'ask_bash',
395
+ 'deny_bash',
396
+ 'deny_read',
397
+ 'deny_edit'
398
+ ]) {
399
+ if (!Array.isArray(shared[field])) {
400
+ fail(`[common/settings] 배열 누락: ${field}`);
401
+ }
402
+ }
403
+
404
+ const claude = securityPolicy.claude_code ?? {};
405
+ if (!claude.default_mode || !claude.disable_bypass_permissions_mode) {
406
+ fail('[common/settings] claude_code default_mode/disable_bypass_permissions_mode 누락');
407
+ }
408
+ }
372
409
  }
373
410
 
374
411
  async function validatePackageJson() {
@@ -506,7 +543,7 @@ async function validateCommandCatalog(toolName) {
506
543
  const filePath = path.join(rootDir, toolName, 'commands', 'command-catalog.json');
507
544
  if (!(await exists(filePath))) {
508
545
  fail(`[${toolName}] command-catalog.json 누락`);
509
- return { commandIds: new Set() };
546
+ return { commandIds: new Set(), commandFileBases: new Set() };
510
547
  }
511
548
 
512
549
  let data;
@@ -514,12 +551,12 @@ async function validateCommandCatalog(toolName) {
514
551
  data = await readJson(filePath);
515
552
  } catch (error) {
516
553
  fail(`[${toolName}] command-catalog.json 파싱 실패: ${error.message}`);
517
- return { commandIds: new Set() };
554
+ return { commandIds: new Set(), commandFileBases: new Set() };
518
555
  }
519
556
 
520
557
  if (!Array.isArray(data.commands) || data.commands.length === 0) {
521
558
  fail(`[${toolName}] commands 배열 누락 또는 비어 있음`);
522
- return { commandIds: new Set() };
559
+ return { commandIds: new Set(), commandFileBases: new Set() };
523
560
  }
524
561
 
525
562
  const requiredFields = [
@@ -536,6 +573,7 @@ async function validateCommandCatalog(toolName) {
536
573
  ];
537
574
 
538
575
  const commandIds = new Set();
576
+ const commandFileBases = new Set();
539
577
  for (const cmd of data.commands) {
540
578
  for (const field of requiredFields) {
541
579
  if (!(field in cmd)) {
@@ -552,6 +590,11 @@ async function validateCommandCatalog(toolName) {
552
590
  fail(`[${toolName}] 중복 명령 ID: ${cmd.id}`);
553
591
  }
554
592
  commandIds.add(cmd.id);
593
+ try {
594
+ commandFileBases.add(normalizeCommandBasename(cmd.id));
595
+ } catch (error) {
596
+ fail(`[${toolName}] 명령 ID 형식 오류: ${cmd.id} (${error.message})`);
597
+ }
555
598
  }
556
599
 
557
600
  const repeatedIds = [
@@ -566,7 +609,7 @@ async function validateCommandCatalog(toolName) {
566
609
  }
567
610
  }
568
611
 
569
- return { commandIds };
612
+ return { commandIds, commandFileBases };
570
613
  }
571
614
 
572
615
  async function validateWorkflowCatalog(toolName, commandIds) {
@@ -620,7 +663,7 @@ async function validateWorkflowCatalog(toolName, commandIds) {
620
663
  }
621
664
  }
622
665
 
623
- async function validateClaudeExtras() {
666
+ async function validateClaudeExtras(commandFileBases) {
624
667
  const subagentsPath = path.join(rootDir, 'claude-code', 'subagents');
625
668
  if (!(await exists(subagentsPath))) {
626
669
  fail('[claude-code] subagents 디렉터리 누락');
@@ -645,9 +688,37 @@ async function validateClaudeExtras() {
645
688
  if (!(await exists(teamCatalog))) {
646
689
  fail('[claude-code] team-catalog.json 누락');
647
690
  }
691
+
692
+ const commandDir = path.join(rootDir, 'claude-code', 'commands', 'native');
693
+ if (!(await exists(commandDir))) {
694
+ fail('[claude-code] commands/native 디렉터리 누락');
695
+ return;
696
+ }
697
+
698
+ const commandFiles = new Set((await fs.readdir(commandDir)).filter((file) => file.endsWith('.md')));
699
+ for (const base of commandFileBases) {
700
+ const expected = `${base}.md`;
701
+ if (!commandFiles.has(expected)) {
702
+ fail(`[claude-code] native command 누락: commands/native/${expected}`);
703
+ }
704
+ }
705
+ }
706
+
707
+ async function validateCodexExtras(commandFileBases) {
708
+ const codexSkillDir = path.join(rootDir, 'codex', 'skills');
709
+ for (const base of commandFileBases) {
710
+ const skillFile = path.join(codexSkillDir, base, 'SKILL.md');
711
+ const openAiYaml = path.join(codexSkillDir, base, 'agents', 'openai.yaml');
712
+ if (!(await exists(skillFile))) {
713
+ fail(`[codex] 명령 스킬 누락: skills/${base}/SKILL.md`);
714
+ }
715
+ if (!(await exists(openAiYaml))) {
716
+ fail(`[codex] 명령 스킬 openai.yaml 누락: skills/${base}/agents/openai.yaml`);
717
+ }
718
+ }
648
719
  }
649
720
 
650
- async function validateAntigravityExtras() {
721
+ async function validateAntigravityExtras(commandFileBases) {
651
722
  const agentCatalog = path.join(rootDir, 'antigravity', 'agents', 'agent-catalog.json');
652
723
  const artifactCatalog = path.join(rootDir, 'antigravity', 'artifacts', 'artifact-catalog.json');
653
724
 
@@ -693,6 +764,22 @@ async function validateAntigravityExtras() {
693
764
  fail(`[antigravity] workflow definition 누락: ${expected}`);
694
765
  }
695
766
  }
767
+
768
+ const commandDefinitionsDir = path.join(rootDir, 'antigravity', 'commands', 'definitions');
769
+ if (!(await exists(commandDefinitionsDir))) {
770
+ fail('[antigravity] commands/definitions 디렉터리 누락');
771
+ return;
772
+ }
773
+
774
+ const commandDefinitionFiles = new Set(
775
+ (await fs.readdir(commandDefinitionsDir)).filter((file) => file.endsWith('.md'))
776
+ );
777
+ for (const base of commandFileBases) {
778
+ const expected = `${base}.md`;
779
+ if (!commandDefinitionFiles.has(expected)) {
780
+ fail(`[antigravity] command definition 누락: commands/definitions/${expected}`);
781
+ }
782
+ }
696
783
  }
697
784
 
698
785
  async function validateReadmes() {
@@ -704,6 +791,89 @@ async function validateReadmes() {
704
791
  }
705
792
  }
706
793
 
794
+ async function validateSettingsOutputs() {
795
+ const settingsFiles = [
796
+ 'claude-code/settings/settings.json',
797
+ 'claude-code/settings/settings.local.json',
798
+ 'antigravity/settings/editor-policy.json',
799
+ 'codex/settings/runtime-policy.json'
800
+ ];
801
+
802
+ for (const relPath of settingsFiles) {
803
+ const fullPath = path.join(rootDir, relPath);
804
+ if (!(await exists(fullPath))) {
805
+ fail(`[settings] 파일 누락: ${relPath}`);
806
+ continue;
807
+ }
808
+ try {
809
+ await readJson(fullPath);
810
+ } catch (error) {
811
+ fail(`[settings] JSON 파싱 실패: ${relPath} (${error.message})`);
812
+ }
813
+ }
814
+
815
+ const claudeProjectPath = path.join(
816
+ rootDir,
817
+ 'claude-code',
818
+ 'settings',
819
+ 'settings.json'
820
+ );
821
+ if (await exists(claudeProjectPath)) {
822
+ try {
823
+ const claude = await readJson(claudeProjectPath);
824
+ const permissions = claude.permissions ?? {};
825
+ const validModes = new Set([
826
+ 'default',
827
+ 'acceptEdits',
828
+ 'plan',
829
+ 'dontAsk',
830
+ 'bypassPermissions'
831
+ ]);
832
+ if (!validModes.has(permissions.defaultMode)) {
833
+ fail(`[settings] Claude defaultMode 값 오류: ${permissions.defaultMode}`);
834
+ }
835
+ for (const key of ['allow', 'ask', 'deny']) {
836
+ if (!Array.isArray(permissions[key])) {
837
+ fail(`[settings] Claude permissions.${key} 누락`);
838
+ }
839
+ }
840
+ } catch (error) {
841
+ fail(`[settings] Claude 설정 검증 실패: ${error.message}`);
842
+ }
843
+ }
844
+
845
+ const codexAgentsPermissionPath = path.join(
846
+ rootDir,
847
+ 'codex',
848
+ 'instructions',
849
+ 'AGENTS.permissions.generated.md'
850
+ );
851
+ if (!(await exists(codexAgentsPermissionPath))) {
852
+ fail('[settings] Codex AGENTS.permissions.generated.md 누락');
853
+ }
854
+ }
855
+
856
+ async function validateProjectRuleTemplates() {
857
+ const requiredFiles = [
858
+ 'claude-code/instructions/CLAUDE.template.md',
859
+ 'codex/instructions/AGENTS.template.md',
860
+ 'antigravity/instructions/WORKSPACE-RULES.template.md'
861
+ ];
862
+
863
+ for (const relPath of requiredFiles) {
864
+ const fullPath = path.join(rootDir, relPath);
865
+ if (!(await exists(fullPath))) {
866
+ fail(`[project-rules] 템플릿 누락: ${relPath}`);
867
+ continue;
868
+ }
869
+
870
+ const content = await fs.readFile(fullPath, 'utf8');
871
+ if (!content.trim()) {
872
+ fail(`[project-rules] 템플릿 비어 있음: ${relPath}`);
873
+ }
874
+ }
875
+ }
876
+
707
877
  async function runCliSmokeTests() {
708
878
  const nodeBin = process.execPath;
709
879
  const cliPath = path.join(rootDir, 'scripts', 'init.mjs');
@@ -802,6 +972,30 @@ async function runCliSmokeTests() {
802
972
  fail(`[cli] install --install-root dry-run 실행 실패: ${error.message}`);
803
973
  }
804
974
 
975
+ try {
976
+ await execFileAsync(
977
+ nodeBin,
978
+ [
979
+ cliPath,
980
+ 'install',
981
+ '--tool',
982
+ 'antigravity',
983
+ '--components',
984
+ 'skills',
985
+ '--project-rules',
986
+ 'if-instructions',
987
+ '--target',
988
+ '/tmp/tri-agent-manager-validate',
989
+ '--dry-run',
990
+ '--yes',
991
+ '--non-interactive'
992
+ ],
993
+ { cwd: rootDir }
994
+ );
995
+ } catch (error) {
996
+ fail(`[cli] install --project-rules dry-run 실행 실패: ${error.message}`);
997
+ }
998
+
805
999
  try {
806
1000
  await execFileAsync(
807
1001
  nodeBin,
@@ -870,15 +1064,20 @@ async function main() {
870
1064
  await validateCommonSources();
871
1065
  await validateCatalog();
872
1066
  await validateReadmes();
1067
+ await validateSettingsOutputs();
1068
+ await validateProjectRuleTemplates();
873
1069
 
1070
+ const commandFileBaseByTool = {};
874
1071
  for (const toolName of toolDirs) {
875
1072
  await validateSkillDirectory(toolName);
876
- const { commandIds } = await validateCommandCatalog(toolName);
1073
+ const { commandIds, commandFileBases } = await validateCommandCatalog(toolName);
1074
+ commandFileBaseByTool[toolName] = commandFileBases;
877
1075
  await validateWorkflowCatalog(toolName, commandIds);
878
1076
  }
879
1077
 
880
- await validateClaudeExtras();
881
- await validateAntigravityExtras();
1078
+ await validateClaudeExtras(commandFileBaseByTool['claude-code'] ?? new Set());
1079
+ await validateCodexExtras(commandFileBaseByTool.codex ?? new Set());
1080
+ await validateAntigravityExtras(commandFileBaseByTool.antigravity ?? new Set());
882
1081
  await runCliSmokeTests();
883
1082
 
884
1083
  if (errors.length > 0) {