persona-harness 0.3.0-alpha.0

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 (176) hide show
  1. package/.persona/harness.jsonc +9 -0
  2. package/.persona/rules/backend/gradle-bootstrap.md +27 -0
  3. package/.persona/rules/backend/java-backend-bootstrap.md +28 -0
  4. package/.persona/rules/backend/java-common.md +22 -0
  5. package/.persona/rules/backend/layered-architecture.md +19 -0
  6. package/.persona/rules/backend/package-structure.md +21 -0
  7. package/.persona/rules/backend/spring-controller.md +19 -0
  8. package/.persona/rules/backend/spring-dto.md +21 -0
  9. package/.persona/rules/backend/spring-entity.md +22 -0
  10. package/.persona/rules/backend/spring-repository.md +22 -0
  11. package/.persona/rules/backend/spring-service.md +23 -0
  12. package/.persona/rules/backend/spring-test.md +32 -0
  13. package/.persona/rules/backend/step1-api-contract.md +29 -0
  14. package/.persona/rules/backend/step2-3-api-contract.md +24 -0
  15. package/.persona/rules/backend/validation-exception.md +18 -0
  16. package/.persona/rules/clean-code/abstraction.md +18 -0
  17. package/.persona/rules/clean-code/common.md +21 -0
  18. package/.persona/rules/clean-code/method-design.md +20 -0
  19. package/.persona/rules/clean-code/naming.md +19 -0
  20. package/.persona/rules/clean-code/oop.md +18 -0
  21. package/.persona/rules/clean-code/testability.md +19 -0
  22. package/CHANGELOG.md +40 -0
  23. package/LICENSE +201 -0
  24. package/README.ja.md +95 -0
  25. package/README.ko.md +95 -0
  26. package/README.md +125 -0
  27. package/README.zh-cn.md +95 -0
  28. package/dist/cli/bearshell.d.ts +12 -0
  29. package/dist/cli/bearshell.js +189 -0
  30. package/dist/cli/bearshell.js.map +1 -0
  31. package/dist/cli/history.d.ts +15 -0
  32. package/dist/cli/history.js +156 -0
  33. package/dist/cli/history.js.map +1 -0
  34. package/dist/cli/index.d.ts +10 -0
  35. package/dist/cli/index.js +117 -0
  36. package/dist/cli/index.js.map +1 -0
  37. package/dist/cli/init.d.ts +21 -0
  38. package/dist/cli/init.js +194 -0
  39. package/dist/cli/init.js.map +1 -0
  40. package/dist/cli/intake-profile.d.ts +52 -0
  41. package/dist/cli/intake-profile.js +167 -0
  42. package/dist/cli/intake-profile.js.map +1 -0
  43. package/dist/cli/intake.d.ts +14 -0
  44. package/dist/cli/intake.js +209 -0
  45. package/dist/cli/intake.js.map +1 -0
  46. package/dist/cli/plan-command.d.ts +4 -0
  47. package/dist/cli/plan-command.js +130 -0
  48. package/dist/cli/plan-command.js.map +1 -0
  49. package/dist/cli/plan-status.d.ts +11 -0
  50. package/dist/cli/plan-status.js +41 -0
  51. package/dist/cli/plan-status.js.map +1 -0
  52. package/dist/cli/plan.d.ts +10 -0
  53. package/dist/cli/plan.js +199 -0
  54. package/dist/cli/plan.js.map +1 -0
  55. package/dist/cli/policy.d.ts +7 -0
  56. package/dist/cli/policy.js +139 -0
  57. package/dist/cli/policy.js.map +1 -0
  58. package/dist/cli/report-status.d.ts +13 -0
  59. package/dist/cli/report-status.js +40 -0
  60. package/dist/cli/report-status.js.map +1 -0
  61. package/dist/index.d.ts +5 -0
  62. package/dist/index.js +9 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/phase0/drift-detector.d.ts +24 -0
  65. package/dist/phase0/drift-detector.js +334 -0
  66. package/dist/phase0/drift-detector.js.map +1 -0
  67. package/dist/phase0/evidence.d.ts +9 -0
  68. package/dist/phase0/evidence.js +36 -0
  69. package/dist/phase0/evidence.js.map +1 -0
  70. package/dist/phase0/file-role.d.ts +5 -0
  71. package/dist/phase0/file-role.js +55 -0
  72. package/dist/phase0/file-role.js.map +1 -0
  73. package/dist/phase0/harness-config.d.ts +12 -0
  74. package/dist/phase0/harness-config.js +115 -0
  75. package/dist/phase0/harness-config.js.map +1 -0
  76. package/dist/phase0/hooks.d.ts +8 -0
  77. package/dist/phase0/hooks.js +127 -0
  78. package/dist/phase0/hooks.js.map +1 -0
  79. package/dist/phase0/injection.d.ts +2 -0
  80. package/dist/phase0/injection.js +77 -0
  81. package/dist/phase0/injection.js.map +1 -0
  82. package/dist/phase0/java-role-discovery.d.ts +6 -0
  83. package/dist/phase0/java-role-discovery.js +90 -0
  84. package/dist/phase0/java-role-discovery.js.map +1 -0
  85. package/dist/phase0/messages.d.ts +2 -0
  86. package/dist/phase0/messages.js +30 -0
  87. package/dist/phase0/messages.js.map +1 -0
  88. package/dist/phase0/policy-overlay.d.ts +12 -0
  89. package/dist/phase0/policy-overlay.js +171 -0
  90. package/dist/phase0/policy-overlay.js.map +1 -0
  91. package/dist/phase0/project-profile.d.ts +1 -0
  92. package/dist/phase0/project-profile.js +148 -0
  93. package/dist/phase0/project-profile.js.map +1 -0
  94. package/dist/phase0/rule-catalog.d.ts +14 -0
  95. package/dist/phase0/rule-catalog.js +77 -0
  96. package/dist/phase0/rule-catalog.js.map +1 -0
  97. package/dist/phase0/rule-diagnostics-report.d.ts +17 -0
  98. package/dist/phase0/rule-diagnostics-report.js +51 -0
  99. package/dist/phase0/rule-diagnostics-report.js.map +1 -0
  100. package/dist/phase0/rule-frontmatter-diagnostics.d.ts +19 -0
  101. package/dist/phase0/rule-frontmatter-diagnostics.js +65 -0
  102. package/dist/phase0/rule-frontmatter-diagnostics.js.map +1 -0
  103. package/dist/phase0/rule-frontmatter.d.ts +23 -0
  104. package/dist/phase0/rule-frontmatter.js +172 -0
  105. package/dist/phase0/rule-frontmatter.js.map +1 -0
  106. package/dist/phase0/rule-glob.d.ts +2 -0
  107. package/dist/phase0/rule-glob.js +38 -0
  108. package/dist/phase0/rule-glob.js.map +1 -0
  109. package/dist/phase0/rule-loader.d.ts +13 -0
  110. package/dist/phase0/rule-loader.js +143 -0
  111. package/dist/phase0/rule-loader.js.map +1 -0
  112. package/dist/phase0/shared-skill-router.d.ts +14 -0
  113. package/dist/phase0/shared-skill-router.js +85 -0
  114. package/dist/phase0/shared-skill-router.js.map +1 -0
  115. package/dist/phase0/store.d.ts +6 -0
  116. package/dist/phase0/store.js +14 -0
  117. package/dist/phase0/store.js.map +1 -0
  118. package/dist/phase0/target-file.d.ts +2 -0
  119. package/dist/phase0/target-file.js +41 -0
  120. package/dist/phase0/target-file.js.map +1 -0
  121. package/dist/phase0/types.d.ts +38 -0
  122. package/dist/phase0/types.js +2 -0
  123. package/dist/phase0/types.js.map +1 -0
  124. package/dist/phase1/observer/controller-repository-observer.d.ts +17 -0
  125. package/dist/phase1/observer/controller-repository-observer.js +210 -0
  126. package/dist/phase1/observer/controller-repository-observer.js.map +1 -0
  127. package/dist/phase1/observer/controller-sql-observer.d.ts +20 -0
  128. package/dist/phase1/observer/controller-sql-observer.js +148 -0
  129. package/dist/phase1/observer/controller-sql-observer.js.map +1 -0
  130. package/dist/phase1/observer/java-source.d.ts +9 -0
  131. package/dist/phase1/observer/java-source.js +88 -0
  132. package/dist/phase1/observer/java-source.js.map +1 -0
  133. package/dist/phase1/observer/report.d.ts +52 -0
  134. package/dist/phase1/observer/report.js +173 -0
  135. package/dist/phase1/observer/report.js.map +1 -0
  136. package/dist/phase1/observer/service-storage-observer.d.ts +20 -0
  137. package/dist/phase1/observer/service-storage-observer.js +155 -0
  138. package/dist/phase1/observer/service-storage-observer.js.map +1 -0
  139. package/dist/phase1/observer/test-contract-anchor-matchers.d.ts +10 -0
  140. package/dist/phase1/observer/test-contract-anchor-matchers.js +198 -0
  141. package/dist/phase1/observer/test-contract-anchor-matchers.js.map +1 -0
  142. package/dist/phase1/observer/test-contract-observer.d.ts +21 -0
  143. package/dist/phase1/observer/test-contract-observer.js +70 -0
  144. package/dist/phase1/observer/test-contract-observer.js.map +1 -0
  145. package/docs/README.md +34 -0
  146. package/docs/current/README.md +35 -0
  147. package/docs/current/java-backend-mvp-install-guide.md +160 -0
  148. package/docs/current/persona-harness-detailed-usage.md +782 -0
  149. package/docs/current/release/README.md +6 -0
  150. package/docs/current/release/release-checklist.md +113 -0
  151. package/docs/current/release/release-notes-template.md +68 -0
  152. package/docs/current/v0.3.0-alpha-publish-readiness.md +185 -0
  153. package/docs/current/v0.3.0-external-tester-feedback-template.md +214 -0
  154. package/docs/current/v0.3.0-external-tester-guide.md +217 -0
  155. package/docs/current/v0.3.0-gradle-spring-build-guidance.md +100 -0
  156. package/package.json +87 -0
  157. package/packages/shared-skills/skills/programming/SKILL.md +490 -0
  158. package/packages/shared-skills/skills/programming/references/java/README.md +193 -0
  159. package/packages/shared-skills/skills/programming/references/java/anti-patterns.md +85 -0
  160. package/packages/shared-skills/skills/programming/references/java/application-layer.md +200 -0
  161. package/packages/shared-skills/skills/programming/references/java/architecture.md +152 -0
  162. package/packages/shared-skills/skills/programming/references/java/backend.md +152 -0
  163. package/packages/shared-skills/skills/programming/references/java/code-quality-refactoring.md +146 -0
  164. package/packages/shared-skills/skills/programming/references/java/concurrency-discipline.md +98 -0
  165. package/packages/shared-skills/skills/programming/references/java/domain-model.md +214 -0
  166. package/packages/shared-skills/skills/programming/references/java/error-handling.md +179 -0
  167. package/packages/shared-skills/skills/programming/references/java/foundations.md +49 -0
  168. package/packages/shared-skills/skills/programming/references/java/java-idioms.md +108 -0
  169. package/packages/shared-skills/skills/programming/references/java/language-core.md +96 -0
  170. package/packages/shared-skills/skills/programming/references/java/method-and-naming.md +164 -0
  171. package/packages/shared-skills/skills/programming/references/java/object-collaboration.md +140 -0
  172. package/packages/shared-skills/skills/programming/references/java/performance-discipline.md +115 -0
  173. package/packages/shared-skills/skills/programming/references/java/repository-pattern.md +181 -0
  174. package/packages/shared-skills/skills/programming/references/java/technology-seams.md +92 -0
  175. package/packages/shared-skills/skills/programming/references/java/test-design.md +149 -0
  176. package/packages/shared-skills/skills/programming/references/java/testing.md +188 -0
