@opengroundplan/core 0.1.1 → 0.2.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 (64) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-runtime.d.ts +81 -0
  3. package/dist/agent-runtime.js +108 -0
  4. package/dist/agent-runtime.js.map +1 -0
  5. package/dist/analysis.d.ts +36 -0
  6. package/dist/analysis.js +106 -0
  7. package/dist/analysis.js.map +1 -0
  8. package/dist/analyze.d.ts +26 -0
  9. package/dist/analyze.js +155 -0
  10. package/dist/analyze.js.map +1 -0
  11. package/dist/assessment.d.ts +39 -0
  12. package/dist/assessment.js +81 -0
  13. package/dist/assessment.js.map +1 -0
  14. package/dist/autoplan.d.ts +60 -0
  15. package/dist/autoplan.js +219 -0
  16. package/dist/autoplan.js.map +1 -0
  17. package/dist/blueprint.d.ts +102 -0
  18. package/dist/blueprint.js +490 -0
  19. package/dist/blueprint.js.map +1 -0
  20. package/dist/config.d.ts +11 -0
  21. package/dist/config.js +18 -0
  22. package/dist/config.js.map +1 -1
  23. package/dist/graph.d.ts +20 -0
  24. package/dist/graph.js +84 -0
  25. package/dist/graph.js.map +1 -0
  26. package/dist/improve.d.ts +20 -0
  27. package/dist/improve.js +50 -0
  28. package/dist/improve.js.map +1 -0
  29. package/dist/index.d.ts +15 -0
  30. package/dist/index.js +15 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/infer-llm.d.ts +29 -0
  33. package/dist/infer-llm.js +114 -0
  34. package/dist/infer-llm.js.map +1 -0
  35. package/dist/intent.js +24 -1
  36. package/dist/intent.js.map +1 -1
  37. package/dist/knowledge.d.ts +23 -0
  38. package/dist/knowledge.js +61 -0
  39. package/dist/knowledge.js.map +1 -0
  40. package/dist/library.d.ts +25 -0
  41. package/dist/library.js +89 -0
  42. package/dist/library.js.map +1 -0
  43. package/dist/loader.js +23 -5
  44. package/dist/loader.js.map +1 -1
  45. package/dist/pipeline.d.ts +25 -0
  46. package/dist/pipeline.js +37 -0
  47. package/dist/pipeline.js.map +1 -0
  48. package/dist/schema.d.ts +113 -113
  49. package/dist/simulate.d.ts +15 -0
  50. package/dist/simulate.js +89 -0
  51. package/dist/simulate.js.map +1 -0
  52. package/dist/variables.d.ts +7 -0
  53. package/dist/variables.js +37 -0
  54. package/dist/variables.js.map +1 -0
  55. package/dist/verification.d.ts +23 -0
  56. package/dist/verification.js +61 -0
  57. package/dist/verification.js.map +1 -0
  58. package/package.json +7 -4
  59. package/templates/bases/fastapi-service/blueprint.yaml +2 -3
  60. package/templates/layers/auth-jwt/blueprint.yaml +3 -0
  61. package/templates/layers/auth-oidc/blueprint.yaml +1 -0
  62. package/templates/layers/db-mongo/blueprint.yaml +1 -0
  63. package/templates/layers/db-postgres/blueprint.yaml +3 -0
  64. package/templates/layers/db-sqlite/blueprint.yaml +1 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The one place blueprint variables become values. The interview, the autoplanner, and the
