@ai-support-agent/cli 0.1.35-beta.0 → 0.1.35

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 (61) hide show
  1. package/dist/api-client.d.ts +1 -6
  2. package/dist/api-client.d.ts.map +1 -1
  3. package/dist/api-client.js +0 -9
  4. package/dist/api-client.js.map +1 -1
  5. package/dist/commands/index.d.ts.map +1 -1
  6. package/dist/commands/index.js +0 -44
  7. package/dist/commands/index.js.map +1 -1
  8. package/dist/constants.d.ts +0 -30
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/constants.js +2 -37
  11. package/dist/constants.js.map +1 -1
  12. package/dist/index.js +1 -17
  13. package/dist/index.js.map +1 -1
  14. package/dist/locales/en.json +0 -18
  15. package/dist/locales/ja.json +0 -18
  16. package/dist/project-agent.d.ts.map +1 -1
  17. package/dist/project-agent.js +1 -13
  18. package/dist/project-agent.js.map +1 -1
  19. package/dist/types/command.d.ts +1 -8
  20. package/dist/types/command.d.ts.map +1 -1
  21. package/dist/types/command.js.map +1 -1
  22. package/dist/types/config.d.ts +0 -6
  23. package/dist/types/config.d.ts.map +1 -1
  24. package/dist/types/index.d.ts +0 -1
  25. package/dist/types/index.d.ts.map +1 -1
  26. package/dist/types/index.js +0 -1
  27. package/dist/types/index.js.map +1 -1
  28. package/docker/entrypoint.sh +0 -9
  29. package/package.json +1 -6
  30. package/dist/cli/ecs-publish-command.d.ts +0 -49
  31. package/dist/cli/ecs-publish-command.d.ts.map +0 -1
  32. package/dist/cli/ecs-publish-command.js +0 -214
  33. package/dist/cli/ecs-publish-command.js.map +0 -1
  34. package/dist/ecs/aws-arn.d.ts +0 -30
  35. package/dist/ecs/aws-arn.d.ts.map +0 -1
  36. package/dist/ecs/aws-arn.js +0 -36
  37. package/dist/ecs/aws-arn.js.map +0 -1
  38. package/dist/ecs/ecr-publisher.d.ts +0 -49
  39. package/dist/ecs/ecr-publisher.d.ts.map +0 -1
  40. package/dist/ecs/ecr-publisher.js +0 -118
  41. package/dist/ecs/ecr-publisher.js.map +0 -1
  42. package/dist/ecs/ecs-launcher.d.ts +0 -25
  43. package/dist/ecs/ecs-launcher.d.ts.map +0 -1
  44. package/dist/ecs/ecs-launcher.js +0 -157
  45. package/dist/ecs/ecs-launcher.js.map +0 -1
  46. package/dist/ecs/launcher-capability.d.ts +0 -26
  47. package/dist/ecs/launcher-capability.d.ts.map +0 -1
  48. package/dist/ecs/launcher-capability.js +0 -86
  49. package/dist/ecs/launcher-capability.js.map +0 -1
  50. package/dist/ecs/task-definition-registrar.d.ts +0 -39
  51. package/dist/ecs/task-definition-registrar.d.ts.map +0 -1
  52. package/dist/ecs/task-definition-registrar.js +0 -80
  53. package/dist/ecs/task-definition-registrar.js.map +0 -1
  54. package/dist/oneshot-runner.d.ts +0 -38
  55. package/dist/oneshot-runner.d.ts.map +0 -1
  56. package/dist/oneshot-runner.js +0 -166
  57. package/dist/oneshot-runner.js.map +0 -1
  58. package/dist/types/ecs.d.ts +0 -71
  59. package/dist/types/ecs.d.ts.map +0 -1
  60. package/dist/types/ecs.js +0 -12
  61. package/dist/types/ecs.js.map +0 -1