@@ -0,0 +1,115 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { isAbsolute, join } from "node:path";
3
+ const DEFAULT_CONFIG = {
4
+ enabled: true,
5
+ rulesDir: ".persona/rules",
6
+ evidenceDir: ".persona/evidence",
7
+ maxRulesPerInjection: 12,
8
+ evidenceMode: "metadata_only",
9
+ enabledDomains: ["backend", "frontend", "infra", "programming"],
10
+ scenario: "step1",
11
+ };
12
+ function stripJsonComments(input) {
13
+ let output = "";
14
+ let index = 0;
15
+ let inString = false;
16
+ let escaped = false;
17
+ while (index < input.length) {
18
+ const current = input[index];
19
+ const next = input[index + 1];
20
+ if (inString) {
21
+ output += current;
22
+ if (escaped) {
23
+ escaped = false;
24
+ }
25
+ else if (current === "\\") {
26
+ escaped = true;
27
+ }
28
+ else if (current === "\"") {
29
+ inString = false;
30
+ }
31
+ index += 1;
32
+ continue;
33
+ }
34
+ if (current === "\"") {
35
+ inString = true;
36
+ output += current;
37
+ index += 1;
38
+ continue;
39
+ }
40
+ if (current === "/" && next === "/") {
41
+ while (index < input.length && input[index] !== "\n") {
42
+ index += 1;
43
+ }
44
+ continue;
45
+ }
46
+ if (current === "/" && next === "*") {
47
+ index += 2;
48
+ while (index < input.length && !(input[index] === "*" && input[index + 1] === "/")) {
49
+ index += 1;
50
+ }
51
+ index += 2;
52
+ continue;
53
+ }
54
+ output += current;
55
+ index += 1;
56
+ }
57
+ return output;
58
+ }
59
+ function isRecord(value) {
60
+ return typeof value === "object" && value !== null && !Array.isArray(value);
61
+ }
62
+ function readBoolean(value, fallback) {
63
+ return typeof value === "boolean" ? value : fallback;
64
+ }
65
+ function readString(value, fallback) {
66
+ return typeof value === "string" && value.trim() !== "" ? value : fallback;
67
+ }
68
+ function readPositiveInteger(value, fallback) {
69
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : fallback;
70
+ }
71
+ function readStringArray(value, fallback) {
72
+ if (!Array.isArray(value)) {
73
+ return fallback;
74
+ }
75
+ const strings = value.filter((item) => typeof item === "string" && item.trim() !== "");
76
+ return strings.length > 0 ? strings : fallback;
77
+ }
78
+ function readScenario(value, fallback) {
79
+ return value === "step2-3" ? "step2-3" : fallback;
80
+ }
81
+ function readEvidenceMode(value) {
82
+ return value === "metadata_only" ? "metadata_only" : DEFAULT_CONFIG.evidenceMode;
83
+ }
84
+ export function resolveConfiguredPath(projectDir, configuredPath) {
85
+ return isAbsolute(configuredPath) ? configuredPath : join(projectDir, configuredPath);
86
+ }
87
+ export function loadHarnessConfig(projectDir) {
88
+ const harnessPath = join(projectDir, ".persona", "harness.jsonc");
89
+ if (!existsSync(harnessPath)) {
90
+ return DEFAULT_CONFIG;
91
+ }
92
+ let parsed;
93
+ try {
94
+ parsed = JSON.parse(stripJsonComments(readFileSync(harnessPath, "utf8")));
95
+ }
96
+ catch (error) {
97
+ if (error instanceof SyntaxError) {
98
+ return DEFAULT_CONFIG;
99
+ }
100
+ throw error;
101
+ }
102
+ if (!isRecord(parsed)) {
103
+ return DEFAULT_CONFIG;
104
+ }
105
+ return {
106
+ enabled: readBoolean(parsed.enabled, DEFAULT_CONFIG.enabled),
107
+ rulesDir: readString(parsed.rulesDir, DEFAULT_CONFIG.rulesDir),
108
+ evidenceDir: readString(parsed.evidenceDir, DEFAULT_CONFIG.evidenceDir),
109
+ maxRulesPerInjection: readPositiveInteger(parsed.maxRulesPerInjection, DEFAULT_CONFIG.maxRulesPerInjection),
110
+ evidenceMode: readEvidenceMode(parsed.evidenceMode),
111
+ enabledDomains: readStringArray(parsed.enabledDomains, DEFAULT_CONFIG.enabledDomains),
112
+ scenario: readScenario(parsed.scenario, DEFAULT_CONFIG.scenario),
113
+ };
114
+ }
115
+ //# sourceMappingURL=harness-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-config.js","sourceRoot":"","sources":["../../src/phase0/harness-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Hooks } from "@opencode-ai/plugin";
2
+ import { PendingInjectionStore } from "./store.js";
3
+ type Phase0HookOptions = {
4
+ projectDir?: string;
5
+ store?: PendingInjectionStore;
6
+ };
7
+ export declare function createPhase0Hooks(options?: Phase0HookOptions): Hooks;
8
+ export {};
@@ -0,0 +1,127 @@
1
+ import { writePhase0Evidence } from "./evidence.js";
2
+ import { isBackendBootstrapTargetFile, isJavaTargetFile } from "./file-role.js";
3
+ import { loadHarnessConfig } from "./harness-config.js";
4
+ import { createInjectionBlock } from "./injection.js";
5
+ import { createJavaRoleReadFollowUp, discoverJavaRoleInjections, formatJavaRoleDiscoveryBlock, } from "./java-role-discovery.js";
6
+ import { injectIntoLatestUserMessage } from "./messages.js";
7
+ import { PendingInjectionStore } from "./store.js";
8
+ import { extractTargetFile, isInstalledPersonaHarnessPackageFile } from "./target-file.js";
9
+ import { selectSharedSkillsForTarget } from "./shared-skill-router.js";
10
+ function appendInjectionToToolOutput(output, block) {
11
+ if (typeof output.output !== "string" || output.output.includes("[Persona Harness Injection]")) {
12
+ return;
13
+ }
14
+ output.output = `${output.output}\n\n---\n\n${block}`;
15
+ }
16
+ function appendJavaRoleDiscoveryToToolOutput(output, block) {
17
+ if (typeof output.output !== "string" || output.output.includes("[Persona Harness Java Role Discovery]")) {
18
+ return;
19
+ }
20
+ output.output = `${output.output}\n\n---\n\n${block}`;
21
+ }
22
+ function hasEnabledSharedSkillDomain(enabledDomains, targetFile) {
23
+ return selectSharedSkillsForTarget(targetFile).some((skill) => enabledDomains.includes(skill.domain));
24
+ }
25
+ export function createPhase0Hooks(options = {}) {
26
+ const store = options.store ?? new PendingInjectionStore();
27
+ const projectDir = options.projectDir ?? process.cwd();
28
+ const config = loadHarnessConfig(projectDir);
29
+ function captureTargetFile(hook, tool, sessionID, callID, args) {
30
+ if (!config.enabled) {
31
+ return undefined;
32
+ }
33
+ const targetFile = extractTargetFile(tool, args);
34
+ if (!targetFile) {
35
+ return undefined;
36
+ }
37
+ if (isInstalledPersonaHarnessPackageFile(targetFile)) {
38
+ return undefined;
39
+ }
40
+ const canInjectBackend = (isJavaTargetFile(targetFile) || isBackendBootstrapTargetFile(targetFile)) &&
41
+ config.enabledDomains.includes("backend");
42
+ const canInjectSharedSkill = hasEnabledSharedSkillDomain(config.enabledDomains, targetFile);
43
+ if (!canInjectBackend && !canInjectSharedSkill) {
44
+ return undefined;
45
+ }
46
+ const injection = createInjectionBlock(targetFile, projectDir);
47
+ store.set(sessionID, injection);
48
+ writePhase0Evidence(projectDir, {
49
+ hook,
50
+ sessionID,
51
+ callID,
52
+ injectedInto: "pending-store",
53
+ injection,
54
+ });
55
+ return injection;
56
+ }
57
+ function captureJavaRoleDiscovery(input, output) {
58
+ if (!config.enabled || typeof output.output !== "string" || !config.enabledDomains.includes("backend")) {
59
+ return;
60
+ }
61
+ const injections = discoverJavaRoleInjections(input.tool, output.output, projectDir);
62
+ if (injections.length === 0) {
63
+ return;
64
+ }
65
+ appendJavaRoleDiscoveryToToolOutput(output, formatJavaRoleDiscoveryBlock(injections));
66
+ const followUp = createJavaRoleReadFollowUp(injections);
67
+ if (followUp) {
68
+ store.set(input.sessionID, followUp);
69
+ writePhase0Evidence(projectDir, {
70
+ hook: "tool.execute.after",
71
+ sessionID: input.sessionID,
72
+ callID: input.callID,
73
+ injectedInto: "pending-store",
74
+ injection: followUp,
75
+ });
76
+ }
77
+ for (const injection of injections) {
78
+ writePhase0Evidence(projectDir, {
79
+ hook: "tool.execute.after",
80
+ sessionID: input.sessionID,
81
+ callID: input.callID,
82
+ injectedInto: "role-discovery",
83
+ injection,
84
+ });
85
+ }
86
+ }
87
+ return {
88
+ "tool.execute.before": async (input, output) => {
89
+ captureTargetFile("tool.execute.before", input.tool, input.sessionID, input.callID, output.args);
90
+ },
91
+ "tool.execute.after": async (input, output) => {
92
+ captureJavaRoleDiscovery(input, output);
93
+ const injection = captureTargetFile("tool.execute.after", input.tool, input.sessionID, input.callID, input.args);
94
+ if (!injection) {
95
+ return;
96
+ }
97
+ appendInjectionToToolOutput(output, injection.block);
98
+ writePhase0Evidence(projectDir, {
99
+ hook: "tool.execute.after",
100
+ sessionID: input.sessionID,
101
+ callID: input.callID,
102
+ injectedInto: "tool-output",
103
+ injection,
104
+ });
105
+ },
106
+ "experimental.chat.messages.transform": async (_input, output) => {
107
+ const latestUserMessage = [...output.messages].reverse().find((message) => message.info.role === "user");
108
+ const sessionId = latestUserMessage?.info.sessionID;
109
+ if (!sessionId) {
110
+ return;
111
+ }
112
+ const injection = store.take(sessionId);
113
+ if (!injection) {
114
+ return;
115
+ }
116
+ if (injectIntoLatestUserMessage(output, injection)) {
117
+ writePhase0Evidence(projectDir, {
118
+ hook: "experimental.chat.messages.transform",
119
+ sessionID: sessionId,
120
+ injectedInto: "model-input",
121
+ injection,
122
+ });
123
+ }
124
+ },
125
+ };
126
+ }
127
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/phase0/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { PendingInjection } from "./types.js";
2
+ export declare function createInjectionBlock(targetFile: string, projectDir?: string): PendingInjection;
@@ -0,0 +1,77 @@
1
+ import { isBackendBootstrapTargetFile, resolveBootstrapFileRole, resolveFileRole } from "./file-role.js";
2
+ import { loadHarnessConfig } from "./harness-config.js";
3
+ import { loadBackendPolicyOverlay } from "./policy-overlay.js";
4
+ import { loadBackendProjectProfileSummary } from "./project-profile.js";
5
+ import { loadRulesForRole } from "./rule-loader.js";
6
+ import { resolveSharedSkillFileRole, selectSharedSkillsForTarget } from "./shared-skill-router.js";
7
+ import { isJavaTargetFile } from "./file-role.js";
8
+ const inactivePolicyOverlay = {
9
+ enabled: false,
10
+ sources: [],
11
+ diagnostics: [],
12
+ };
13
+ function dedupePolicies(policies) {
14
+ return Array.from(new Set(policies));
15
+ }
16
+ export function createInjectionBlock(targetFile, projectDir = process.cwd()) {
17
+ const config = loadHarnessConfig(projectDir);
18
+ const selectedSharedSkills = selectSharedSkillsForTarget(targetFile);
19
+ const isJavaTarget = isJavaTargetFile(targetFile);
20
+ const isBootstrapTarget = isBackendBootstrapTargetFile(targetFile);
21
+ const fileRole = isJavaTarget
22
+ ? resolveFileRole(targetFile)
23
+ : isBootstrapTarget
24
+ ? resolveBootstrapFileRole(targetFile)
25
+ : resolveSharedSkillFileRole(selectedSharedSkills, targetFile);
26
+ const shouldLoadJavaRules = isJavaTarget || isBootstrapTarget || fileRole === "java-common";
27
+ const ruleTargetFile = shouldLoadJavaRules ? targetFile : undefined;
28
+ const loadedRules = shouldLoadJavaRules ? loadRulesForRole(projectDir, fileRole, ruleTargetFile) : [];
29
+ const projectProfileSummary = shouldLoadJavaRules ? loadBackendProjectProfileSummary(projectDir) : [];
30
+ const policyOverlay = shouldLoadJavaRules
31
+ ? loadBackendPolicyOverlay(projectDir)
32
+ : { summaryLines: [], metadata: inactivePolicyOverlay };
33
+ const selectedRules = loadedRules.map((rule) => rule.path);
34
+ const selectedRuleMetadata = loadedRules.map((rule) => ({
35
+ path: rule.path,
36
+ id: rule.metadata.id,
37
+ source: rule.metadata.source,
38
+ domain: rule.metadata.domain,
39
+ topic: rule.metadata.topic,
40
+ severity: rule.metadata.severity,
41
+ }));
42
+ const policies = dedupePolicies(loadedRules.flatMap((rule) => rule.policies)).slice(0, config.maxRulesPerInjection);
43
+ const block = [
44
+ "[Persona Harness Injection]",
45
+ "",
46
+ `현재 파일: ${targetFile}`,
47
+ `파일 역할: ${fileRole}`,
48
+ "",
49
+ ...(projectProfileSummary.length > 0 ? [...projectProfileSummary, ""] : []),
50
+ ...(policyOverlay.summaryLines.length > 0 ? [...policyOverlay.summaryLines, ""] : []),
51
+ "선택 규칙:",
52
+ ...selectedRules.map((rule) => `- ${rule}`),
53
+ "",
54
+ "선택 스킬:",
55
+ ...(selectedSharedSkills.length > 0
56
+ ? selectedSharedSkills.map((skill) => `- ${skill.name} (${skill.domain}): ${skill.path} — ${skill.reason}`)
57
+ : ["- 없음"]),
58
+ "",
59
+ "적용 정책:",
60
+ ...policies.map((policy) => `- ${policy}`),
61
+ "",
62
+ "주의:",
63
+ "이 Phase 0 블록은 .persona/rules 정본과 최소 frontmatter/glob/scenario catalog layer를 읽는 MVP rule-loader 결과이며, 아직 full rule engine은 아니다.",
64
+ "repo inspection, CLI smoke test, 큰 출력 확인은 `ph bearshell`을 우선 사용한다.",
65
+ ].join("\n");
66
+ return {
67
+ targetFile,
68
+ fileRole,
69
+ selectedRules,
70
+ selectedRuleMetadata,
71
+ selectedSharedSkills,
72
+ selectedPolicyOverlay: policyOverlay.metadata,
73
+ policies,
74
+ block,
75
+ };
76
+ }
77
+ //# sourceMappingURL=injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.js","sourceRoot":"","sources":["../../src/phase0/injection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { PendingInjection } from "./types.js";
2
+ export declare function isJavaRoleDiscoveryTool(toolName: string): boolean;
3
+ export declare function extractJavaTargetFilesFromText(source: string): readonly string[];
4
+ export declare function discoverJavaRoleInjections(toolName: string, toolOutput: string, projectDir: string): readonly PendingInjection[];
5
+ export declare function formatJavaRoleDiscoveryBlock(injections: readonly PendingInjection[]): string;
6
+ export declare function createJavaRoleReadFollowUp(injections: readonly PendingInjection[]): PendingInjection | undefined;
@@ -0,0 +1,90 @@
1
+ import { isJavaTargetFile } from "./file-role.js";
2
+ import { createInjectionBlock } from "./injection.js";
3
+ import { isInstalledPersonaHarnessPackageFile } from "./target-file.js";
4
+ const JAVA_PATH_PATTERN = /(?:[A-Za-z]:)?(?:\/|\.{1,2}\/)?[^\s"'`<>|]*src\/(?:main|test)\/java\/[^\s"'`<>|]+?\.java\b/g;
5
+ const DISCOVERY_TOOL_NAMES = new Set(["glob", "ls", "list", "find"]);
6
+ export function isJavaRoleDiscoveryTool(toolName) {
7
+ const normalizedToolName = toolName.toLowerCase();
8
+ return DISCOVERY_TOOL_NAMES.has(normalizedToolName) || normalizedToolName.includes("glob");
9
+ }
10
+ export function extractJavaTargetFilesFromText(source) {
11
+ const matches = [];
12
+ for (const match of source.matchAll(JAVA_PATH_PATTERN)) {
13
+ const targetFile = match[0]?.replace(/[),.;:\]]+$/g, "");
14
+ if (targetFile && isJavaTargetFile(targetFile) && !isInstalledPersonaHarnessPackageFile(targetFile)) {
15
+ matches.push(targetFile);
16
+ }
17
+ }
18
+ return [...new Set(matches)];
19
+ }
20
+ export function discoverJavaRoleInjections(toolName, toolOutput, projectDir) {
21
+ if (!isJavaRoleDiscoveryTool(toolName)) {
22
+ return [];
23
+ }
24
+ return extractJavaTargetFilesFromText(toolOutput).map((targetFile) => createInjectionBlock(targetFile, projectDir));
25
+ }
26
+ function uniqueValues(values) {
27
+ return [...new Set(values)];
28
+ }
29
+ function uniqueRuleMetadata(injections) {
30
+ const metadataByKey = new Map();
31
+ for (const injection of injections) {
32
+ for (const metadata of injection.selectedRuleMetadata) {
33
+ metadataByKey.set(`${metadata.path}:${metadata.id}`, metadata);
34
+ }
35
+ }
36
+ return [...metadataByKey.values()];
37
+ }
38
+ function uniqueSharedSkills(injections) {
39
+ const skillsByKey = new Map();
40
+ for (const injection of injections) {
41
+ for (const skill of injection.selectedSharedSkills) {
42
+ skillsByKey.set(`${skill.domain}:${skill.name}:${skill.path}`, skill);
43
+ }
44
+ }
45
+ return [...skillsByKey.values()];
46
+ }
47
+ export function formatJavaRoleDiscoveryBlock(injections) {
48
+ const roleLines = injections.map((injection) => `- ${injection.fileRole}: ${injection.targetFile}`);
49
+ return [
50
+ "[Persona Harness Java Role Discovery]",
51
+ "",
52
+ "발견된 Java 역할 파일:",
53
+ ...roleLines,
54
+ "",
55
+ "다음 단계:",
56
+ "- Controller, Service, Repository, Request DTO, Response DTO 역할 파일을 read 도구로 최소 1개씩 열어 역할별 rule injection을 실제 model input에 태운다.",
57
+ ].join("\n");
58
+ }
59
+ export function createJavaRoleReadFollowUp(injections) {
60
+ if (injections.length === 0) {
61
+ return undefined;
62
+ }
63
+ const readLines = injections.map((injection) => `- read ${injection.targetFile} (${injection.fileRole})`);
64
+ return {
65
+ targetFile: "<java-role-read-follow-up>",
66
+ fileRole: "java-common",
67
+ selectedRules: uniqueValues(injections.flatMap((injection) => injection.selectedRules)),
68
+ selectedRuleMetadata: uniqueRuleMetadata(injections),
69
+ selectedSharedSkills: uniqueSharedSkills(injections),
70
+ selectedPolicyOverlay: {
71
+ enabled: false,
72
+ sources: [],
73
+ diagnostics: [],
74
+ },
75
+ policies: [
76
+ "Discovered Java role files must be read so role-specific rule injection reaches model input before further edits.",
77
+ ],
78
+ block: [
79
+ "[Persona Harness Injection]",
80
+ "",
81
+ "[Persona Harness Java Role Read Follow-up]",
82
+ "",
83
+ "발견된 Java 역할 파일을 다음 수정 전에 read 도구로 연다.",
84
+ "이 단계는 Controller/Service/Repository/Request DTO/Response DTO 등 역할별 rule injection을 실제 model input에 태운다.",
85
+ "",
86
+ ...readLines,
87
+ ].join("\n"),
88
+ };
89
+ }
90
+ //# sourceMappingURL=java-role-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"java-role-discovery.js","sourceRoot":"","sources":["../../src/phase0/java-role-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { PendingInjection, TransformMessagesOutput } from "./types.js";
2
+ export declare function injectIntoLatestUserMessage(output: TransformMessagesOutput, injection: PendingInjection): boolean;
@@ -0,0 +1,30 @@
1
+ function isTextPart(part) {
2
+ return part.type === "text" && typeof part.text === "string";
3
+ }
4
+ export function injectIntoLatestUserMessage(output, injection) {
5
+ for (let messageIndex = output.messages.length - 1; messageIndex >= 0; messageIndex -= 1) {
6
+ const message = output.messages[messageIndex];
7
+ if (message?.info?.role !== "user") {
8
+ continue;
9
+ }
10
+ const textPart = message.parts.find(isTextPart);
11
+ if (textPart) {
12
+ if (textPart.text.includes("[Persona Harness Injection]")) {
13
+ return false;
14
+ }
15
+ textPart.text = `${injection.block}\n\n---\n\n${textPart.text}`;
16
+ return true;
17
+ }
18
+ message.parts.unshift({
19
+ id: "persona-harness-injection",
20
+ sessionID: message.info.sessionID,
21
+ messageID: message.info.id,
22
+ type: "text",
23
+ text: injection.block,
24
+ synthetic: true,
25
+ });
26
+ return true;
27
+ }
28
+ return false;
29
+ }
30
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/phase0/messages.ts"],"names":[],"mappings":"AAIA,SAAS,UAAU,CAAC,IAAU;IAC5B,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,MAA+B,EAC/B,SAA2B;IAE3B,KAAK,IAAI,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,YAAY,IAAI,CAAC,EAAE,YAAY,IAAI,CAAC,EAAE,CAAC;QACzF,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QAC7C,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;YACnC,SAAQ;QACV,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC/C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,CAAC;gBAC1D,OAAO,KAAK,CAAA;YACd,CAAC;YACD,QAAQ,CAAC,IAAI,GAAG,GAAG,SAAS,CAAC,KAAK,cAAc,QAAQ,CAAC,IAAI,EAAE,CAAA;YAC/D,OAAO,IAAI,CAAA;QACb,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YACpB,EAAE,EAAE,2BAA2B;YAC/B,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS;YACjC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;YAC1B,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,SAAS,CAAC,KAAK;YACrB,SAAS,EAAE,IAAI;SAChB,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ type PolicySourceName = "company" | "personal";
2
+ export type SelectedPolicyOverlay = {
3
+ readonly enabled: boolean;
4
+ readonly sources: readonly PolicySourceName[];
5
+ readonly diagnostics: readonly string[];
6
+ };
7
+ export type BackendPolicyOverlay = {
8
+ readonly summaryLines: readonly string[];
9
+ readonly metadata: SelectedPolicyOverlay;
10
+ };
11
+ export declare function loadBackendPolicyOverlay(projectDir: string): BackendPolicyOverlay;
12
+ export {};