@agentworkforce/deploy 0.0.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 (65) hide show
  1. package/dist/bundle.d.ts +22 -0
  2. package/dist/bundle.d.ts.map +1 -0
  3. package/dist/bundle.js +132 -0
  4. package/dist/bundle.js.map +1 -0
  5. package/dist/bundle.test.d.ts +2 -0
  6. package/dist/bundle.test.d.ts.map +1 -0
  7. package/dist/bundle.test.js +92 -0
  8. package/dist/bundle.test.js.map +1 -0
  9. package/dist/connect.d.ts +81 -0
  10. package/dist/connect.d.ts.map +1 -0
  11. package/dist/connect.js +127 -0
  12. package/dist/connect.js.map +1 -0
  13. package/dist/deploy.d.ts +50 -0
  14. package/dist/deploy.d.ts.map +1 -0
  15. package/dist/deploy.js +172 -0
  16. package/dist/deploy.js.map +1 -0
  17. package/dist/deploy.test.d.ts +2 -0
  18. package/dist/deploy.test.d.ts.map +1 -0
  19. package/dist/deploy.test.js +293 -0
  20. package/dist/deploy.test.js.map +1 -0
  21. package/dist/index.d.ts +11 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +10 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/io.d.ts +22 -0
  26. package/dist/io.d.ts.map +1 -0
  27. package/dist/io.js +76 -0
  28. package/dist/io.js.map +1 -0
  29. package/dist/login.d.ts +24 -0
  30. package/dist/login.d.ts.map +1 -0
  31. package/dist/login.js +27 -0
  32. package/dist/login.js.map +1 -0
  33. package/dist/modes/cloud.d.ts +18 -0
  34. package/dist/modes/cloud.d.ts.map +1 -0
  35. package/dist/modes/cloud.js +21 -0
  36. package/dist/modes/cloud.js.map +1 -0
  37. package/dist/modes/dev.d.ts +12 -0
  38. package/dist/modes/dev.d.ts.map +1 -0
  39. package/dist/modes/dev.js +153 -0
  40. package/dist/modes/dev.js.map +1 -0
  41. package/dist/modes/sandbox-client.d.ts +63 -0
  42. package/dist/modes/sandbox-client.d.ts.map +1 -0
  43. package/dist/modes/sandbox-client.js +177 -0
  44. package/dist/modes/sandbox-client.js.map +1 -0
  45. package/dist/modes/sandbox-client.test.d.ts +2 -0
  46. package/dist/modes/sandbox-client.test.d.ts.map +1 -0
  47. package/dist/modes/sandbox-client.test.js +177 -0
  48. package/dist/modes/sandbox-client.test.js.map +1 -0
  49. package/dist/modes/sandbox.d.ts +50 -0
  50. package/dist/modes/sandbox.d.ts.map +1 -0
  51. package/dist/modes/sandbox.js +131 -0
  52. package/dist/modes/sandbox.js.map +1 -0
  53. package/dist/modes/sandbox.test.d.ts +2 -0
  54. package/dist/modes/sandbox.test.d.ts.map +1 -0
  55. package/dist/modes/sandbox.test.js +95 -0
  56. package/dist/modes/sandbox.test.js.map +1 -0
  57. package/dist/preflight.d.ts +14 -0
  58. package/dist/preflight.d.ts.map +1 -0
  59. package/dist/preflight.js +78 -0
  60. package/dist/preflight.js.map +1 -0
  61. package/dist/types.d.ts +140 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/dist/types.js +2 -0
  64. package/dist/types.js.map +1 -0
  65. package/package.json +40 -0
