guardian-framework 0.1.103 → 0.1.105

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.
package/dist/cli.js CHANGED
@@ -3197,7 +3197,7 @@ __export(exports_package, {
3197
3197
  bin: () => bin,
3198
3198
  author: () => author
3199
3199
  });
3200
- var name = "guardian-framework", version = "0.1.103", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
3200
+ var name = "guardian-framework", version = "0.1.105", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
3201
3201
  var init_package = __esm(() => {
3202
3202
  exports = {
3203
3203
  ".": {
package/dist/exports.js CHANGED
@@ -1982,7 +1982,7 @@ __export(exports_package, {
1982
1982
  bin: () => bin,
1983
1983
  author: () => author
1984
1984
  });
1985
- var name = "guardian-framework", version = "0.1.103", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1985
+ var name = "guardian-framework", version = "0.1.105", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
1986
1986
  var init_package = __esm(() => {
1987
1987
  exports = {
1988
1988
  ".": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guardian-framework",
3
- "version": "0.1.103",
3
+ "version": "0.1.105",
4
4
  "description": "Token-optimized agentic framework scaffolder with pi-first architecture",
5
5
  "type": "module",
6
6
  "main": "dist/exports.js",
@@ -121,15 +121,57 @@ function buildInScope(comp: ModuleComponent, primaryAcRows: AcRow[], implSteps:
121
121
  ];
122
122
  }
123
123
 
124
- /** Detect whether project at `cwd` is a Java project. */
125
- function isJavaProject(cwd?: string): boolean {
126
- if (!cwd) return false;
124
+ /** Supported project languages. */
125
+ export type ProjectLanguage = "typescript" | "java" | "python" | "go" | "rust";
126
+
127
+ /** Detect project language at `cwd` by checking for build files. */
128
+ export function detectLanguage(cwd?: string): ProjectLanguage {
129
+ if (!cwd) return "typescript";
127
130
  try {
128
- return existsSync(join(cwd, "pom.xml")) ||
129
- existsSync(join(cwd, "build.gradle")) ||
130
- existsSync(join(cwd, "build.gradle.kts"));
131
+ if (existsSync(join(cwd, "pom.xml")) || existsSync(join(cwd, "build.gradle")) || existsSync(join(cwd, "build.gradle.kts")))
132
+ return "java";
133
+ if (existsSync(join(cwd, "go.mod")))
134
+ return "go";
135
+ if (existsSync(join(cwd, "Cargo.toml")))
136
+ return "rust";
137
+ if (existsSync(join(cwd, "pyproject.toml")) || existsSync(join(cwd, "setup.py")) || existsSync(join(cwd, "requirements.txt")))
138
+ return "python";
139
+ return "typescript";
131
140
  } catch {
132
- return false;
141
+ return "typescript";
142
+ }
143
+ }
144
+
145
+ /** Language-specific file extension for implementation files. */
146
+ export function implExtension(lang: ProjectLanguage): string {
147
+ switch (lang) {
148
+ case "java": return "java";
149
+ case "python": return "py";
150
+ case "go": return "go";
151
+ case "rust": return "rs";
152
+ default: return "ts";
153
+ }
154
+ }
155
+
156
+ /** Language-specific test directory base. */
157
+ export function testBaseDirFromLang(lang: ProjectLanguage): string {
158
+ switch (lang) {
159
+ case "java": return "src/test/java";
160
+ case "python": return "tests";
161
+ case "go": return "tests";
162
+ case "rust": return "tests";
163
+ default: return "tests/unit";
164
+ }
165
+ }
166
+
167
+ /** Language-specific test runner command hint. */
168
+ export function testRunnerHintFromLang(lang: ProjectLanguage): string {
169
+ switch (lang) {
170
+ case "java": return "mvn test";
171
+ case "python": return "pytest";
172
+ case "go": return "go test ./...";
173
+ case "rust": return "cargo test";
174
+ default: return "bun test";
133
175
  }
134
176
  }
135
177
 
@@ -156,9 +198,10 @@ export function generateIssueMarkdown(
156
198
  const inScope = buildInScope(comp, compAcs, implSteps, moduleId);
157
199
 
158
200
  // Language-aware test paths
159
- const isJava = isJavaProject(cwd);
160
- const testBaseDir = isJava ? "src/test/java" : "tests/unit";
161
- const testRunnerHint = isJava ? "mvn test" : "bun test";
201
+ const lang = detectLanguage(cwd);
202
+ const ext = implExtension(lang);
203
+ const testBaseDir = testBaseDirFromLang(lang);
204
+ const testRunnerHint = testRunnerHintFromLang(lang);
162
205
 
163
206
  const testLine = tdd
164
207
  ? ` - "update: ${testBaseDir}/ (failing tests already generated — make them pass)"`
@@ -252,7 +295,7 @@ ${yamlAcs}
252
295
  All Acceptance Criteria in that file must be satisfied before this issue is closed.
253
296
  Component focus: ${comp.name}.
254
297
  CONCRETE IMPLEMENTATIONS MUST BE CREATED — interface stubs from the contract freeze
255
- are not sufficient. Each domain service/aggregate needs a concrete .impl.${isJava ? "java" : "ts"} file.
298
+ are not sufficient. Each domain service/aggregate needs a concrete .impl.${ext} file.
256
299
 
257
300
  file_changes:
258
301
  - "create: src/${moduleId}/domain/"
@@ -307,7 +350,7 @@ ${stepsMarkdown}
307
350
  > **Agent instructions:**
308
351
  > 1. Open \`.pi/architecture/modules/${slice.module}.md\` — read the full Acceptance Criteria table
309
352
  > 2. Identify which rows are your responsibility for **${comp.name}**
310
- > 3. Create concrete implementation files (\`.impl.${isJava ? "java" : "ts"}\`) in \`src/${moduleId}/\` — the interface stubs from the contract freeze are NOT enough
353
+ > 3. Create concrete implementation files (\`.impl.${ext}\`) in \`src/${moduleId}/\` — the interface stubs from the contract freeze are NOT enough
311
354
  > 4. Each domain aggregate/service must have a working implementation with business logic
312
355
  > 5. Verify each AC row is satisfied in \`src/\` before marking done
313
356
  > 6. Run validators and create MR
@@ -81,7 +81,7 @@ export interface TddGenerateOptions {
81
81
  cwd: string;
82
82
  /** Language from manifest (default: "typescript") */
83
83
  language: string;
84
- /** Base test directory (default: "tests/unit") */
84
+ /** Base test directory (auto-detected from project language if not set) */
85
85
  testBaseDir?: string;
86
86
  /** Module name for path construction */
87
87
  moduleName?: string;
@@ -34,6 +34,10 @@ import {
34
34
  generateContractFreezeMarkdown,
35
35
  generateIssueMarkdown,
36
36
  generateProofingMarkdown,
37
+ detectLanguage,
38
+ testBaseDirFromLang,
39
+ testRunnerHintFromLang,
40
+ implExtension,
37
41
  } from "./architect-lib/generators";
38
42
  import {
39
43
  generateEpicTestFiles,
@@ -870,7 +874,7 @@ export default function (pi: ExtensionAPI) {
870
874
  "",
871
875
  "**TDD Mode: ON**",
872
876
  "- Failing test files were generated from architecture contracts before issues were created.",
873
- "- Start each component by examining its test file in the `tests/unit/` directory.",
877
+ "- Start each component by examining its test file in the `" + testBaseDirFromLang(detectLanguage(ctx.cwd)) + "/` directory.",
874
878
  "- Run tests first to see them fail, then implement to make them pass (Red→Green→Refactor).",
875
879
  "- Tests are living artifacts — evolve them as the component grows.",
876
880
  "- Reference `.pi/skills/tdd-practice.md` for TDD guidance.",
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-07-20T12:41:24Z",
2
+ "timestamp": "2026-07-20T16:02:31Z",
3
3
  "mode": "all",
4
4
  "stages_run": [],
5
5
  "summary": {
@@ -6,7 +6,9 @@ description: TDD practice guide for Guardian implementation agents. Use when TDD
6
6
  # TDD Practice — Red → Green → Refactor
7
7
 
8
8
  > This skill applies when TDD mode is enabled on the current epic (`--tdd`).
9
- > Pre-generated failing test files exist in `tests/unit/<module>/<component>/`.
9
+ > Pre-generated failing test files exist in the project's test directory
10
+ > (language-specific: `tests/unit/` for TypeScript, `src/test/java/` for Java,
11
+ > `tests/` for Python/Go/Rust).
10
12
  > These tests were generated deterministically from architecture contracts — no LLM involvement.
11
13
 
12
14
  ## Core Principle
@@ -24,8 +26,14 @@ Do NOT treat the generated tests as rigid specs you must match exactly. Treat th
24
26
 
25
27
  ### 1. Red — See the test fail
26
28
 
27
- ```
28
- bun test tests/unit/<module>/<component>/<component>.test.ts
29
+ Run the project's test runner on the generated test file:
30
+
31
+ ```bash
32
+ # TypeScript: bun test tests/unit/<module>/<component>/<component>.test.ts
33
+ # Java: mvn test -Dtest=<Component>Test
34
+ # Python: pytest tests/<module>/<component>/test_<component>.py
35
+ # Go: go test ./tests/<module>/<component>/
36
+ # Rust: cargo test --test <component>
29
37
  ```
30
38
 
31
39
  Confirm the test fails before writing any implementation code. This validates that:
@@ -41,7 +49,7 @@ Write the minimal implementation to make the failing test pass.
41
49
  - Write only enough code to pass the test
42
50
  - Do not over-engineer — YAGNI
43
51
  - Use the test's TODO comments as a guide for what the API should look like
44
- - The test file is in `tests/unit/`, implementation files go in `src/`
52
+ - The test file is in the project's test directory (`tests/unit/`, `src/test/java/`, or `tests/`), implementation files go in `src/`
45
53
  - Import the implementation module into the test file
46
54
 
47
55
  If the generated test assumes an API shape that doesn't fit, **update the test first**, then implement.
@@ -107,11 +115,11 @@ The generated tests are **suggestions, not constraints**. You should modify them
107
115
 
108
116
  ## File Locations
109
117
 
110
- | Artifact | Path |
111
- |----------|------|
112
- | Tests | `tests/unit/<module>/<component>/<component>.test.ts` |
113
- | Implementation | `src/<module>/<component>.ts` (or appropriate layer) |
114
- | TDD guide | `.pi/skills/tdd-practice.md` |
118
+ | Artifact | TypeScript | Java | Python | Go | Rust |
119
+ |----------|------------|------|--------|-----|------|
120
+ | Tests | `tests/unit/.../component.test.ts` | `src/test/java/.../ComponentTest.java` | `tests/.../test_component.py` | `tests/.../component_test.go` | `tests/.../mod.rs` |
121
+ | Implementation | `src/<module>/` | `src/main/java/.../` | `src/<module>/` | `src/<module>/` | `src/<module>/` |
122
+ | TDD guide | `.pi/skills/tdd-practice.md` | same | same | same | same |
115
123
 
116
124
  ## Anti-Patterns
117
125