agentic-orchestrator 0.2.2 → 0.2.3

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.
@@ -1,7 +1,28 @@
1
+ import fsSync from 'node:fs';
1
2
  import fs from 'node:fs/promises';
2
3
  import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
3
5
  import { ensureDir, pathExists } from './fs.js';
4
6
 
7
+ const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
8
+
9
+ function resolveBundledOrchestratorRoot(startDir: string): string | null {
10
+ let current = path.resolve(startDir);
11
+ while (true) {
12
+ const candidate = path.join(current, 'agentic', 'orchestrator', 'schemas');
13
+ if (fsSync.existsSync(candidate)) {
14
+ return path.join(current, 'agentic', 'orchestrator');
15
+ }
16
+ const parent = path.dirname(current);
17
+ if (parent === current) {
18
+ return null;
19
+ }
20
+ current = parent;
21
+ }
22
+ }
23
+
24
+ const BUNDLED_ORCHESTRATOR_ROOT = resolveBundledOrchestratorRoot(MODULE_DIR);
25
+
5
26
  export class AopPathLayout {
6
27
  readonly repoRoot: string;
7
28
 
@@ -54,11 +75,8 @@ export class AopPathLayout {
54
75
  }
55
76
 
56
77
  organizerOrderingSchemaPath(): string {
57
- return path.join(
58
- this.legacyOrchestratorRoot,
59
- 'schemas',
60
- 'organizer-ordering-artifact.schema.json',
61
- );
78
+ const root = BUNDLED_ORCHESTRATOR_ROOT ?? this.legacyOrchestratorRoot;
79
+ return path.join(root, 'schemas', 'organizer-ordering-artifact.schema.json');
62
80
  }
63
81
 
64
82
  get legacyFeaturesRoot(): string {
@@ -13,6 +13,17 @@ async function writeMarker(filePath: string, content = 'marker'): Promise<void>
13
13
  await fs.writeFile(filePath, content, 'utf8');
14
14
  }
15
15
 
16
+ describe('AopPathLayout', () => {
17
+ it('resolves organizerOrderingSchemaPath from the bundled package tree', () => {
18
+ const layout = new AopPathLayout('/some/external/project');
19
+ const schemaPath = layout.organizerOrderingSchemaPath();
20
+
21
+ expect(schemaPath).toContain('organizer-ordering-artifact.schema.json');
22
+ // Must NOT resolve from the arbitrary repoRoot — it must find the bundled schema
23
+ expect(schemaPath).not.toContain('/some/external/project/');
24
+ });
25
+ });
26
+
16
27
  describe('ensureAopRuntimeLayout', () => {
17
28
  it('migrates legacy features when .aop is missing', async () => {
18
29
  const repoRoot = await makeTempDir();
@@ -1,6 +1,24 @@
1
+ import fsSync from 'node:fs';
1
2
  import fs from 'node:fs/promises';
2
3
  import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
3
5
  import { ensureDir, pathExists } from './fs.js';
6
+ const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
7
+ function resolveBundledOrchestratorRoot(startDir) {
8
+ let current = path.resolve(startDir);
9
+ while (true) {
10
+ const candidate = path.join(current, 'agentic', 'orchestrator', 'schemas');
11
+ if (fsSync.existsSync(candidate)) {
12
+ return path.join(current, 'agentic', 'orchestrator');
13
+ }
14
+ const parent = path.dirname(current);
15
+ if (parent === current) {
16
+ return null;
17
+ }
18
+ current = parent;
19
+ }
20
+ }
21
+ const BUNDLED_ORCHESTRATOR_ROOT = resolveBundledOrchestratorRoot(MODULE_DIR);
4
22
  export class AopPathLayout {
5
23
  repoRoot;
6
24
  constructor(repoRoot) {
@@ -40,7 +58,8 @@ export class AopPathLayout {
40
58
  return path.join(this.instanceRuntimeRoot(instanceId), 'organizer-ordering.json');
41
59
  }
42
60
  organizerOrderingSchemaPath() {
43
- return path.join(this.legacyOrchestratorRoot, 'schemas', 'organizer-ordering-artifact.schema.json');
61
+ const root = BUNDLED_ORCHESTRATOR_ROOT ?? this.legacyOrchestratorRoot;
62
+ return path.join(root, 'schemas', 'organizer-ordering-artifact.schema.json');
44
63
  }
45
64
  get legacyFeaturesRoot() {
46
65
  return path.join(this.repoRoot, 'agentic', 'features');
@@ -1 +1 @@
1
- {"version":3,"file":"path-layout.js","sourceRoot":"","sources":["../../../../apps/control-plane/src/core/path-layout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"path-layout.js","sourceRoot":"","sources":["../../../../apps/control-plane/src/core/path-layout.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-orchestrator",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "packages/*"
@@ -261,6 +261,36 @@ describe('POST /api/launch/submit', () => {
261
261
  ).resolves.toContain('Ship it.');
262
262
  });
263
263
 
264
+ it('accepts uploaded drafts where name is stripped but source_path retains .md', async () => {
265
+ const response = await POST(
266
+ new Request('http://localhost/api/launch/submit', {
267
+ method: 'POST',
268
+ body: JSON.stringify({
269
+ drafts: [
270
+ {
271
+ draft_id: 'upload-stripped',
272
+ draft_order: 0,
273
+ source_type: 'upload',
274
+ name: 'my-feature',
275
+ source_path: 'my-feature.md',
276
+ markdown: '# My Feature\n\nDescription.',
277
+ },
278
+ ],
279
+ }),
280
+ }),
281
+ );
282
+ const body = (await response.json()) as {
283
+ ok: boolean;
284
+ data?: { outcomes: Array<{ draft_id: string; status: string; errors: string[] }> };
285
+ };
286
+
287
+ expect(body.ok).toBe(true);
288
+ expect(body.data?.outcomes[0]).toMatchObject({
289
+ draft_id: 'upload-stripped',
290
+ status: 'submitted',
291
+ });
292
+ });
293
+
264
294
  it('rejects duplicate slugs before writing specs or submitting enrollment requests', async () => {
265
295
  prepareLaunchDraftSpecsMock.mockResolvedValue([
266
296
  {
@@ -0,0 +1,65 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { validateLaunchDraftInput } from '@/lib/launch-contracts.js';
3
+ import type { LaunchDraftInput } from '@/lib/launch-contracts.js';
4
+
5
+ function baseDraft(overrides: Partial<LaunchDraftInput> = {}): LaunchDraftInput {
6
+ return {
7
+ draft_id: 'draft-1',
8
+ draft_order: 0,
9
+ source_type: 'paste',
10
+ name: 'Feature Draft',
11
+ markdown: '# Feature',
12
+ ...overrides,
13
+ };
14
+ }
15
+
16
+ describe('validateLaunchDraftInput', () => {
17
+ it('returns no errors for a valid paste draft', () => {
18
+ expect(validateLaunchDraftInput(baseDraft())).toEqual([]);
19
+ });
20
+
21
+ it('returns no errors for a valid upload draft with .md extension', () => {
22
+ expect(validateLaunchDraftInput(baseDraft({ source_type: 'upload', name: 'spec.md' }))).toEqual(
23
+ [],
24
+ );
25
+ });
26
+
27
+ it('rejects uploaded drafts with unsupported extensions', () => {
28
+ const errors = validateLaunchDraftInput(
29
+ baseDraft({ source_type: 'upload', name: 'notes.txt' }),
30
+ );
31
+ expect(errors).toContain('Only .md draft uploads are supported.');
32
+ });
33
+
34
+ it('accepts uploaded drafts when name is stripped but source_path retains .md', () => {
35
+ const errors = validateLaunchDraftInput(
36
+ baseDraft({ source_type: 'upload', name: 'my-feature', source_path: 'my-feature.md' }),
37
+ );
38
+ expect(errors).toEqual([]);
39
+ });
40
+
41
+ it('rejects uploaded drafts when both name and source_path lack .md extension', () => {
42
+ const errors = validateLaunchDraftInput(
43
+ baseDraft({ source_type: 'upload', name: 'my-feature', source_path: 'my-feature.txt' }),
44
+ );
45
+ expect(errors).toContain('Only .md draft uploads are supported.');
46
+ });
47
+
48
+ it('rejects drafts with empty name', () => {
49
+ expect(validateLaunchDraftInput(baseDraft({ name: ' ' }))).toContain(
50
+ 'Draft name is required.',
51
+ );
52
+ });
53
+
54
+ it('rejects drafts with empty markdown', () => {
55
+ expect(validateLaunchDraftInput(baseDraft({ markdown: '' }))).toContain(
56
+ 'Draft markdown is required.',
57
+ );
58
+ });
59
+
60
+ it('rejects drafts with empty draft_id', () => {
61
+ expect(validateLaunchDraftInput(baseDraft({ draft_id: '' }))).toContain(
62
+ 'draft_id is required.',
63
+ );
64
+ });
65
+ });