@agentage/extension 0.0.0-stage → 0.1.1

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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -2
  3. package/dist/agcid/agcid.d.ts +4 -0
  4. package/dist/agcid/agcid.js +15 -0
  5. package/dist/agcid/scope.d.ts +4 -0
  6. package/dist/agcid/scope.js +16 -0
  7. package/dist/context/context.d.ts +36 -0
  8. package/dist/context/context.js +25 -0
  9. package/dist/discovery/discovery.d.ts +47 -0
  10. package/dist/discovery/discovery.js +52 -0
  11. package/dist/discovery/discovery.schema.d.ts +106 -0
  12. package/dist/discovery/discovery.schema.js +56 -0
  13. package/dist/envelope/codes.d.ts +16 -0
  14. package/dist/envelope/codes.js +15 -0
  15. package/dist/envelope/envelope.d.ts +34 -0
  16. package/dist/envelope/envelope.js +23 -0
  17. package/dist/envelope/envelope.schema.d.ts +24 -0
  18. package/dist/envelope/envelope.schema.js +18 -0
  19. package/dist/envelope/parse.d.ts +17 -0
  20. package/dist/envelope/parse.js +12 -0
  21. package/dist/health/health.d.ts +18 -0
  22. package/dist/health/health.js +43 -0
  23. package/dist/health/health.schema.d.ts +46 -0
  24. package/dist/health/health.schema.js +20 -0
  25. package/dist/index.d.ts +19 -0
  26. package/dist/index.js +19 -0
  27. package/dist/log/log.d.ts +13 -0
  28. package/dist/log/log.js +21 -0
  29. package/dist/manifest/manifest.schema.d.ts +195 -0
  30. package/dist/manifest/manifest.schema.js +88 -0
  31. package/dist/manifest/parts.d.ts +11 -0
  32. package/dist/manifest/parts.js +24 -0
  33. package/dist/manifest/primitives.schema.d.ts +20 -0
  34. package/dist/manifest/primitives.schema.js +52 -0
  35. package/dist/manifest/read-manifest.d.ts +5 -0
  36. package/dist/manifest/read-manifest.js +19 -0
  37. package/dist/runtime/build-info.d.ts +4 -0
  38. package/dist/runtime/build-info.js +16 -0
  39. package/dist/runtime/main.d.ts +2 -0
  40. package/dist/runtime/main.js +10 -0
  41. package/dist/runtime/run-part.d.ts +13 -0
  42. package/dist/runtime/run-part.js +57 -0
  43. package/dist/schemas/json-schemas.d.ts +2 -0
  44. package/dist/schemas/json-schemas.js +29 -0
  45. package/dist/schemas/write-schemas.d.ts +1 -0
  46. package/dist/schemas/write-schemas.js +8 -0
  47. package/dist/server/app.d.ts +18 -0
  48. package/dist/server/app.js +47 -0
  49. package/dist/server/errors.d.ts +6 -0
  50. package/dist/server/errors.js +29 -0
  51. package/dist/server/part.types.d.ts +7 -0
  52. package/dist/server/part.types.js +2 -0
  53. package/dist/server/serve.d.ts +14 -0
  54. package/dist/server/serve.js +27 -0
  55. package/dist/testing/test-server.d.ts +12 -0
  56. package/dist/testing/test-server.js +26 -0
  57. package/dist/tool/build-info.d.ts +4 -0
  58. package/dist/tool/build-info.js +18 -0
  59. package/dist/tool/build.d.ts +35 -0
  60. package/dist/tool/build.js +83 -0
  61. package/dist/tool/cli.d.ts +2 -0
  62. package/dist/tool/cli.js +3 -0
  63. package/dist/tool/docker.d.ts +15 -0
  64. package/dist/tool/docker.js +26 -0
  65. package/dist/tool/exec.d.ts +12 -0
  66. package/dist/tool/exec.js +24 -0
  67. package/dist/tool/format.d.ts +2 -0
  68. package/dist/tool/format.js +14 -0
  69. package/dist/tool/index.d.ts +11 -0
  70. package/dist/tool/index.js +11 -0
  71. package/dist/tool/labels.d.ts +4 -0
  72. package/dist/tool/labels.js +25 -0
  73. package/dist/tool/main.d.ts +8 -0
  74. package/dist/tool/main.js +54 -0
  75. package/dist/tool/recipe.d.ts +3 -0
  76. package/dist/tool/recipe.js +32 -0
  77. package/dist/tool/stage.d.ts +5 -0
  78. package/dist/tool/stage.js +52 -0
  79. package/package.json +61 -4
  80. package/schemas/error-envelope.schema.json +70 -0
  81. package/schemas/extension-discovery.schema.json +182 -0
  82. package/schemas/extension-package.schema.json +309 -0
  83. package/schemas/extension-record.schema.json +176 -0
  84. package/schemas/health.schema.json +100 -0
  85. package/schemas/ok-envelope.schema.json +25 -0
