agentic-orchestrator 0.2.1 → 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.1",
3
+ "version": "0.2.3",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "packages/*"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aop/web-dashboard",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { existsSync } from 'node:fs';
3
3
  import path from 'node:path';
4
- import { pathToFileURL } from 'node:url';
4
+ import { fileURLToPath, pathToFileURL } from 'node:url';
5
5
  import { getAopRoot } from '@/lib/aop-client.js';
6
6
  import {
7
7
  submitDashboardRuntimeCommand,
@@ -348,16 +348,23 @@ function resolveControlPlaneModulePath(): string {
348
348
  return fromAopRoot;
349
349
  }
350
350
 
351
- // Strategy 3: Resolve from globally installed package
351
+ // Strategy 3: Walk up from this file's compiled location (handles .next chunks
352
+ // within the installed package tree, e.g. packages/web-dashboard/.next/dev/...)
352
353
  try {
353
- // eslint-disable-next-line @typescript-eslint/no-require-imports
354
- const pkgJson = require.resolve('agentic-orchestrator/package.json');
355
- const candidate = path.join(path.dirname(pkgJson), distRelative);
356
- if (existsSync(candidate)) {
357
- return candidate;
354
+ let dir = path.dirname(fileURLToPath(import.meta.url));
355
+ for (let i = 0; i < 10; i++) {
356
+ const candidate = path.join(dir, distRelative);
357
+ if (existsSync(candidate)) {
358
+ return candidate;
359
+ }
360
+ const parent = path.dirname(dir);
361
+ if (parent === dir) {
362
+ break;
363
+ }
364
+ dir = parent;
358
365
  }
359
366
  } catch {
360
- // package not resolvable via require continue
367
+ // import.meta.url may not resolve to a file path in all bundler contexts
361
368
  }
362
369
 
363
370
  // Fallback: return the AOP_ROOT-based path (will fail at import time with a clear error)
@@ -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
+ });