@@ -0,0 +1,22 @@
1
+ import type { BundleStager } from './types.js';
2
+ /**
3
+ * Stage a deploy-ready bundle to `input.outDir`. Output layout:
4
+ *
5
+ * <outDir>/
6
+ * agent.bundle.mjs — esbuilt user `onEvent` (default-exported handler)
7
+ * runner.mjs — entry that imports the runtime + bundle + persona
8
+ * persona.json — verbatim copy of the input persona spec
9
+ * package.json — minimal manifest pinning the runtime dep
10
+ *
11
+ * The bundle is idempotent: re-running with the same `outDir` overwrites
12
+ * the four files cleanly. Auxiliary files left behind from earlier runs
13
+ * are not touched (callers control the directory lifecycle).
14
+ *
15
+ * Externals: every `node:*` builtin and `@agentworkforce/runtime` itself
16
+ * are left external so the runner can resolve them at execution time.
17
+ * Bundling the runtime in would require shipping the runtime sources into
18
+ * every sandbox; the chosen split keeps the bundle small and lets ops
19
+ * patch the runtime without rebuilding every persona.
20
+ */
21
+ export declare const bundleStager: BundleStager;
22
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkC,YAAY,EAAE,MAAM,YAAY,CAAC;AAS/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,YAAY,EAAE,YAyD1B,CAAC"}
package/dist/bundle.js ADDED
@@ -0,0 +1,132 @@
1
+ import { mkdir, writeFile, stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { build } from 'esbuild';
4
+ /**
5
+ * Versioned identifier embedded in the generated runner so a future
6
+ * bundle reader can detect format drift. Bumped whenever the runner
7
+ * shape changes incompatibly.
8
+ */
9
+ const RUNNER_FORMAT_VERSION = 1;
10
+ /**
11
+ * Stage a deploy-ready bundle to `input.outDir`. Output layout:
12
+ *
13
+ * <outDir>/
14
+ * agent.bundle.mjs — esbuilt user `onEvent` (default-exported handler)
15
+ * runner.mjs — entry that imports the runtime + bundle + persona
16
+ * persona.json — verbatim copy of the input persona spec
17
+ * package.json — minimal manifest pinning the runtime dep
18
+ *
19
+ * The bundle is idempotent: re-running with the same `outDir` overwrites
20
+ * the four files cleanly. Auxiliary files left behind from earlier runs
21
+ * are not touched (callers control the directory lifecycle).
22
+ *
23
+ * Externals: every `node:*` builtin and `@agentworkforce/runtime` itself
24
+ * are left external so the runner can resolve them at execution time.
25
+ * Bundling the runtime in would require shipping the runtime sources into
26
+ * every sandbox; the chosen split keeps the bundle small and lets ops
27
+ * patch the runtime without rebuilding every persona.
28
+ */
29
+ export const bundleStager = {
30
+ async stage(input) {
31
+ await mkdir(input.outDir, { recursive: true });
32
+ const onEventAbs = path.resolve(path.dirname(input.personaPath), input.persona.onEvent ?? '');
33
+ if (!input.persona.onEvent) {
34
+ throw new Error(`bundle: persona "${input.persona.id}" is missing onEvent (cannot stage a bundle without a handler)`);
35
+ }
36
+ await assertReadableFile(onEventAbs, `persona "${input.persona.id}" onEvent`);
37
+ const bundlePath = path.join(input.outDir, 'agent.bundle.mjs');
38
+ const runnerPath = path.join(input.outDir, 'runner.mjs');
39
+ const personaCopyPath = path.join(input.outDir, 'persona.json');
40
+ const packageJsonPath = path.join(input.outDir, 'package.json');
41
+ await build({
42
+ entryPoints: [onEventAbs],
43
+ outfile: bundlePath,
44
+ bundle: true,
45
+ format: 'esm',
46
+ platform: 'node',
47
+ target: 'node20',
48
+ sourcemap: 'inline',
49
+ logLevel: 'silent',
50
+ minify: input.bundlerOptions?.minify ?? false,
51
+ // Resolve TypeScript / JS extensions without forcing the user to
52
+ // write `.ts`-suffixed imports in their handler file.
53
+ resolveExtensions: ['.ts', '.mts', '.cts', '.tsx', '.js', '.mjs', '.cjs', '.jsx', '.json'],
54
+ external: [
55
+ // Runtime stays external — see file header comment.
56
+ '@agentworkforce/runtime',
57
+ '@agentworkforce/runtime/raw',
58
+ // Node builtins must never be bundled.
59
+ 'node:*'
60
+ ]
61
+ });
62
+ await writeFile(personaCopyPath, JSON.stringify(input.persona, null, 2) + '\n', 'utf8');
63
+ await writeFile(packageJsonPath, buildPackageJson(input.persona.id), 'utf8');
64
+ await writeFile(runnerPath, renderRunner(), 'utf8');
65
+ const bundleStat = await stat(bundlePath);
66
+ const runnerStat = await stat(runnerPath);
67
+ const sizeBytes = bundleStat.size + runnerStat.size;
68
+ return {
69
+ personaCopyPath,
70
+ runnerPath,
71
+ bundlePath,
72
+ packageJsonPath,
73
+ sizeBytes
74
+ };
75
+ }
76
+ };
77
+ function buildPackageJson(personaId) {
78
+ return (JSON.stringify({
79
+ name: `@agentworkforce/deployed-${personaId}`,
80
+ private: true,
81
+ version: '0.0.0',
82
+ type: 'module',
83
+ main: './runner.mjs',
84
+ dependencies: {
85
+ '@agentworkforce/runtime': '*'
86
+ },
87
+ comment: 'Generated by workforce deploy. The runtime dep is pinned to "*" because deploys resolve the runtime version from the active workspace.'
88
+ }, null, 2) + '\n');
89
+ }
90
+ function renderRunner() {
91
+ return `// Generated by @agentworkforce/deploy. Format version ${RUNNER_FORMAT_VERSION}.
92
+ // Do not edit by hand — \`workforce deploy\` overwrites this file on every stage.
93
+ //
94
+ // The runner imports the user's handler from the esbuilt bundle, the
95
+ // parsed persona spec from the verbatim JSON copy, and the runtime's
96
+ // \`startRunner\` to drive the dispatch loop. Envelopes arrive on stdin
97
+ // as NDJSON; structured logs go to stdout.
98
+
99
+ import { createRequire } from 'node:module';
100
+ import { startRunner } from '@agentworkforce/runtime/runner';
101
+ import { handler as wrapHandler } from '@agentworkforce/runtime';
102
+ import * as userModule from './agent.bundle.mjs';
103
+
104
+ const require = createRequire(import.meta.url);
105
+ const persona = require('./persona.json');
106
+
107
+ const candidate = userModule.default ?? userModule.handler;
108
+ if (typeof candidate !== 'function') {
109
+ throw new TypeError(
110
+ \`workforce deploy bundle: \${persona.id} did not default-export a function. Did you forget \\\`export default handler(...)\\\`?\`
111
+ );
112
+ }
113
+ const handler = candidate.__workforceHandler ? candidate : wrapHandler(candidate);
114
+
115
+ await startRunner({ persona, handler });
116
+ `;
117
+ }
118
+ async function assertReadableFile(abs, label) {
119
+ try {
120
+ const st = await stat(abs);
121
+ if (!st.isFile()) {
122
+ throw new Error(`${label}: ${abs} is not a regular file`);
123
+ }
124
+ }
125
+ catch (err) {
126
+ if (err.code === 'ENOENT') {
127
+ throw new Error(`${label}: file not found at ${abs}`);
128
+ }
129
+ throw err;
130
+ }
131
+ }
132
+ //# sourceMappingURL=bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bundle.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.test.d.ts","sourceRoot":"","sources":["../src/bundle.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,92 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
6
+ import { bundleStager } from './bundle.js';
7
+ function persona(overrides = {}) {
8
+ return {
9
+ id: 'bundle-fixture',
10
+ intent: 'documentation',
11
+ tags: ['documentation'],
12
+ description: 'fixture for bundle tests',
13
+ skills: [],
14
+ harness: 'claude',
15
+ model: 'anthropic/claude-3-5-sonnet',
16
+ systemPrompt: 'be helpful',
17
+ harnessSettings: { reasoning: 'medium', timeoutSeconds: 300 },
18
+ cloud: true,
19
+ schedules: [{ name: 'weekly', cron: '0 9 * * 6' }],
20
+ onEvent: './agent.ts',
21
+ ...overrides
22
+ };
23
+ }
24
+ test('bundleStager produces an executable, importable bundle from a real onEvent file', async () => {
25
+ const dir = await mkdtemp(path.join(os.tmpdir(), 'wf-bundle-'));
26
+ try {
27
+ const personaPath = path.join(dir, 'persona.json');
28
+ const personaSpec = persona();
29
+ await writeFile(personaPath, JSON.stringify(personaSpec, null, 2), 'utf8');
30
+ await writeFile(path.join(dir, 'agent.ts'), [
31
+ "import { handler } from '@agentworkforce/runtime';",
32
+ '',
33
+ 'export default handler(async (ctx, event) => {',
34
+ " ctx.log('info', 'fixture.handler.fired', { eventId: event.id });",
35
+ '});',
36
+ ''
37
+ ].join('\n'), 'utf8');
38
+ const outDir = path.join(dir, 'build');
39
+ const result = await bundleStager.stage({
40
+ personaPath,
41
+ persona: personaSpec,
42
+ outDir
43
+ });
44
+ assert.equal(result.personaCopyPath, path.join(outDir, 'persona.json'));
45
+ assert.equal(result.runnerPath, path.join(outDir, 'runner.mjs'));
46
+ assert.equal(result.bundlePath, path.join(outDir, 'agent.bundle.mjs'));
47
+ assert.equal(result.packageJsonPath, path.join(outDir, 'package.json'));
48
+ assert.ok(result.sizeBytes > 0);
49
+ // persona.json round-trips verbatim
50
+ const personaCopy = JSON.parse(await readFile(result.personaCopyPath, 'utf8'));
51
+ assert.equal(personaCopy.id, personaSpec.id);
52
+ assert.equal(personaCopy.onEvent, './agent.ts');
53
+ // runner imports the expected entry points
54
+ const runnerSource = await readFile(result.runnerPath, 'utf8');
55
+ assert.match(runnerSource, /from '@agentworkforce\/runtime\/runner'/);
56
+ assert.match(runnerSource, /from '@agentworkforce\/runtime'/);
57
+ assert.match(runnerSource, /import \* as userModule from '\.\/agent\.bundle\.mjs'/);
58
+ // bundle output is ES module shape and references the runtime as external
59
+ const bundleSource = await readFile(result.bundlePath, 'utf8');
60
+ assert.match(bundleSource, /^import /m);
61
+ assert.match(bundleSource, /from\s+['"]@agentworkforce\/runtime['"]/);
62
+ }
63
+ finally {
64
+ await rm(dir, { recursive: true, force: true });
65
+ }
66
+ });
67
+ test('bundleStager throws when onEvent file is missing', async () => {
68
+ const dir = await mkdtemp(path.join(os.tmpdir(), 'wf-bundle-'));
69
+ try {
70
+ const personaPath = path.join(dir, 'persona.json');
71
+ const personaSpec = persona({ onEvent: './missing.ts' });
72
+ await writeFile(personaPath, JSON.stringify(personaSpec, null, 2), 'utf8');
73
+ await assert.rejects(() => bundleStager.stage({ personaPath, persona: personaSpec, outDir: path.join(dir, 'build') }), /file not found/);
74
+ }
75
+ finally {
76
+ await rm(dir, { recursive: true, force: true });
77
+ }
78
+ });
79
+ test('bundleStager throws when persona has no onEvent', async () => {
80
+ const dir = await mkdtemp(path.join(os.tmpdir(), 'wf-bundle-'));
81
+ try {
82
+ const personaPath = path.join(dir, 'persona.json');
83
+ const personaSpec = persona();
84
+ delete personaSpec.onEvent;
85
+ await writeFile(personaPath, JSON.stringify(personaSpec, null, 2), 'utf8');
86
+ await assert.rejects(() => bundleStager.stage({ personaPath, persona: personaSpec, outDir: path.join(dir, 'build') }), /missing onEvent/);
87
+ }
88
+ finally {
89
+ await rm(dir, { recursive: true, force: true });
90
+ }
91
+ });
92
+ //# sourceMappingURL=bundle.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.test.js","sourceRoot":"","sources":["../src/bundle.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { PersonaSpec } from '@agentworkforce/persona-kit';
2
+ import type { DeployIO, IntegrationConnectOutcome } from './types.js';
3
+ /**
4
+ * Resolver the orchestrator uses to check + connect a Relayfile-backed
5
+ * provider for the active workspace. The deploy package does not depend
6
+ * on `@relayfile/sdk` directly; the CLI dispatches the real implementation
7
+ * (which imports the SDK) into this contract.
8
+ *
9
+ * Decoupling this keeps the orchestrator unit-testable without spinning
10
+ * up Relayfile and keeps the SDK out of the deploy package's transitive
11
+ * dep tree (smaller bin, faster install).
12
+ */
13
+ export interface IntegrationConnectResolver {
14
+ /** Is the provider already linked to the workspace? */
15
+ isConnected(args: {
16
+ workspace: string;
17
+ provider: string;
18
+ }): Promise<boolean>;
19
+ /** Run the browser-based OAuth flow and resolve when the user finishes. */
20
+ connect(args: {
21
+ workspace: string;
22
+ provider: string;
23
+ }): Promise<{
24
+ connectionId: string;
25
+ }>;
26
+ }
27
+ /**
28
+ * Provider linker for `useSubscription: true` personas — connects the
29
+ * user's chosen LLM provider so cloud inference is billed against their
30
+ * subscription rather than workforce.
31
+ */
32
+ export interface ProviderSubscriptionResolver {
33
+ isConnected(args: {
34
+ workspace: string;
35
+ providerHint?: string;
36
+ }): Promise<boolean>;
37
+ connect(args: {
38
+ workspace: string;
39
+ providerHint?: string;
40
+ }): Promise<{
41
+ provider: string;
42
+ }>;
43
+ }
44
+ /**
45
+ * Resolver backed by env vars. Used as the default when no higher-level
46
+ * implementation is plugged in. `isConnected` returns true exactly when
47
+ * one of the two recognized env vars is set for the provider; `connect`
48
+ * is a no-op that records the env-resolved nature of the connection so
49
+ * the orchestrator's flow stays uniform across resolvers.
50
+ */
51
+ export declare function envIntegrationResolver(): IntegrationConnectResolver;
52
+ export interface ConnectAllInput {
53
+ persona: PersonaSpec;
54
+ workspace: string;
55
+ noConnect: boolean;
56
+ io: DeployIO;
57
+ integrations: IntegrationConnectResolver;
58
+ /** Required only when persona.useSubscription is true. */
59
+ subscription?: ProviderSubscriptionResolver;
60
+ }
61
+ export interface ConnectAllResult {
62
+ outcomes: IntegrationConnectOutcome[];
63
+ /** Provider the subscription was bound to, when applicable. */
64
+ subscriptionProvider?: string;
65
+ }
66
+ /**
67
+ * Walk the persona's declared integrations and ensure each is connected.
68
+ * Per the deploy-v1 spec, the orchestrator prompts before each provider's
69
+ * connect flow ("Connect github now? (Y/n)") so users running on a shared
70
+ * machine don't have surprise browser pops.
71
+ *
72
+ * Behavior summary:
73
+ * - integrations: {} or undefined → returns immediately, no prompts
74
+ * - already-connected provider → no prompt; emits `already-connected`
75
+ * - not connected + noConnect=true → fails the deploy with a clear message
76
+ * - not connected + noConnect=false → prompts; on yes runs `connect`,
77
+ * on no marks `skipped`. The orchestrator decides what to do with
78
+ * `skipped` outcomes (today: fails the deploy at the call site).
79
+ */
80
+ export declare function connectIntegrations(input: ConnectAllInput): Promise<ConnectAllResult>;
81
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAkBtE;;;;;;;;;GASG;AACH,MAAM,WAAW,0BAA0B;IACzC,uDAAuD;IACvD,WAAW,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,2EAA2E;IAC3E,OAAO,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3F;AAED;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClF,OAAO,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5F;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,0BAA0B,CAcnE;AAUD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,EAAE,EAAE,QAAQ,CAAC;IACb,YAAY,EAAE,0BAA0B,CAAC;IACzC,0DAA0D;IAC1D,YAAY,CAAC,EAAE,4BAA4B,CAAC;CAC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,+DAA+D;IAC/D,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0F3F"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Provider env-var conventions the deploy CLI checks when no higher-level
3
+ * integration resolver is supplied. The convention is:
4
+ *
5
+ * - `WORKFORCE_INTEGRATION_<PROVIDER>_TOKEN` — direct provider token
6
+ * (e.g. `WORKFORCE_INTEGRATION_GITHUB_TOKEN`). Treated as "connected"
7
+ * when present and non-empty.
8
+ * - or `WORKFORCE_INTEGRATION_<PROVIDER>_CONNECTION_ID` — Relayfile
9
+ * connection id, resolved to a scoped token at runtime by the agent.
10
+ *
11
+ * The connect side is a no-op for the env path: there is nothing to
12
+ * authenticate interactively. Authors plug a higher-level resolver into
13
+ * `DeployResolvers.integrations` once Relayfile's OAuth surface is wired.
14
+ */
15
+ const PROVIDER_ENV_PREFIX = 'WORKFORCE_INTEGRATION_';
16
+ /**
17
+ * Resolver backed by env vars. Used as the default when no higher-level
18
+ * implementation is plugged in. `isConnected` returns true exactly when
19
+ * one of the two recognized env vars is set for the provider; `connect`
20
+ * is a no-op that records the env-resolved nature of the connection so
21
+ * the orchestrator's flow stays uniform across resolvers.
22
+ */
23
+ export function envIntegrationResolver() {
24
+ return {
25
+ async isConnected({ provider }) {
26
+ return providerHasEnvCredentials(provider);
27
+ },
28
+ async connect({ provider }) {
29
+ if (!providerHasEnvCredentials(provider)) {
30
+ throw new Error(`env resolver: ${provider} is not connected. Set ${PROVIDER_ENV_PREFIX}${provider.toUpperCase()}_TOKEN or ${PROVIDER_ENV_PREFIX}${provider.toUpperCase()}_CONNECTION_ID, then re-run deploy. (Higher-level resolvers — e.g. a Relayfile OAuth flow — plug in via DeployResolvers.integrations.)`);
31
+ }
32
+ return { connectionId: `env:${provider}` };
33
+ }
34
+ };
35
+ }
36
+ function providerHasEnvCredentials(provider) {
37
+ const upper = provider.toUpperCase();
38
+ return Boolean(process.env[`${PROVIDER_ENV_PREFIX}${upper}_TOKEN`] ||
39
+ process.env[`${PROVIDER_ENV_PREFIX}${upper}_CONNECTION_ID`]);
40
+ }
41
+ /**
42
+ * Walk the persona's declared integrations and ensure each is connected.
43
+ * Per the deploy-v1 spec, the orchestrator prompts before each provider's
44
+ * connect flow ("Connect github now? (Y/n)") so users running on a shared
45
+ * machine don't have surprise browser pops.
46
+ *
47
+ * Behavior summary:
48
+ * - integrations: {} or undefined → returns immediately, no prompts
49
+ * - already-connected provider → no prompt; emits `already-connected`
50
+ * - not connected + noConnect=true → fails the deploy with a clear message
51
+ * - not connected + noConnect=false → prompts; on yes runs `connect`,
52
+ * on no marks `skipped`. The orchestrator decides what to do with
53
+ * `skipped` outcomes (today: fails the deploy at the call site).
54
+ */
55
+ export async function connectIntegrations(input) {
56
+ const integrations = input.persona.integrations ?? {};
57
+ const outcomes = [];
58
+ for (const provider of Object.keys(integrations)) {
59
+ const connected = await input.integrations
60
+ .isConnected({ workspace: input.workspace, provider })
61
+ .catch((err) => {
62
+ input.io.warn(`failed to check connection status for ${provider}: ${err instanceof Error ? err.message : String(err)}`);
63
+ return false;
64
+ });
65
+ if (connected) {
66
+ input.io.info(`integrations.${provider}: already connected`);
67
+ outcomes.push({ provider, status: 'already-connected' });
68
+ continue;
69
+ }
70
+ if (input.noConnect) {
71
+ input.io.error(`integrations.${provider}: not connected, and --no-connect was passed`);
72
+ outcomes.push({
73
+ provider,
74
+ status: 'failed',
75
+ message: 'not connected (--no-connect was set)'
76
+ });
77
+ continue;
78
+ }
79
+ const shouldConnect = await input.io.confirm(`Connect ${provider} now? (opens browser)`, { defaultValue: true });
80
+ if (!shouldConnect) {
81
+ outcomes.push({ provider, status: 'skipped', message: 'user declined to connect' });
82
+ continue;
83
+ }
84
+ try {
85
+ const result = await input.integrations.connect({ workspace: input.workspace, provider });
86
+ input.io.info(`integrations.${provider}: connected (${result.connectionId})`);
87
+ outcomes.push({ provider, status: 'connected-now' });
88
+ }
89
+ catch (err) {
90
+ const message = err instanceof Error ? err.message : String(err);
91
+ input.io.error(`integrations.${provider}: connect failed: ${message}`);
92
+ outcomes.push({ provider, status: 'failed', message });
93
+ }
94
+ }
95
+ // Track the subscription provider only when this deploy actually
96
+ // connected one — already-connected cases stay logged but do not
97
+ // leak a sentinel string up to callers reading `subscriptionProvider`.
98
+ let subscriptionProvider;
99
+ if (input.persona.useSubscription) {
100
+ if (!input.subscription) {
101
+ throw new Error('persona has useSubscription:true but no subscription resolver was supplied to the deploy orchestrator');
102
+ }
103
+ const isConn = await input.subscription
104
+ .isConnected({ workspace: input.workspace })
105
+ .catch(() => false);
106
+ if (!isConn) {
107
+ if (input.noConnect) {
108
+ throw new Error('persona requires a subscription provider connection, but --no-connect was passed');
109
+ }
110
+ const ok = await input.io.confirm('persona has useSubscription:true — connect your LLM provider now?', { defaultValue: true });
111
+ if (!ok) {
112
+ throw new Error('user declined the subscription provider connect; deploy aborted');
113
+ }
114
+ const result = await input.subscription.connect({ workspace: input.workspace });
115
+ subscriptionProvider = result.provider;
116
+ input.io.info(`subscription: connected (${result.provider})`);
117
+ }
118
+ else {
119
+ input.io.info('subscription: already connected');
120
+ }
121
+ }
122
+ return {
123
+ outcomes,
124
+ ...(subscriptionProvider ? { subscriptionProvider } : {})
125
+ };
126
+ }
127
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { type IntegrationConnectResolver, type ProviderSubscriptionResolver } from './connect.js';
2
+ import { type WorkspaceAuth } from './login.js';
3
+ import type { BundleStager, DeployMode, DeployOptions, DeployResult, ModeLauncher } from './types.js';
4
+ /**
5
+ * External-resolver bundle the orchestrator depends on. Each field has a
6
+ * real default backed by env (or, for `bundle`/`modes`, the real
7
+ * launchers). Callers override individual fields to plug in higher-level
8
+ * implementations: a CLI dispatch case may pass an `IntegrationResolver`
9
+ * backed by `@relayfile/sdk`'s OAuth flow once it is available, tests
10
+ * pass deterministic in-memory fakes.
11
+ */
12
+ export interface DeployResolvers {
13
+ workspaceAuth?: WorkspaceAuth;
14
+ integrations?: IntegrationConnectResolver;
15
+ subscription?: ProviderSubscriptionResolver;
16
+ bundle?: BundleStager;
17
+ modes?: Partial<Record<DeployMode, ModeLauncher>>;
18
+ }
19
+ /**
20
+ * Pick the run mode for this deploy. Per the deploy-v1 spec:
21
+ * - Explicit `--mode` always wins.
22
+ * - Otherwise `--mode sandbox` is the default when Daytona creds resolve
23
+ * (BYO env or workforce-managed both count as "resolved" here; the
24
+ * sandbox launcher itself decides which auth path to use).
25
+ * - Otherwise fall back to `--mode dev`.
26
+ *
27
+ * The orchestrator doesn't probe the cloud endpoint here — `--mode cloud`
28
+ * stays opt-in until the M4 endpoint is live.
29
+ */
30
+ export declare function pickMode(opts: DeployOptions): DeployMode;
31
+ /**
32
+ * Top-level entry. The CLI dispatch case calls this with parsed options
33
+ * and resolvers. Returns a `DeployResult` summarizing the deploy; on
34
+ * failure, throws with an actionable message (no half-deploys).
35
+ *
36
+ * Step ordering — see `docs/plans/deploy-v1.md` §5:
37
+ * 1. Preflight persona (parse, lint, onEvent on disk).
38
+ * 2. Resolve workspace + token.
39
+ * 3. Connect integrations (prompt per provider).
40
+ * 4. Stage bundle to `.workforce/build/<id>/`.
41
+ * 5. Launch in the resolved mode.
42
+ * 6. Return the handle + summary.
43
+ *
44
+ * `dryRun: true` exits cleanly after step 1, returning a minimal result
45
+ * with the warnings collected so far.
46
+ *
47
+ * `bundleOut: <dir>` runs steps 1-4 then exits, skipping launch.
48
+ */
49
+ export declare function deploy(opts: DeployOptions, resolvers?: DeployResolvers): Promise<DeployResult>;
50
+ //# sourceMappingURL=deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EAClC,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAKlE,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,0BAA0B,CAAC;IAC1C,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;CACnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAQxD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,GAAE,eAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAsHxG"}