3
+ * generate harness all resolve through here — the same loop lived in three files and was three
4
+ * chances for the CLI and the library to disagree about what a repo contains.
5
+ *
6
+ * Every variable takes its declared default. A variable gated off on this stack by `when` may
7
+ * still be named by a template on another stack, so it is deferred and defaulted rather than
8
+ * left unset — an unresolved token fails generation, a stale default never renders.
9
+ */
10
+ import { test as testCondition } from './condition.js';
11
+ export function resolveVariableDefaults(blueprints, context, overrides = {}) {
12
+ const vars = { ...overrides };
13
+ const missing = [];
14
+ const deferred = [];
15
+ for (const blueprint of blueprints) {
16
+ for (const variable of blueprint.variables) {
17
+ if (variable.name in vars)
18
+ continue;
19
+ if (!testCondition(variable.when, { ...context, ...vars })) {
20
+ deferred.push(variable);
21
+ continue;
22
+ }
23
+ if (variable.default === undefined) {
24
+ missing.push(`${blueprint.id}.${variable.name}`);
25
+ continue;
26
+ }
27
+ vars[variable.name] = variable.default;
28
+ }
29
+ }
30
+ for (const variable of deferred) {
31
+ if (!(variable.name in vars) && variable.default !== undefined) {
32
+ vars[variable.name] = variable.default;
33
+ }
34
+ }
35
+ return { vars, missing };
36
+ }
37
+ //# sourceMappingURL=variables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables.js","sourceRoot":"","sources":["../src/variables.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAC;AASvD,MAAM,UAAU,uBAAuB,CACrC,UAAuB,EACvB,OAAgC,EAChC,YAAqC,EAAE;IAEvC,MAAM,IAAI,GAA4B,EAAE,GAAG,SAAS,EAAE,CAAC;IACvD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAE5C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;YAC3C,IAAI,QAAQ,CAAC,IAAI,IAAI,IAAI;gBAAE,SAAS;YACpC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC3D,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjD,SAAS;YACX,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;QACzC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/D,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { GroundplanConfig } from './config.js';
2
+ export interface Check {
3
+ name: string;
4
+ command: string;
5
+ }
6
+ export interface CheckResult extends Check {
7
+ ok: boolean;
8
+ /** Combined stdout+stderr, trimmed — empty when the check could not start. */
9
+ output: string;
10
+ }
11
+ /**
12
+ * The ordered checks for a stack: typecheck → lint → build → test, skipping any the stack does
13
+ * not declare. Install is the caller's concern (the generated repo's postApply handles it).
14
+ */
15
+ export declare function verificationPlan(stack: string, config: GroundplanConfig): Check[];
16
+ export interface RunOptions {
17
+ timeoutMs?: number;
18
+ onProgress?: (name: string) => void;
19
+ /** Stop at the first failing check (the default) rather than running them all. */
20
+ stopOnFailure?: boolean;
21
+ }
22
+ /** Run each check in `cwd`, capturing its result. Never throws — a failed spawn is a failed check. */
23
+ export declare function runChecks(cwd: string, checks: Check[], config: GroundplanConfig, opts?: RunOptions): Promise<CheckResult[]>;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Post-generation verification. A generated repo is only correct if it builds — the rule this
3
+ * project holds itself to — so this runs the stack's own checks against the output and reports
4
+ * what passed. The plan is derived from `config.stackCommands` (one place, no inlined command),
5
+ * and the runner captures each result; a failing check carries its output so an agent, or a
6
+ * person, can fix it. The self-fix loop lives above this: this layer reports, it does not edit.
7
+ */
8
+ import { spawn } from 'node:child_process';
9
+ /**
10
+ * The ordered checks for a stack: typecheck → lint → build → test, skipping any the stack does
11
+ * not declare. Install is the caller's concern (the generated repo's postApply handles it).
12
+ */
13
+ export function verificationPlan(stack, config) {
14
+ const cmds = config.stackCommands[stack];
15
+ if (!cmds)
16
+ return [];
17
+ const ordered = [
18
+ ['typecheck', cmds.typecheck],
19
+ ['lint', cmds.lint],
20
+ ['build', cmds.build],
21
+ ['test', cmds.test],
22
+ ];
23
+ return ordered.filter((c) => Boolean(c[1])).map(([name, command]) => ({ name, command }));
24
+ }
25
+ /** Run each check in `cwd`, capturing its result. Never throws — a failed spawn is a failed check. */
26
+ export async function runChecks(cwd, checks, config, opts = {}) {
27
+ const timeoutMs = opts.timeoutMs ?? config.postApplyTimeoutMs;
28
+ const stopOnFailure = opts.stopOnFailure ?? true;
29
+ const results = [];
30
+ for (const check of checks) {
31
+ opts.onProgress?.(check.name);
32
+ const result = await runOne(cwd, check, timeoutMs);
33
+ results.push(result);
34
+ if (!result.ok && stopOnFailure)
35
+ break;
36
+ }
37
+ return results;
38
+ }
39
+ function runOne(cwd, check, timeoutMs) {
40
+ return new Promise((resolve) => {
41
+ // shell:true so a declared command line ("pnpm run build") runs as written; the command
42
+ // comes from config.stackCommands, never from user input.
43
+ const child = spawn(check.command, { cwd, shell: true, stdio: ['ignore', 'pipe', 'pipe'] });
44
+ let output = '';
45
+ const capture = (buf) => {
46
+ output += buf.toString();
47
+ };
48
+ child.stdout?.on('data', capture);
49
+ child.stderr?.on('data', capture);
50
+ const timer = setTimeout(() => child.kill('SIGKILL'), timeoutMs);
51
+ child.on('error', (err) => {
52
+ clearTimeout(timer);
53
+ resolve({ ...check, ok: false, output: `could not start: ${err.message}` });
54
+ });
55
+ child.on('close', (code) => {
56
+ clearTimeout(timer);
57
+ resolve({ ...check, ok: code === 0, output: output.trim().slice(-4000) });
58
+ });
59
+ });
60
+ }
61
+ //# sourceMappingURL=verification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification.js","sourceRoot":"","sources":["../src/verification.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@opengroundplan/core",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "The Groundplan engine and catalog: composes a repository from templates, brands it, and wires it for every AI coding tool.",
5
5
  "license": "MIT",