@@ -0,0 +1,54 @@
1
+ import { parseArgs } from 'node:util';
2
+ import { build } from './build.js';
3
+ import { buildLines } from './format.js';
4
+ export const USAGE = `usage: agentage-extension build [--push] [--dir <path>] [--registry <host/owner>]
5
+
6
+ build one image per server part from the kit recipe
7
+ --push push the images and write dist/agentage-extension.json with their digests
8
+ --dir the extension package folder (default: the current folder)
9
+ --registry image registry and owner (default: ghcr.io/agentage)`;
10
+ const defaultDeps = {
11
+ build: (options) => build(options),
12
+ out: (line) => void process.stdout.write(`${line}\n`),
13
+ err: (line) => void process.stderr.write(`${line}\n`),
14
+ };
15
+ const parse = (argv) => parseArgs({
16
+ args: argv,
17
+ allowPositionals: true,
18
+ options: {
19
+ push: { type: 'boolean' },
20
+ dir: { type: 'string' },
21
+ registry: { type: 'string' },
22
+ help: { type: 'boolean', short: 'h' },
23
+ },
24
+ });
25
+ // Exit codes: 0 ok, 1 the build failed, 2 usage.
26
+ export const main = async (argv, deps = defaultDeps) => {
27
+ let parsed;
28
+ try {
29
+ parsed = parse(argv);
30
+ }
31
+ catch (err) {
32
+ deps.err(`${err.message}\n${USAGE}`);
33
+ return 2;
34
+ }
35
+ const { positionals, values } = parsed;
36
+ if (values.help)
37
+ return (deps.out(USAGE), 0);
38
+ if (positionals[0] !== 'build' || positionals.length !== 1)
39
+ return (deps.err(USAGE), 2);
40
+ try {
41
+ const result = await deps.build({
42
+ push: values.push,
43
+ dir: values.dir,
44
+ registry: values.registry,
45
+ });
46
+ for (const line of buildLines(result))
47
+ deps.out(line);
48
+ return 0;
49
+ }
50
+ catch (err) {
51
+ deps.err(`build failed: ${err.message}`);
52
+ return 1;
53
+ }
54
+ };
@@ -0,0 +1,3 @@
1
+ import { type ImagePartKind } from '../manifest/primitives.schema.js';
2
+ export declare const PART_PORT = 3000;
3
+ export declare const serverPartRecipe: (part: ImagePartKind) => string;
@@ -0,0 +1,32 @@
1
+ import {} from '../manifest/primitives.schema.js';
2
+ export const PART_PORT = 3000;
3
+ const HEALTH_PROBE = `fetch('http://127.0.0.1:${PART_PORT}/health')` +
4
+ '.then((r) => process.exit(r.status === 200 || r.status === 503 ? 0 : 1), () => process.exit(1))';
5
+ // The one recipe for a Node server part; the staged context holds deps/ (npm ci) and app/ (code).
6
+ export const serverPartRecipe = (part) => [
7
+ '# syntax=docker/dockerfile:1',
8
+ '# Generated by @agentage/extension build. Extension authors never write a Dockerfile.',
9
+ 'FROM node:26-alpine AS deps',
10
+ 'WORKDIR /app',
11
+ 'COPY deps/ ./',
12
+ 'RUN npm ci --omit=dev --no-audit --no-fund',
13
+ '',
14
+ 'FROM node:26-alpine AS runner',
15
+ 'ARG COMMIT_SHA',
16
+ 'ARG BUILD_TIME',
17
+ 'ARG IMAGE',
18
+ 'ENV NODE_ENV=production \\',
19
+ ' NODE_OPTIONS=--enable-source-maps \\',
20
+ ` PORT=${PART_PORT} \\`,
21
+ ' COMMIT_SHA=$COMMIT_SHA \\',
22
+ ' BUILD_TIME=$BUILD_TIME \\',
23
+ ' AGENTAGE_IMAGE=$IMAGE',
24
+ 'WORKDIR /app',
25
+ 'COPY --from=deps /app/node_modules ./node_modules',
26
+ 'COPY app/ ./',
27
+ 'USER node',
28
+ `EXPOSE ${PART_PORT}`,
29
+ `HEALTHCHECK --interval=10s --timeout=3s --start-period=15s --retries=3 CMD ["node", "-e", "${HEALTH_PROBE}"]`,
30
+ `CMD ["node", "node_modules/@agentage/extension/dist/runtime/main.js", "${part}"]`,
31
+ '',
32
+ ].join('\n');
@@ -0,0 +1,5 @@
1
+ import { type ExtensionPackage } from '../manifest/manifest.schema.js';
2
+ import { type ImagePartKind } from '../manifest/primitives.schema.js';
3
+ export declare const RECORD_FILE = "agentage-extension.json";
4
+ export declare const localTarballs: (pkg: ExtensionPackage) => string[];
5
+ export declare const stageContext: (dir: string, pkg: ExtensionPackage, part: ImagePartKind, tmpRoot?: string) => Promise<string>;
@@ -0,0 +1,52 @@
1
+ import { access, cp, mkdir, mkdtemp, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { basename, dirname, isAbsolute, join, normalize } from 'node:path';
4
+ import {} from '../manifest/manifest.schema.js';
5
+ import {} from '../manifest/primitives.schema.js';
6
+ import { serverPartRecipe } from './recipe.js';
7
+ export const RECORD_FILE = 'agentage-extension.json';
8
+ const dependencySpecs = (pkg) => {
9
+ const deps = pkg.dependencies;
10
+ if (typeof deps !== 'object' || deps === null)
11
+ return [];
12
+ return Object.values(deps).filter((spec) => typeof spec === 'string');
13
+ };
14
+ // `file:` tarball dependencies travel into the deps stage at the same relative path.
15
+ export const localTarballs = (pkg) => dependencySpecs(pkg)
16
+ .filter((spec) => spec.startsWith('file:') && spec.endsWith('.tgz'))
17
+ .map((spec) => normalize(spec.slice('file:'.length)))
18
+ .map((path) => {
19
+ if (isAbsolute(path) || path.startsWith('..')) {
20
+ throw new Error(`local dependency ${path} must live inside the package folder`);
21
+ }
22
+ return path;
23
+ });
24
+ const copyInto = async (from, to) => {
25
+ await mkdir(dirname(to), { recursive: true });
26
+ await cp(from, to, { recursive: true });
27
+ };
28
+ const copyDeps = async (dir, root, pkg) => {
29
+ await access(join(dir, 'package-lock.json')).catch(() => {
30
+ throw new Error('package-lock.json is missing: the image installs with npm ci');
31
+ });
32
+ await copyInto(join(dir, 'package.json'), join(root, 'deps', 'package.json'));
33
+ await copyInto(join(dir, 'package-lock.json'), join(root, 'deps', 'package-lock.json'));
34
+ for (const path of localTarballs(pkg))
35
+ await copyInto(join(dir, path), join(root, 'deps', path));
36
+ };
37
+ const copyApp = async (dir, root) => {
38
+ await copyInto(join(dir, 'package.json'), join(root, 'app', 'package.json'));
39
+ await mkdir(join(root, 'app'), { recursive: true });
40
+ await cp(join(dir, 'dist'), join(root, 'app', 'dist'), {
41
+ recursive: true,
42
+ filter: (source) => basename(source) !== RECORD_FILE,
43
+ });
44
+ };
45
+ // A clean build context per part: only the manifest, the lockfile, local tarballs and dist/.
46
+ export const stageContext = async (dir, pkg, part, tmpRoot = tmpdir()) => {
47
+ const root = await mkdtemp(join(tmpRoot, `agentage-${pkg.agentage.id}-${part}-`));
48
+ await copyDeps(dir, root, pkg);
49
+ await copyApp(dir, root);
50
+ await writeFile(join(root, 'Dockerfile'), serverPartRecipe(part));
51
+ return root;
52
+ };
package/package.json CHANGED
@@ -1,6 +1,63 @@
1
1
  {
2
2
  "name": "@agentage/extension",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "The agentage extension kit: create(ctx) per part, the server, /health, discovery, the envelope, and the build tool",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/agentage/platform.git",
10
+ "directory": "packages/extension"
11
+ },
12
+ "homepage": "https://agentage.io",
13
+ "bugs": {
14
+ "url": "https://github.com/agentage/platform/issues"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "engines": {
20
+ "node": ">=22"
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "./tool": {
28
+ "types": "./dist/tool/index.d.ts",
29
+ "default": "./dist/tool/index.js"
30
+ },
31
+ "./schemas/*": "./schemas/*",
32
+ "./package.json": "./package.json"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "schemas",
37
+ "!dist/**/*.test.*",
38
+ "!dist/test-support"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsc -b",
42
+ "schemas": "node dist/schemas/write-schemas.js schemas",
43
+ "verify": "npm run verify --prefix ../..",
44
+ "prepublishOnly": "npm run verify"
45
+ },
46
+ "dependencies": {
47
+ "cors": "^2.8.5",
48
+ "helmet": "^8.1.0",
49
+ "zod": "^4.2.0"
50
+ },
51
+ "peerDependencies": {
52
+ "express": "^5.1.0"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "express": {
56
+ "optional": true
57
+ }
58
+ },
59
+ "keywords": [
60
+ "agentage",
61
+ "extension"
62
+ ]
63
+ }
@@ -0,0 +1,70 @@
1
+ {
2
+ "$id": "https://agentage.io/schemas/error-envelope.schema.json",
3
+ "title": "REST error envelope",
4
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
5
+ "type": "object",
6
+ "properties": {
7
+ "success": {
8
+ "type": "boolean",
9
+ "const": false
10
+ },
11
+ "error": {
12
+ "type": "object",
13
+ "properties": {
14
+ "code": {
15
+ "type": "string",
16
+ "enum": [
17
+ "VALIDATION_ERROR",
18
+ "UNAUTHORIZED",
19
+ "FORBIDDEN",
20
+ "NOT_FOUND",
21
+ "CONFLICT",
22
+ "PRECONDITION_FAILED",
23
+ "PAYLOAD_TOO_LARGE",
24
+ "RATE_LIMITED",
25
+ "INTERNAL",
26
+ "UNAVAILABLE"
27
+ ]
28
+ },
29
+ "message": {
30
+ "type": "string",
31
+ "minLength": 1
32
+ },
33
+ "agcid": {
34
+ "type": "string",
35
+ "pattern": "^[A-Za-z0-9._:-]{8,128}$"
36
+ },
37
+ "details": {
38
+ "type": "array",
39
+ "items": {
40
+ "type": "object",
41
+ "properties": {
42
+ "field": {
43
+ "type": "string"
44
+ },
45
+ "message": {
46
+ "type": "string"
47
+ }
48
+ },
49
+ "required": [
50
+ "field",
51
+ "message"
52
+ ],
53
+ "additionalProperties": false
54
+ }
55
+ }
56
+ },
57
+ "required": [
58
+ "code",
59
+ "message",
60
+ "agcid"
61
+ ],
62
+ "additionalProperties": false
63
+ }
64
+ },
65
+ "required": [
66
+ "success",
67
+ "error"
68
+ ],
69
+ "additionalProperties": false
70
+ }
@@ -0,0 +1,182 @@
1
+ {
2
+ "$id": "https://agentage.io/schemas/extension-discovery.schema.json",
3
+ "title": "GET /.well-known/agentage-extension.json",
4
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
5
+ "type": "object",
6
+ "properties": {
7
+ "id": {
8
+ "type": "string",
9
+ "maxLength": 32,
10
+ "pattern": "^(?!(?:auth|www|api|sync|mail|mcp|ui|git|setup|status|update|extension|add|remove|help|con|prn|aux|nul|com[0-9]|lpt[0-9])$)[a-z][a-z0-9-]*$"
11
+ },
12
+ "version": {
13
+ "type": "string",
14
+ "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$"
15
+ },
16
+ "commit": {
17
+ "type": "string",
18
+ "pattern": "^[0-9a-f]{40}$"
19
+ },
20
+ "buildTime": {
21
+ "type": "string",
22
+ "format": "date-time",
23
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
24
+ },
25
+ "parts": {
26
+ "type": "object",
27
+ "properties": {
28
+ "pages": {
29
+ "type": "object",
30
+ "properties": {
31
+ "image": {
32
+ "type": "string",
33
+ "maxLength": 256,
34
+ "pattern": "^[a-z0-9][a-z0-9.-]*(:[0-9]{1,5})?\\/[a-z0-9][a-z0-9-]*\\/[a-z][a-z0-9-]*-(pages|ui|api|mcp|worker)@sha256:[0-9a-f]{64}$"
35
+ }
36
+ },
37
+ "required": [
38
+ "image"
39
+ ],
40
+ "additionalProperties": false
41
+ },
42
+ "ui": {
43
+ "type": "object",
44
+ "properties": {
45
+ "image": {
46
+ "type": "string",
47
+ "maxLength": 256,
48
+ "pattern": "^[a-z0-9][a-z0-9.-]*(:[0-9]{1,5})?\\/[a-z0-9][a-z0-9-]*\\/[a-z][a-z0-9-]*-(pages|ui|api|mcp|worker)@sha256:[0-9a-f]{64}$"
49
+ }
50
+ },
51
+ "required": [
52
+ "image"
53
+ ],
54
+ "additionalProperties": false
55
+ },
56
+ "api": {
57
+ "type": "object",
58
+ "properties": {
59
+ "image": {
60
+ "type": "string",
61
+ "maxLength": 256,
62
+ "pattern": "^[a-z0-9][a-z0-9.-]*(:[0-9]{1,5})?\\/[a-z0-9][a-z0-9-]*\\/[a-z][a-z0-9-]*-(pages|ui|api|mcp|worker)@sha256:[0-9a-f]{64}$"
63
+ }
64
+ },
65
+ "required": [
66
+ "image"
67
+ ],
68
+ "additionalProperties": false
69
+ },
70
+ "mcp": {
71
+ "type": "object",
72
+ "properties": {
73
+ "image": {
74
+ "type": "string",
75
+ "maxLength": 256,
76
+ "pattern": "^[a-z0-9][a-z0-9.-]*(:[0-9]{1,5})?\\/[a-z0-9][a-z0-9-]*\\/[a-z][a-z0-9-]*-(pages|ui|api|mcp|worker)@sha256:[0-9a-f]{64}$"
77
+ }
78
+ },
79
+ "required": [
80
+ "image"
81
+ ],
82
+ "additionalProperties": false
83
+ },
84
+ "worker": {
85
+ "type": "object",
86
+ "properties": {
87
+ "image": {
88
+ "type": "string",
89
+ "maxLength": 256,
90
+ "pattern": "^[a-z0-9][a-z0-9.-]*(:[0-9]{1,5})?\\/[a-z0-9][a-z0-9-]*\\/[a-z][a-z0-9-]*-(pages|ui|api|mcp|worker)@sha256:[0-9a-f]{64}$"
91
+ }
92
+ },
93
+ "required": [
94
+ "image"
95
+ ],
96
+ "additionalProperties": false
97
+ },
98
+ "store": {
99
+ "type": "object",
100
+ "properties": {
101
+ "kind": {
102
+ "type": "string",
103
+ "enum": [
104
+ "postgres",
105
+ "git",
106
+ "signoz"
107
+ ]
108
+ }
109
+ },
110
+ "required": [
111
+ "kind"
112
+ ],
113
+ "additionalProperties": false
114
+ }
115
+ },
116
+ "additionalProperties": false
117
+ },
118
+ "openapi": {
119
+ "type": "string",
120
+ "pattern": "^\\/api\\/v[1-9][0-9]*\\/openapi\\.json$"
121
+ },
122
+ "tools": {
123
+ "minItems": 1,
124
+ "type": "array",
125
+ "items": {
126
+ "type": "string",
127
+ "maxLength": 64,
128
+ "pattern": "^[a-z][a-z0-9-]*__[a-z][a-z0-9_-]*$"
129
+ }
130
+ },
131
+ "widgets": {
132
+ "minItems": 1,
133
+ "type": "array",
134
+ "items": {
135
+ "type": "object",
136
+ "properties": {
137
+ "name": {
138
+ "type": "string",
139
+ "pattern": "^[a-z][a-z0-9-]*$"
140
+ },
141
+ "element": {
142
+ "type": "string",
143
+ "pattern": "^[a-z][a-z0-9]*-[a-z0-9-]+$"
144
+ },
145
+ "module": {
146
+ "type": "string",
147
+ "pattern": "^\\/ui\\/[^/]+\\/[^/]+\\.m?js$"
148
+ }
149
+ },
150
+ "required": [
151
+ "name",
152
+ "element",
153
+ "module"
154
+ ],
155
+ "additionalProperties": false
156
+ }
157
+ },
158
+ "commands": {
159
+ "minItems": 1,
160
+ "type": "array",
161
+ "items": {
162
+ "type": "string",
163
+ "maxLength": 32,
164
+ "pattern": "^[a-z][a-z0-9-]*$"
165
+ }
166
+ },
167
+ "host": {
168
+ "type": "string",
169
+ "maxLength": 270,
170
+ "pattern": "^(https:\\/\\/[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+|http:\\/\\/(127\\.0\\.0\\.1|localhost))(:[0-9]{1,5})?$"
171
+ }
172
+ },
173
+ "required": [
174
+ "id",
175
+ "version",
176
+ "commit",
177
+ "buildTime",
178
+ "parts",
179
+ "host"
180
+ ],
181
+ "additionalProperties": false
182
+ }