@@ -1,118 +0,0 @@
1
- "use strict";
2
- /**
3
- * ECR image publisher for `ecs publish`.
4
- *
5
- * Logs in to ECR with the local AWS credentials (GetAuthorizationToken),
6
- * builds/tags/pushes the image with the docker CLI, and resolves the pushed
7
- * image digest via DescribeImages so the task definition can pin the image
8
- * by digest. The registry password is always passed over stdin
9
- * (`--password-stdin`), never on the command line.
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.runDocker = runDocker;
13
- exports.loginToEcr = loginToEcr;
14
- exports.getImageDigest = getImageDigest;
15
- exports.publishImage = publishImage;
16
- const child_process_1 = require("child_process");
17
- const client_ecr_1 = require("@aws-sdk/client-ecr");
18
- const aws_arn_1 = require("./aws-arn");
19
- const docker_utils_1 = require("../docker/docker-utils");
20
- const logger_1 = require("../logger");
21
- const utils_1 = require("../utils");
22
- /**
23
- * Run a docker CLI command. Output is streamed to the terminal.
24
- * When `input` is provided it is written to the child's stdin (used for
25
- * `docker login --password-stdin` so the password never appears in argv).
26
- */
27
- function runDocker(args, input) {
28
- return new Promise((resolve, reject) => {
29
- const proc = (0, child_process_1.spawn)((0, docker_utils_1.getDockerPath)(), args, {
30
- stdio: [input === undefined ? 'ignore' : 'pipe', 'inherit', 'inherit'],
31
- });
32
- if (input !== undefined && proc.stdin) {
33
- // If the child dies between spawn and write (e.g. `docker login` fails
34
- // instantly), writing to its stdin raises EPIPE. Swallow it here and let
35
- // the 'close'/'error' handlers report the real exit code instead of
36
- // surfacing an uncaught EPIPE.
37
- proc.stdin.on('error', () => { });
38
- proc.stdin.write(input);
39
- proc.stdin.end();
40
- }
41
- proc.on('error', (err) => reject((0, utils_1.toError)(err)));
42
- proc.on('close', (code) => {
43
- if (code === 0)
44
- resolve();
45
- else
46
- reject(new Error(`docker ${args[0]} exited with code ${code}`));
47
- });
48
- });
49
- }
50
- /**
51
- * Log in the local docker CLI to the ECR registry using GetAuthorizationToken.
52
- * The decoded password is piped to `docker login --password-stdin`.
53
- */
54
- async function loginToEcr(client, registry) {
55
- logger_1.logger.info(`[ecs] Logging in to ECR registry: ${registry}`);
56
- const response = await client.send(new client_ecr_1.GetAuthorizationTokenCommand({}));
57
- const token = response.authorizationData?.[0]?.authorizationToken;
58
- if (!token) {
59
- throw new Error('ECR GetAuthorizationToken returned no authorization data');
60
- }
61
- const decoded = Buffer.from(token, 'base64').toString('utf-8');
62
- const separator = decoded.indexOf(':');
63
- if (separator < 0) {
64
- throw new Error('ECR authorization token has an unexpected format');
65
- }
66
- const username = decoded.slice(0, separator);
67
- const password = decoded.slice(separator + 1);
68
- await runDocker(['login', '--username', username, '--password-stdin', registry], password);
69
- logger_1.logger.success(`[ecs] Logged in to ${registry}`);
70
- }
71
- /**
72
- * Resolve the digest of a pushed image tag via DescribeImages.
73
- */
74
- async function getImageDigest(client, repositoryName, tag) {
75
- const response = await client.send(new client_ecr_1.DescribeImagesCommand({
76
- repositoryName,
77
- imageIds: [{ imageTag: tag }],
78
- }));
79
- const digest = response.imageDetails?.[0]?.imageDigest;
80
- if (!digest) {
81
- throw new Error(`Could not resolve image digest for ${repositoryName}:${tag}`);
82
- }
83
- return digest;
84
- }
85
- /**
86
- * Build (unless a local image is given), tag, and push the image to ECR,
87
- * then return the digest-pinned image URI.
88
- */
89
- async function publishImage(options) {
90
- const parts = (0, aws_arn_1.parseEcrRepositoryUri)(options.repositoryUri);
91
- if (!parts) {
92
- throw new Error(`Invalid ECR repository URI: ${options.repositoryUri}`);
93
- }
94
- const client = new client_ecr_1.ECRClient({ region: parts.region });
95
- await loginToEcr(client, parts.registry);
96
- const remoteRef = `${options.repositoryUri}:${options.tag}`;
97
- if (options.image) {
98
- logger_1.logger.info(`[ecs] Using local image ${options.image} (build skipped)`);
99
- await runDocker(['tag', options.image, remoteRef]);
100
- }
101
- else {
102
- const contextDir = options.contextDir ?? '.';
103
- const buildArgs = ['build', '-t', remoteRef];
104
- if (options.dockerfile) {
105
- buildArgs.push('-f', options.dockerfile);
106
- }
107
- buildArgs.push(contextDir);
108
- logger_1.logger.info(`[ecs] Building image ${remoteRef}`);
109
- await runDocker(buildArgs);
110
- }
111
- logger_1.logger.info(`[ecs] Pushing ${remoteRef}`);
112
- await runDocker(['push', remoteRef]);
113
- const imageDigest = await getImageDigest(client, parts.repositoryName, options.tag);
114
- const imageUri = `${options.repositoryUri}@${imageDigest}`;
115
- logger_1.logger.success(`[ecs] Pushed image: ${imageUri}`);
116
- return { imageUri, imageTag: options.tag, imageDigest };
117
- }
118
- //# sourceMappingURL=ecr-publisher.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ecr-publisher.js","sourceRoot":"","sources":["../../src/ecs/ecr-publisher.ts"],"names":[],"mappings":"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"}
@@ -1,25 +0,0 @@
1
- /**
2
- * Launcher-side handlers for the `ecs_launch` / `ecs_stop` commands.
3
- *
4
- * A resident agent with local AWS credentials acts as the "launcher": it
5
- * receives `ecs_launch` via the normal dispatch path (AppSync) and starts a
6
- * oneshot ECS task with RunTask, injecting the per-run environment
7
- * (COMMAND_ID, oneshot token, ...) through containerOverrides.
8
- *
9
- * SECURITY: the containerEnv payload contains AGENT_ONESHOT_TOKEN. Its
10
- * values must never be logged — only log resource identifiers.
11
- */
12
- import { type CommandResult } from '../types';
13
- /**
14
- * Handle the `ecs_launch` command: RunTask (FARGATE, awsvpc) with the
15
- * payload's containerEnv injected via containerOverrides.
16
- * Returns `{ taskArn }` on success, or a failed result carrying RunTask
17
- * `failures` details so the API can mark the work command/task as failed.
18
- */
19
- export declare function ecsLaunch(p: Record<string, unknown>): Promise<CommandResult>;
20
- /**
21
- * Handle the `ecs_stop` command: best-effort StopTask (used by the API's
22
- * timeout sweep to reclaim timed-out oneshot containers).
23
- */
24
- export declare function ecsStop(p: Record<string, unknown>): Promise<CommandResult>;
25
- //# sourceMappingURL=ecs-launcher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ecs-launcher.d.ts","sourceRoot":"","sources":["../../src/ecs/ecs-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EAAE,KAAK,aAAa,EAA8B,MAAM,UAAU,CAAA;AAkDzE;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAyDlF;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CA6BhF"}
@@ -1,157 +0,0 @@
1
- "use strict";
2
- /**
3
- * Launcher-side handlers for the `ecs_launch` / `ecs_stop` commands.
4
- *
5
- * A resident agent with local AWS credentials acts as the "launcher": it
6
- * receives `ecs_launch` via the normal dispatch path (AppSync) and starts a
7
- * oneshot ECS task with RunTask, injecting the per-run environment
8
- * (COMMAND_ID, oneshot token, ...) through containerOverrides.
9
- *
10
- * SECURITY: the containerEnv payload contains AGENT_ONESHOT_TOKEN. Its
11
- * values must never be logged — only log resource identifiers.
12
- */
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.ecsLaunch = ecsLaunch;
15
- exports.ecsStop = ecsStop;
16
- const client_ecs_1 = require("@aws-sdk/client-ecs");
17
- const aws_arn_1 = require("./aws-arn");
18
- const constants_1 = require("../constants");
19
- const logger_1 = require("../logger");
20
- const types_1 = require("../types");
21
- const utils_1 = require("../utils");
22
- function parseStringArray(value) {
23
- if (!Array.isArray(value) || value.length === 0)
24
- return null;
25
- if (!value.every((v) => typeof v === 'string' && v.length > 0))
26
- return null;
27
- return value;
28
- }
29
- function validateLaunchPayload(p) {
30
- const taskDefinitionArn = typeof p.taskDefinitionArn === 'string' && p.taskDefinitionArn ? p.taskDefinitionArn : null;
31
- if (!taskDefinitionArn)
32
- return 'taskDefinitionArn is required for ecs_launch';
33
- const clusterArn = typeof p.clusterArn === 'string' && p.clusterArn ? p.clusterArn : null;
34
- if (!clusterArn)
35
- return 'clusterArn is required for ecs_launch';
36
- const subnetIds = parseStringArray(p.subnetIds);
37
- if (!subnetIds)
38
- return 'subnetIds (non-empty string array) is required for ecs_launch';
39
- const securityGroupIds = parseStringArray(p.securityGroupIds);
40
- if (!securityGroupIds)
41
- return 'securityGroupIds (non-empty string array) is required for ecs_launch';
42
- const rawEnv = p.containerEnv;
43
- if (typeof rawEnv !== 'object' || rawEnv === null || Array.isArray(rawEnv)) {
44
- return 'containerEnv (object) is required for ecs_launch';
45
- }
46
- const containerEnv = {};
47
- for (const [key, value] of Object.entries(rawEnv)) {
48
- if (typeof value !== 'string') {
49
- return `containerEnv.${key} must be a string`;
50
- }
51
- containerEnv[key] = value;
52
- }
53
- return {
54
- taskDefinitionArn,
55
- clusterArn,
56
- subnetIds,
57
- securityGroupIds,
58
- assignPublicIp: p.assignPublicIp === true,
59
- containerEnv,
60
- };
61
- }
62
- /**
63
- * Handle the `ecs_launch` command: RunTask (FARGATE, awsvpc) with the
64
- * payload's containerEnv injected via containerOverrides.
65
- * Returns `{ taskArn }` on success, or a failed result carrying RunTask
66
- * `failures` details so the API can mark the work command/task as failed.
67
- */
68
- async function ecsLaunch(p) {
69
- const validated = validateLaunchPayload(p);
70
- if (typeof validated === 'string') {
71
- return (0, types_1.errorResult)(validated);
72
- }
73
- const region = (0, aws_arn_1.regionFromArn)(validated.clusterArn);
74
- if (!region) {
75
- return (0, types_1.errorResult)(`Could not determine region from clusterArn: ${validated.clusterArn}`);
76
- }
77
- // Do NOT log containerEnv — it carries AGENT_ONESHOT_TOKEN.
78
- logger_1.logger.info(`[ecs] RunTask: taskDefinition=${validated.taskDefinitionArn} cluster=${validated.clusterArn}`);
79
- try {
80
- const client = new client_ecs_1.ECSClient({ region });
81
- const response = await client.send(new client_ecs_1.RunTaskCommand({
82
- cluster: validated.clusterArn,
83
- taskDefinition: validated.taskDefinitionArn,
84
- launchType: 'FARGATE',
85
- count: 1,
86
- networkConfiguration: {
87
- awsvpcConfiguration: {
88
- subnets: validated.subnetIds,
89
- securityGroups: validated.securityGroupIds,
90
- assignPublicIp: validated.assignPublicIp ? 'ENABLED' : 'DISABLED',
91
- },
92
- },
93
- overrides: {
94
- containerOverrides: [
95
- {
96
- name: constants_1.ECS_AGENT_CONTAINER_NAME,
97
- environment: Object.entries(validated.containerEnv).map(([name, value]) => ({ name, value })),
98
- },
99
- ],
100
- },
101
- }));
102
- if (response.failures && response.failures.length > 0) {
103
- const reasons = response.failures
104
- .map((f) => `${f.reason ?? 'unknown'}${f.detail ? ` (${f.detail})` : ''}`)
105
- .join('; ');
106
- logger_1.logger.error(`[ecs] RunTask failed: ${reasons}`);
107
- return (0, types_1.errorResult)(`ECS RunTask failed: ${reasons}`, { failures: response.failures });
108
- }
109
- const taskArn = response.tasks?.[0]?.taskArn;
110
- if (!taskArn) {
111
- return (0, types_1.errorResult)('ECS RunTask returned no task');
112
- }
113
- logger_1.logger.success(`[ecs] Task started: ${taskArn}`);
114
- return (0, types_1.successResult)({ taskArn });
115
- }
116
- catch (error) {
117
- const message = (0, utils_1.getErrorMessage)(error);
118
- logger_1.logger.error(`[ecs] RunTask error: ${message}`);
119
- return (0, types_1.errorResult)(`ECS RunTask error: ${message}`);
120
- }
121
- }
122
- /**
123
- * Handle the `ecs_stop` command: best-effort StopTask (used by the API's
124
- * timeout sweep to reclaim timed-out oneshot containers).
125
- */
126
- async function ecsStop(p) {
127
- const clusterArn = typeof p.clusterArn === 'string' && p.clusterArn ? p.clusterArn : null;
128
- if (!clusterArn)
129
- return (0, types_1.errorResult)('clusterArn is required for ecs_stop');
130
- const taskArn = typeof p.taskArn === 'string' && p.taskArn ? p.taskArn : null;
131
- if (!taskArn)
132
- return (0, types_1.errorResult)('taskArn is required for ecs_stop');
133
- const region = (0, aws_arn_1.regionFromArn)(clusterArn);
134
- if (!region) {
135
- return (0, types_1.errorResult)(`Could not determine region from clusterArn: ${clusterArn}`);
136
- }
137
- logger_1.logger.info(`[ecs] StopTask: ${taskArn}`);
138
- try {
139
- const client = new client_ecs_1.ECSClient({ region });
140
- const response = await client.send(new client_ecs_1.StopTaskCommand({
141
- cluster: clusterArn,
142
- task: taskArn,
143
- reason: 'Stopped by ai-support-agent launcher (timeout or cancel)',
144
- }));
145
- return (0, types_1.successResult)({
146
- stopped: true,
147
- taskArn,
148
- lastStatus: response.task?.lastStatus,
149
- });
150
- }
151
- catch (error) {
152
- const message = (0, utils_1.getErrorMessage)(error);
153
- logger_1.logger.warn(`[ecs] StopTask failed (best-effort): ${message}`);
154
- return (0, types_1.errorResult)(`ECS StopTask failed: ${message}`, { stopped: false, taskArn });
155
- }
156
- }
157
- //# sourceMappingURL=ecs-launcher.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ecs-launcher.js","sourceRoot":"","sources":["../../src/ecs/ecs-launcher.ts"],"names":[],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- /**
2
- * ecs_launch capability detection.
3
- *
4
- * A resident agent should only advertise the `ecs_launch` capability when it
5
- * can actually perform ECS RunTask/StopTask — i.e. when AWS credentials are
6
- * resolvable through the default provider chain (env vars, shared
7
- * config/credentials files, SSO cache, IMDS/ECS metadata, ...). Advertising
8
- * it unconditionally would let the API's automatic launcher selection pick an
9
- * agent that cannot launch anything, making ECS dispatch fail unpredictably.
10
- *
11
- * Override (checked before detection):
12
- * AI_SUPPORT_AGENT_ECS_LAUNCHER=true force-enable, skip detection
13
- * AI_SUPPORT_AGENT_ECS_LAUNCHER=false force-disable, skip detection
14
- *
15
- * The detection result is cached for the process lifetime so the register
16
- * retry loop does not re-probe the credential chain (IMDS/STS) on every
17
- * attempt.
18
- */
19
- /** Reset the positive-detection cache (tests only). */
20
- export declare function resetEcsLauncherCapabilityCache(): void;
21
- /**
22
- * Decide whether this agent should advertise the `ecs_launch` capability.
23
- * Returns true when credentials are resolvable or force-enabled via env.
24
- */
25
- export declare function detectEcsLauncherCapability(env?: NodeJS.ProcessEnv, timeoutMs?: number): Promise<boolean>;
26
- //# sourceMappingURL=launcher-capability.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"launcher-capability.d.ts","sourceRoot":"","sources":["../../src/ecs/launcher-capability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAeH,uDAAuD;AACvD,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAuBD;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,GAAE,MAAuC,GACjD,OAAO,CAAC,OAAO,CAAC,CAyBlB"}
@@ -1,86 +0,0 @@
1
- "use strict";
2
- /**
3
- * ecs_launch capability detection.
4
- *
5
- * A resident agent should only advertise the `ecs_launch` capability when it
6
- * can actually perform ECS RunTask/StopTask — i.e. when AWS credentials are
7
- * resolvable through the default provider chain (env vars, shared
8
- * config/credentials files, SSO cache, IMDS/ECS metadata, ...). Advertising
9
- * it unconditionally would let the API's automatic launcher selection pick an
10
- * agent that cannot launch anything, making ECS dispatch fail unpredictably.
11
- *
12
- * Override (checked before detection):
13
- * AI_SUPPORT_AGENT_ECS_LAUNCHER=true force-enable, skip detection
14
- * AI_SUPPORT_AGENT_ECS_LAUNCHER=false force-disable, skip detection
15
- *
16
- * The detection result is cached for the process lifetime so the register
17
- * retry loop does not re-probe the credential chain (IMDS/STS) on every
18
- * attempt.
19
- */
20
- Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.resetEcsLauncherCapabilityCache = resetEcsLauncherCapabilityCache;
22
- exports.detectEcsLauncherCapability = detectEcsLauncherCapability;
23
- const credential_providers_1 = require("@aws-sdk/credential-providers");
24
- const constants_1 = require("../constants");
25
- const logger_1 = require("../logger");
26
- const utils_1 = require("../utils");
27
- // Only a POSITIVE detection is cached for the process lifetime. A negative
28
- // result (e.g. a transient 3s IMDS timeout during cold start) must NOT be
29
- // sticky, or credentials that become available later would never be picked
30
- // up. Re-detection on subsequent register attempts is safe because the
31
- // register loop is backoff-based, so this cannot spam STS/IMDS.
32
- let credentialsConfirmed = false;
33
- /** Reset the positive-detection cache (tests only). */
34
- function resetEcsLauncherCapabilityCache() {
35
- credentialsConfirmed = false;
36
- }
37
- async function credentialsResolvable(timeoutMs) {
38
- let timer;
39
- try {
40
- const timeout = new Promise((_, reject) => {
41
- timer = setTimeout(() => reject(new Error(`credential resolution timed out after ${timeoutMs}ms`)), timeoutMs);
42
- timer.unref?.();
43
- });
44
- const credentials = await Promise.race([(0, credential_providers_1.fromNodeProviderChain)()(), timeout]);
45
- // Never log the credential values — only whether resolution succeeded.
46
- return Boolean(credentials?.accessKeyId);
47
- }
48
- catch (error) {
49
- logger_1.logger.info(`[ecs] AWS credentials not resolvable: ${(0, utils_1.getErrorMessage)(error)}`);
50
- return false;
51
- }
52
- finally {
53
- if (timer)
54
- clearTimeout(timer);
55
- }
56
- }
57
- /**
58
- * Decide whether this agent should advertise the `ecs_launch` capability.
59
- * Returns true when credentials are resolvable or force-enabled via env.
60
- */
61
- async function detectEcsLauncherCapability(env = process.env, timeoutMs = constants_1.ECS_LAUNCHER_DETECT_TIMEOUT_MS) {
62
- const override = env[constants_1.ENV_VARS.ECS_LAUNCHER];
63
- if (override === 'false') {
64
- logger_1.logger.info(`[ecs] ecs_launch capability disabled (${constants_1.ENV_VARS.ECS_LAUNCHER}=false)`);
65
- return false;
66
- }
67
- if (override === 'true') {
68
- logger_1.logger.info(`[ecs] ecs_launch capability force-enabled (${constants_1.ENV_VARS.ECS_LAUNCHER}=true, credential detection skipped)`);
69
- return true;
70
- }
71
- // A confirmed positive is sticky; a previous negative falls through to a
72
- // fresh probe on the next call.
73
- if (credentialsConfirmed) {
74
- return true;
75
- }
76
- const resolved = await credentialsResolvable(timeoutMs);
77
- if (resolved) {
78
- credentialsConfirmed = true;
79
- logger_1.logger.info('[ecs] AWS credentials resolved; advertising ecs_launch capability');
80
- }
81
- else {
82
- logger_1.logger.info('[ecs] ecs_launch capability not advertised (no resolvable AWS credentials; will re-check on next registration)');
83
- }
84
- return resolved;
85
- }
86
- //# sourceMappingURL=launcher-capability.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"launcher-capability.js","sourceRoot":"","sources":["../../src/ecs/launcher-capability.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;AAgBH,0EAEC;AA2BD,kEA4BC;AAvED,wEAAqE;AAErE,4CAAuE;AACvE,sCAAkC;AAClC,oCAA0C;AAE1C,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,uEAAuE;AACvE,gEAAgE;AAChE,IAAI,oBAAoB,GAAG,KAAK,CAAA;AAEhC,uDAAuD;AACvD,SAAgB,+BAA+B;IAC7C,oBAAoB,GAAG,KAAK,CAAA;AAC9B,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,SAAiB;IACpD,IAAI,KAAiC,CAAA;IACrC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;YAC/C,KAAK,GAAG,UAAU,CAChB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yCAAyC,SAAS,IAAI,CAAC,CAAC,EAC/E,SAAS,CACV,CAAA;YACD,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;QACjB,CAAC,CAAC,CAAA;QACF,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAA,4CAAqB,GAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;QAC5E,uEAAuE;QACvE,OAAO,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,IAAI,CAAC,yCAAyC,IAAA,uBAAe,EAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC9E,OAAO,KAAK,CAAA;IACd,CAAC;YAAS,CAAC;QACT,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;AACH,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,2BAA2B,CAC/C,MAAyB,OAAO,CAAC,GAAG,EACpC,YAAoB,0CAA8B;IAElD,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAQ,CAAC,YAAY,CAAC,CAAA;IAC3C,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,eAAM,CAAC,IAAI,CAAC,yCAAyC,oBAAQ,CAAC,YAAY,SAAS,CAAC,CAAA;QACpF,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,eAAM,CAAC,IAAI,CAAC,8CAA8C,oBAAQ,CAAC,YAAY,sCAAsC,CAAC,CAAA;QACtH,OAAO,IAAI,CAAA;IACb,CAAC;IAED,yEAAyE;IACzE,gCAAgC;IAChC,IAAI,oBAAoB,EAAE,CAAC;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,SAAS,CAAC,CAAA;IACvD,IAAI,QAAQ,EAAE,CAAC;QACb,oBAAoB,GAAG,IAAI,CAAA;QAC3B,eAAM,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAA;IAClF,CAAC;SAAM,CAAC;QACN,eAAM,CAAC,IAAI,CAAC,gHAAgH,CAAC,CAAA;IAC/H,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
@@ -1,39 +0,0 @@
1
- /**
2
- * ECS task definition registrar for `ecs publish`.
3
- *
4
- * Registers a Fargate task definition for the ECS execution agent:
5
- * - image pinned by digest (`<repo>@sha256:...`)
6
- * - awslogs log driver (log group created when missing)
7
- * - NO environment variables in the task definition — COMMAND_ID, the
8
- * oneshot token, etc. are injected per run via containerOverrides.
9
- */
10
- import { CloudWatchLogsClient } from '@aws-sdk/client-cloudwatch-logs';
11
- export interface RegisterEcsTaskDefinitionOptions {
12
- /** Task definition family: ai-support-ecs-agent-{tenantCode}-{agentId} */
13
- family: string;
14
- /** Digest-pinned image URI */
15
- imageUri: string;
16
- cpu: number;
17
- memory: number;
18
- region: string;
19
- logGroupName: string;
20
- /** Task execution role (required by Fargate for ECR pull / awslogs) */
21
- executionRoleArn?: string;
22
- /** Task role assumed by the container itself */
23
- taskRoleArn?: string;
24
- }
25
- export interface RegisteredTaskDefinition {
26
- taskDefinitionArn: string;
27
- family: string;
28
- revision: number;
29
- }
30
- /**
31
- * Create the awslogs log group when it does not exist.
32
- * ResourceAlreadyExistsException is tolerated (idempotent).
33
- */
34
- export declare function ensureLogGroup(client: CloudWatchLogsClient, logGroupName: string): Promise<void>;
35
- /**
36
- * Register the Fargate task definition and return its ARN.
37
- */
38
- export declare function registerTaskDefinition(options: RegisterEcsTaskDefinitionOptions): Promise<RegisteredTaskDefinition>;
39
- //# sourceMappingURL=task-definition-registrar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-definition-registrar.d.ts","sourceRoot":"","sources":["../../src/ecs/task-definition-registrar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,oBAAoB,EAErB,MAAM,iCAAiC,CAAA;AAMxC,MAAM,WAAW,gCAAgC;IAC/C,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,iBAAiB,EAAE,MAAM,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,oBAAoB,EAC5B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,wBAAwB,CAAC,CA0CnC"}
@@ -1,80 +0,0 @@
1
- "use strict";
2
- /**
3
- * ECS task definition registrar for `ecs publish`.
4
- *
5
- * Registers a Fargate task definition for the ECS execution agent:
6
- * - image pinned by digest (`<repo>@sha256:...`)
7
- * - awslogs log driver (log group created when missing)
8
- * - NO environment variables in the task definition — COMMAND_ID, the
9
- * oneshot token, etc. are injected per run via containerOverrides.
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.ensureLogGroup = ensureLogGroup;
13
- exports.registerTaskDefinition = registerTaskDefinition;
14
- const client_cloudwatch_logs_1 = require("@aws-sdk/client-cloudwatch-logs");
15
- const client_ecs_1 = require("@aws-sdk/client-ecs");
16
- const constants_1 = require("../constants");
17
- const logger_1 = require("../logger");
18
- /**
19
- * Create the awslogs log group when it does not exist.
20
- * ResourceAlreadyExistsException is tolerated (idempotent).
21
- */
22
- async function ensureLogGroup(client, logGroupName) {
23
- try {
24
- await client.send(new client_cloudwatch_logs_1.CreateLogGroupCommand({ logGroupName }));
25
- logger_1.logger.info(`[ecs] Created log group: ${logGroupName}`);
26
- }
27
- catch (error) {
28
- const name = error.name;
29
- if (name === 'ResourceAlreadyExistsException') {
30
- logger_1.logger.debug(`[ecs] Log group already exists: ${logGroupName}`);
31
- return;
32
- }
33
- throw error;
34
- }
35
- }
36
- /**
37
- * Register the Fargate task definition and return its ARN.
38
- */
39
- async function registerTaskDefinition(options) {
40
- const logsClient = new client_cloudwatch_logs_1.CloudWatchLogsClient({ region: options.region });
41
- await ensureLogGroup(logsClient, options.logGroupName);
42
- const ecsClient = new client_ecs_1.ECSClient({ region: options.region });
43
- const response = await ecsClient.send(new client_ecs_1.RegisterTaskDefinitionCommand({
44
- family: options.family,
45
- requiresCompatibilities: ['FARGATE'],
46
- networkMode: 'awsvpc',
47
- cpu: String(options.cpu),
48
- memory: String(options.memory),
49
- ...(options.executionRoleArn && { executionRoleArn: options.executionRoleArn }),
50
- ...(options.taskRoleArn && { taskRoleArn: options.taskRoleArn }),
51
- containerDefinitions: [
52
- {
53
- name: constants_1.ECS_AGENT_CONTAINER_NAME,
54
- image: options.imageUri,
55
- essential: true,
56
- // No environment variables here: they are injected at RunTask time
57
- // via containerOverrides so secrets never persist in the definition.
58
- logConfiguration: {
59
- logDriver: 'awslogs',
60
- options: {
61
- 'awslogs-group': options.logGroupName,
62
- 'awslogs-region': options.region,
63
- 'awslogs-stream-prefix': 'ecs-agent',
64
- },
65
- },
66
- },
67
- ],
68
- }));
69
- const taskDefinition = response.taskDefinition;
70
- if (!taskDefinition?.taskDefinitionArn) {
71
- throw new Error('ECS RegisterTaskDefinition returned no task definition ARN');
72
- }
73
- logger_1.logger.success(`[ecs] Registered task definition: ${taskDefinition.taskDefinitionArn}`);
74
- return {
75
- taskDefinitionArn: taskDefinition.taskDefinitionArn,
76
- family: taskDefinition.family ?? options.family,
77
- revision: taskDefinition.revision ?? 0,
78
- };
79
- }
80
- //# sourceMappingURL=task-definition-registrar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-definition-registrar.js","sourceRoot":"","sources":["../../src/ecs/task-definition-registrar.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAoCH,wCAeC;AAKD,wDA4CC;AAlGD,4EAGwC;AACxC,oDAA8E;AAE9E,4CAAuD;AACvD,sCAAkC;AAuBlC;;;GAGG;AACI,KAAK,UAAU,cAAc,CAClC,MAA4B,EAC5B,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,8CAAqB,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAA;QAC9D,eAAM,CAAC,IAAI,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAA;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAI,KAA2B,CAAC,IAAI,CAAA;QAC9C,IAAI,IAAI,KAAK,gCAAgC,EAAE,CAAC;YAC9C,eAAM,CAAC,KAAK,CAAC,mCAAmC,YAAY,EAAE,CAAC,CAAA;YAC/D,OAAM;QACR,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,sBAAsB,CAC1C,OAAyC;IAEzC,MAAM,UAAU,GAAG,IAAI,6CAAoB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACvE,MAAM,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAEtD,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAC3D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,0CAA6B,CAAC;QACtE,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,uBAAuB,EAAE,CAAC,SAAS,CAAC;QACpC,WAAW,EAAE,QAAQ;QACrB,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9B,GAAG,CAAC,OAAO,CAAC,gBAAgB,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC/E,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;QAChE,oBAAoB,EAAE;YACpB;gBACE,IAAI,EAAE,oCAAwB;gBAC9B,KAAK,EAAE,OAAO,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI;gBACf,mEAAmE;gBACnE,qEAAqE;gBACrE,gBAAgB,EAAE;oBAChB,SAAS,EAAE,SAAS;oBACpB,OAAO,EAAE;wBACP,eAAe,EAAE,OAAO,CAAC,YAAY;wBACrC,gBAAgB,EAAE,OAAO,CAAC,MAAM;wBAChC,uBAAuB,EAAE,WAAW;qBACrC;iBACF;aACF;SACF;KACF,CAAC,CAAC,CAAA;IAEH,MAAM,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAA;IAC9C,IAAI,CAAC,cAAc,EAAE,iBAAiB,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAC/E,CAAC;IACD,eAAM,CAAC,OAAO,CAAC,qCAAqC,cAAc,CAAC,iBAAiB,EAAE,CAAC,CAAA;IACvF,OAAO;QACL,iBAAiB,EAAE,cAAc,CAAC,iBAAiB;QACnD,MAAM,EAAE,cAAc,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM;QAC/C,QAAQ,EAAE,cAAc,CAAC,QAAQ,IAAI,CAAC;KACvC,CAAA;AACH,CAAC"}
@@ -1,38 +0,0 @@
1
- /**
2
- * Oneshot runner (ECS container mode).
3
- *
4
- * When the CLI starts with AGENT_MODE=oneshot (set via containerOverrides at
5
- * ECS RunTask time), it does NOT run the resident agent flow. Instead it:
6
- * getCommand(COMMAND_ID) -> executeCommand -> submitResult -> exit
7
- *
8
- * There is no AppSync subscription, no heartbeat, and no register call.
9
- * Authentication uses the short-lived oneshot token (AGENT_ONESHOT_TOKEN)
10
- * scoped to the single COMMAND_ID. The token value is never logged.
11
- */
12
- interface OneshotEnv {
13
- commandId: string;
14
- agentId: string;
15
- tenantCode: string;
16
- projectCode: string;
17
- apiBaseUrl: string;
18
- token: string;
19
- }
20
- /**
21
- * Read and validate the oneshot environment.
22
- * Missing variables are a clear fatal error (no fallback).
23
- */
24
- export declare function readOneshotEnv(env?: NodeJS.ProcessEnv): OneshotEnv;
25
- /**
26
- * Run exactly one command and return the process exit code
27
- * (0 = executed and submitted successfully, 1 = any failure).
28
- */
29
- export declare function runOneshot(env?: NodeJS.ProcessEnv): Promise<number>;
30
- /**
31
- * Entry-point wrapper used by src/index.ts: runs the oneshot flow and exits
32
- * the process with the resulting code. Any unexpected rejection is converted
33
- * into exit code 1 — a container that never exits would only be reclaimed by
34
- * the slow timeout sweep. The runner is injectable for tests.
35
- */
36
- export declare function runOneshotFromEnv(runner?: () => Promise<number>): Promise<void>;
37
- export {};
38
- //# sourceMappingURL=oneshot-runner.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oneshot-runner.d.ts","sourceRoot":"","sources":["../src/oneshot-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAqCH,UAAU,UAAU;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,UAAU,CAa/E;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFtF;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,GAAE,MAAM,OAAO,CAAC,MAAM,CAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CASjG"}