6
6
  "author": "Groundplan contributors",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/groundplan/groundplan.git",
9
+ "url": "git+https://github.com/groundplan/opengroundplan.git",
10
10
  "directory": "packages/core"
11
11
  },
12
- "homepage": "https://github.com/groundplan/groundplan#readme",
13
- "bugs": "https://github.com/groundplan/groundplan/issues",
12
+ "homepage": "https://github.com/groundplan/opengroundplan#readme",
13
+ "bugs": "https://github.com/groundplan/opengroundplan/issues",
14
14
  "keywords": [
15
15
  "scaffolding",
16
16
  "templates",
@@ -57,5 +57,8 @@
57
57
  "glob": "^11.0.0",
58
58
  "yaml": "^2.6.1",
59
59
  "zod": "^3.24.1"
60
+ },
61
+ "optionalDependencies": {
62
+ "@anthropic-ai/sdk": "^0.112.0"
60
63
  }
61
64
  }
@@ -33,9 +33,8 @@ supportsArchitectures:
33
33
  - cqrs
34
34
  - microservices
35
35
  - serverless
36
- - llm-workflow
37
- - agentic-tool-loop
38
- - multi-agent
36
+ # AI-agent architectures (llm-workflow, agentic-tool-loop, multi-agent, rag-hybrid) belong to
37
+ # python-ai-agent, which ships the llm-runtime they assume. This is a plain HTTP service base.
39
38
  - medallion
40
39
  - mvc-mvvm
41
40
  - pipes-and-filters
@@ -1,6 +1,9 @@
1
1
  id: auth-jwt
2
2
  kind: layer
3
3
  name: Self-issued JWT auth
4
+ # One auth strategy per repo; self-issued JWT is the default when a project implies auth.
5
+ choiceSet: auth
6
+ choiceDefault: true
4
7
  description: >-
5
8
  First-party authentication: the service signs its own short-lived HS256 access
6
9
  tokens, hashes passwords with Argon2id, and rotates opaque refresh tokens with
@@ -1,6 +1,7 @@
1
1
  id: auth-oidc
2
2
  kind: layer
3
3
  name: OIDC / OAuth2 authentication
4
+ choiceSet: auth
4
5
  description: >-
5
6
  Standards-compliant OpenID Connect wiring. Browser stacks get Authorization Code + PKCE
6
7
  login with an encrypted session cookie; API stacks get bearer-token validation against the
@@ -1,6 +1,7 @@
1
1
  id: db-mongo
2
2
  kind: layer
3
3
  name: MongoDB
4
+ choiceSet: database
4
5
  description: >-
5
6
  MongoDB persistence adapter: pooled client, environment-driven settings, idempotent index
6
7
  declarations, health check, and a dev single-node replica set for transactions and change streams.
@@ -6,6 +6,9 @@
6
6
  id: db-postgres
7
7
  kind: layer
8
8
  name: PostgreSQL
9
+ # One primary datastore per repo; postgres is the default when a project implies a database.
10
+ choiceSet: database
11
+ choiceDefault: true
9
12
  description: Pooled PostgreSQL access, plain-SQL migrations, and a local server, configured entirely from the environment.
10
13
  tags:
11
14
  - database
@@ -1,6 +1,7 @@
1
1
  id: db-sqlite
2
2
  kind: layer
3
3
  name: SQLite
4
+ choiceSet: database
4
5
  description: Embedded SQLite persistence — connection, pragmas, plain-SQL migrations, health probe. For local, single-node, and small workloads.
5
6
  tags: [database, sqlite, persistence, embedded, local-first]
6
7