@numa-tech/numa 1.14.7 → 1.14.9
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.
- package/README.md +20 -29
- package/dist/chatgpt-desktop.d.ts +4 -29
- package/dist/chatgpt-desktop.js +18 -376
- package/dist/chatgpt-desktop.js.map +1 -1
- package/dist/cli.js +20 -7
- package/dist/cli.js.map +1 -1
- package/dist/codex-module.js +2 -6
- package/dist/codex-module.js.map +1 -1
- package/dist/command-catalog.js +126 -6
- package/dist/command-catalog.js.map +1 -1
- package/dist/integration-bootstrap/client.d.ts +31 -4
- package/dist/integration-bootstrap/client.js +161 -35
- package/dist/integration-bootstrap/client.js.map +1 -1
- package/dist/integration-bootstrap/commands.d.ts +28 -5
- package/dist/integration-bootstrap/commands.js +399 -47
- package/dist/integration-bootstrap/commands.js.map +1 -1
- package/dist/integration-bootstrap/schemas.d.ts +408 -43
- package/dist/integration-bootstrap/schemas.js +373 -93
- package/dist/integration-bootstrap/schemas.js.map +1 -1
- package/dist/teams/client.d.ts +119 -0
- package/dist/teams/client.js +177 -0
- package/dist/teams/client.js.map +1 -0
- package/dist/teams/commands.d.ts +6 -0
- package/dist/teams/commands.js +192 -0
- package/dist/teams/commands.js.map +1 -0
- package/dist/teams/errors.d.ts +10 -0
- package/dist/teams/errors.js +56 -0
- package/dist/teams/errors.js.map +1 -0
- package/dist/teams/schemas.d.ts +171 -0
- package/dist/teams/schemas.js +81 -0
- package/dist/teams/schemas.js.map +1 -0
- package/package.json +4 -4
- package/skills/numa-cli/SKILL.md +2 -1
- package/skills/numa-cli/references/pipeline-release.md +2 -0
- package/skills/numa-local-flux-deploy/SKILL.md +24 -0
- package/skills/numa-local-flux-deploy/agents/openai.yaml +4 -0
- package/skills/numa-local-flux-deploy/evals/evals.json +35 -0
- package/skills/numa-local-flux-deploy/references/local-flux-release.md +172 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const TeamRoleSchema: z.ZodEnum<{
|
|
3
|
+
ADMIN: "ADMIN";
|
|
4
|
+
MAINTAINER: "MAINTAINER";
|
|
5
|
+
MEMBER: "MEMBER";
|
|
6
|
+
OWNER: "OWNER";
|
|
7
|
+
VIEWER: "VIEWER";
|
|
8
|
+
}>;
|
|
9
|
+
export declare const TeamStatusSchema: z.ZodEnum<{
|
|
10
|
+
ACTIVE: "ACTIVE";
|
|
11
|
+
ARCHIVED: "ARCHIVED";
|
|
12
|
+
}>;
|
|
13
|
+
export declare const UserStatusSchema: z.ZodEnum<{
|
|
14
|
+
ACTIVE: "ACTIVE";
|
|
15
|
+
ARCHIVED: "ARCHIVED";
|
|
16
|
+
DISABLED: "DISABLED";
|
|
17
|
+
INACTIVE: "INACTIVE";
|
|
18
|
+
}>;
|
|
19
|
+
export declare const TeamViewSchema: z.ZodObject<{
|
|
20
|
+
id: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
21
|
+
code: z.ZodString;
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
24
|
+
ownerUsername: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
25
|
+
status: z.ZodEnum<{
|
|
26
|
+
ACTIVE: "ACTIVE";
|
|
27
|
+
ARCHIVED: "ARCHIVED";
|
|
28
|
+
}>;
|
|
29
|
+
version: z.ZodNumber;
|
|
30
|
+
activeMemberCount: z.ZodNumber;
|
|
31
|
+
createdDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
32
|
+
lastModifiedDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
export declare const PlatformUserViewSchema: z.ZodObject<{
|
|
35
|
+
id: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
36
|
+
username: z.ZodString;
|
|
37
|
+
displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
38
|
+
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
39
|
+
status: z.ZodEnum<{
|
|
40
|
+
ACTIVE: "ACTIVE";
|
|
41
|
+
ARCHIVED: "ARCHIVED";
|
|
42
|
+
DISABLED: "DISABLED";
|
|
43
|
+
INACTIVE: "INACTIVE";
|
|
44
|
+
}>;
|
|
45
|
+
createdDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
46
|
+
lastModifiedDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
export declare const TeamMemberViewSchema: z.ZodObject<{
|
|
49
|
+
membershipId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
50
|
+
teamId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
51
|
+
userId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
52
|
+
username: z.ZodString;
|
|
53
|
+
displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
54
|
+
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
55
|
+
keycloakSubject: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
56
|
+
role: z.ZodEnum<{
|
|
57
|
+
ADMIN: "ADMIN";
|
|
58
|
+
MAINTAINER: "MAINTAINER";
|
|
59
|
+
MEMBER: "MEMBER";
|
|
60
|
+
OWNER: "OWNER";
|
|
61
|
+
VIEWER: "VIEWER";
|
|
62
|
+
}>;
|
|
63
|
+
status: z.ZodEnum<{
|
|
64
|
+
ACTIVE: "ACTIVE";
|
|
65
|
+
INACTIVE: "INACTIVE";
|
|
66
|
+
}>;
|
|
67
|
+
addedBy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
68
|
+
createdDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
69
|
+
lastModifiedDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
export declare const TeamPageSchema: z.ZodObject<{
|
|
72
|
+
items: z.ZodArray<z.ZodObject<{
|
|
73
|
+
id: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
74
|
+
code: z.ZodString;
|
|
75
|
+
name: z.ZodString;
|
|
76
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
77
|
+
ownerUsername: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
78
|
+
status: z.ZodEnum<{
|
|
79
|
+
ACTIVE: "ACTIVE";
|
|
80
|
+
ARCHIVED: "ARCHIVED";
|
|
81
|
+
}>;
|
|
82
|
+
version: z.ZodNumber;
|
|
83
|
+
activeMemberCount: z.ZodNumber;
|
|
84
|
+
createdDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
85
|
+
lastModifiedDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
86
|
+
}, z.core.$strip>>;
|
|
87
|
+
total: z.ZodNumber;
|
|
88
|
+
page: z.ZodNumber;
|
|
89
|
+
size: z.ZodNumber;
|
|
90
|
+
}, z.core.$strip>;
|
|
91
|
+
export declare const PlatformUserPageSchema: z.ZodObject<{
|
|
92
|
+
items: z.ZodArray<z.ZodObject<{
|
|
93
|
+
id: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
94
|
+
username: z.ZodString;
|
|
95
|
+
displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
96
|
+
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
97
|
+
status: z.ZodEnum<{
|
|
98
|
+
ACTIVE: "ACTIVE";
|
|
99
|
+
ARCHIVED: "ARCHIVED";
|
|
100
|
+
DISABLED: "DISABLED";
|
|
101
|
+
INACTIVE: "INACTIVE";
|
|
102
|
+
}>;
|
|
103
|
+
createdDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
104
|
+
lastModifiedDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
105
|
+
}, z.core.$strip>>;
|
|
106
|
+
total: z.ZodNumber;
|
|
107
|
+
page: z.ZodNumber;
|
|
108
|
+
size: z.ZodNumber;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
export declare const TeamMemberListSchema: z.ZodArray<z.ZodObject<{
|
|
111
|
+
membershipId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
112
|
+
teamId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
113
|
+
userId: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<string, string | number>>;
|
|
114
|
+
username: z.ZodString;
|
|
115
|
+
displayName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
116
|
+
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
117
|
+
keycloakSubject: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
118
|
+
role: z.ZodEnum<{
|
|
119
|
+
ADMIN: "ADMIN";
|
|
120
|
+
MAINTAINER: "MAINTAINER";
|
|
121
|
+
MEMBER: "MEMBER";
|
|
122
|
+
OWNER: "OWNER";
|
|
123
|
+
VIEWER: "VIEWER";
|
|
124
|
+
}>;
|
|
125
|
+
status: z.ZodEnum<{
|
|
126
|
+
ACTIVE: "ACTIVE";
|
|
127
|
+
INACTIVE: "INACTIVE";
|
|
128
|
+
}>;
|
|
129
|
+
addedBy: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
130
|
+
createdDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
131
|
+
lastModifiedDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
132
|
+
}, z.core.$strip>>;
|
|
133
|
+
export declare const CreateTeamRequestSchema: z.ZodObject<{
|
|
134
|
+
code: z.ZodString;
|
|
135
|
+
name: z.ZodString;
|
|
136
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
137
|
+
ownerUserId: z.ZodOptional<z.ZodNumber>;
|
|
138
|
+
}, z.core.$strict>;
|
|
139
|
+
export declare const UpdateTeamRequestSchema: z.ZodObject<{
|
|
140
|
+
name: z.ZodString;
|
|
141
|
+
description: z.ZodNullable<z.ZodString>;
|
|
142
|
+
status: z.ZodEnum<{
|
|
143
|
+
ACTIVE: "ACTIVE";
|
|
144
|
+
ARCHIVED: "ARCHIVED";
|
|
145
|
+
}>;
|
|
146
|
+
expectedVersion: z.ZodNumber;
|
|
147
|
+
}, z.core.$strict>;
|
|
148
|
+
export declare const SaveTeamMemberRequestSchema: z.ZodObject<{
|
|
149
|
+
userId: z.ZodNumber;
|
|
150
|
+
role: z.ZodEnum<{
|
|
151
|
+
ADMIN: "ADMIN";
|
|
152
|
+
MAINTAINER: "MAINTAINER";
|
|
153
|
+
MEMBER: "MEMBER";
|
|
154
|
+
OWNER: "OWNER";
|
|
155
|
+
VIEWER: "VIEWER";
|
|
156
|
+
}>;
|
|
157
|
+
}, z.core.$strict>;
|
|
158
|
+
export declare const TeamApiErrorSchema: z.ZodObject<{
|
|
159
|
+
code: z.ZodOptional<z.ZodString>;
|
|
160
|
+
message: z.ZodOptional<z.ZodString>;
|
|
161
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
162
|
+
requestId: z.ZodOptional<z.ZodString>;
|
|
163
|
+
details: z.ZodOptional<z.ZodUnknown>;
|
|
164
|
+
}, z.core.$loose>;
|
|
165
|
+
export type TeamRole = z.infer<typeof TeamRoleSchema>;
|
|
166
|
+
export type TeamView = z.infer<typeof TeamViewSchema>;
|
|
167
|
+
export type PlatformUserView = z.infer<typeof PlatformUserViewSchema>;
|
|
168
|
+
export type TeamMemberView = z.infer<typeof TeamMemberViewSchema>;
|
|
169
|
+
export type CreateTeamRequest = z.infer<typeof CreateTeamRequestSchema>;
|
|
170
|
+
export type UpdateTeamRequest = z.infer<typeof UpdateTeamRequestSchema>;
|
|
171
|
+
export type SaveTeamMemberRequest = z.infer<typeof SaveTeamMemberRequestSchema>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const NonEmptyString = z.string().trim().min(1);
|
|
3
|
+
const OptionalString = z.string().nullable().optional();
|
|
4
|
+
const PositiveId = z.union([
|
|
5
|
+
z.string().trim().regex(/^[1-9]\d*$/u),
|
|
6
|
+
z.number().int().positive()
|
|
7
|
+
]).transform(String);
|
|
8
|
+
const DateValue = z.string().nullable().optional();
|
|
9
|
+
export const TeamRoleSchema = z.enum(["OWNER", "ADMIN", "MAINTAINER", "MEMBER", "VIEWER"]);
|
|
10
|
+
export const TeamStatusSchema = z.enum(["ACTIVE", "ARCHIVED"]);
|
|
11
|
+
export const UserStatusSchema = z.enum(["ACTIVE", "ARCHIVED", "INACTIVE", "DISABLED"]);
|
|
12
|
+
export const TeamViewSchema = z.object({
|
|
13
|
+
id: PositiveId,
|
|
14
|
+
code: NonEmptyString,
|
|
15
|
+
name: NonEmptyString,
|
|
16
|
+
description: OptionalString,
|
|
17
|
+
ownerUsername: OptionalString,
|
|
18
|
+
status: TeamStatusSchema,
|
|
19
|
+
version: z.number().int().nonnegative(),
|
|
20
|
+
activeMemberCount: z.number().int().nonnegative(),
|
|
21
|
+
createdDate: DateValue,
|
|
22
|
+
lastModifiedDate: DateValue
|
|
23
|
+
});
|
|
24
|
+
export const PlatformUserViewSchema = z.object({
|
|
25
|
+
id: PositiveId,
|
|
26
|
+
username: NonEmptyString,
|
|
27
|
+
displayName: OptionalString,
|
|
28
|
+
email: OptionalString,
|
|
29
|
+
status: UserStatusSchema,
|
|
30
|
+
createdDate: DateValue,
|
|
31
|
+
lastModifiedDate: DateValue
|
|
32
|
+
});
|
|
33
|
+
export const TeamMemberViewSchema = z.object({
|
|
34
|
+
membershipId: PositiveId,
|
|
35
|
+
teamId: PositiveId,
|
|
36
|
+
userId: PositiveId,
|
|
37
|
+
username: NonEmptyString,
|
|
38
|
+
displayName: OptionalString,
|
|
39
|
+
email: OptionalString,
|
|
40
|
+
keycloakSubject: OptionalString,
|
|
41
|
+
role: TeamRoleSchema,
|
|
42
|
+
status: z.enum(["ACTIVE", "INACTIVE"]),
|
|
43
|
+
addedBy: OptionalString,
|
|
44
|
+
createdDate: DateValue,
|
|
45
|
+
lastModifiedDate: DateValue
|
|
46
|
+
});
|
|
47
|
+
function pageSchema(item) {
|
|
48
|
+
return z.object({
|
|
49
|
+
items: z.array(item),
|
|
50
|
+
total: z.number().int().nonnegative(),
|
|
51
|
+
page: z.number().int().positive(),
|
|
52
|
+
size: z.number().int().positive()
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
export const TeamPageSchema = pageSchema(TeamViewSchema);
|
|
56
|
+
export const PlatformUserPageSchema = pageSchema(PlatformUserViewSchema);
|
|
57
|
+
export const TeamMemberListSchema = z.array(TeamMemberViewSchema);
|
|
58
|
+
export const CreateTeamRequestSchema = z.object({
|
|
59
|
+
code: z.string().trim().regex(/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u).max(80),
|
|
60
|
+
name: z.string().trim().min(1).max(120),
|
|
61
|
+
description: z.string().trim().max(2000).nullable().optional(),
|
|
62
|
+
ownerUserId: z.number().int().positive().safe().optional()
|
|
63
|
+
}).strict();
|
|
64
|
+
export const UpdateTeamRequestSchema = z.object({
|
|
65
|
+
name: z.string().trim().min(1).max(120),
|
|
66
|
+
description: z.string().trim().max(2000).nullable(),
|
|
67
|
+
status: TeamStatusSchema,
|
|
68
|
+
expectedVersion: z.number().int().nonnegative()
|
|
69
|
+
}).strict();
|
|
70
|
+
export const SaveTeamMemberRequestSchema = z.object({
|
|
71
|
+
userId: z.number().int().positive().safe(),
|
|
72
|
+
role: TeamRoleSchema
|
|
73
|
+
}).strict();
|
|
74
|
+
export const TeamApiErrorSchema = z.object({
|
|
75
|
+
code: z.string().optional(),
|
|
76
|
+
message: z.string().optional(),
|
|
77
|
+
detail: z.string().optional(),
|
|
78
|
+
requestId: z.string().optional(),
|
|
79
|
+
details: z.unknown().optional()
|
|
80
|
+
}).passthrough();
|
|
81
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/teams/schemas.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@numa-tech/numa",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.9",
|
|
4
4
|
"description": "Cross-platform CLI for the Numa internal developer platform with Keycloak authentication and MCP support.",
|
|
5
5
|
"author": "numa-tech",
|
|
6
6
|
"keywords": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"typecheck": "turbo run typecheck root:typecheck",
|
|
33
33
|
"root:typecheck": "tsc --noEmit",
|
|
34
34
|
"test": "turbo run test root:test",
|
|
35
|
-
"root:test": "node --import tsx --test src/branding.test.ts src/app-config.test.ts src/platform-profile.test.ts src/identity.test.ts src/backend.test.ts src/oauth.test.ts src/web-console.test.ts src/cli-options.test.ts src/ai-registry/client.test.ts src/ai-registry/workspace.test.ts src/ai-registry/namespace.test.ts src/ai-registry/sync.test.ts src/ai-registry/bridge.test.ts src/ai-registry/skill-installer.test.ts src/ai-registry/mcp-installer.test.ts src/media/client.test.ts src/media/commands.test.ts src/media/transfers.test.ts src/pipeline/client.test.ts src/pipeline/commands.test.ts src/platform-builds/client.test.ts src/platform-builds/commands.test.ts src/gitops/client.test.ts src/gitops/commands.test.ts src/repositories/client.test.ts src/repositories/commands.test.ts src/publications/scanner.test.ts src/publications/client.test.ts src/publications/commands.test.ts src/jenkins-jobs/client.test.ts src/jenkins-jobs/commands.test.ts src/jenkins-gitops-rollouts/client.test.ts src/jenkins-gitops-rollouts/commands.test.ts src/platform-build-rollouts/client.test.ts src/platform-build-rollouts/commands.test.ts src/platform-build-job-replans/client.test.ts src/platform-build-job-replans/commands.test.ts src/clusters/client.test.ts src/clusters/commands.test.ts src/clusters/kubeconfig-discovery.test.ts src/authorization/client.test.ts src/authorization/commands.test.ts src/authorization/access-request-client.test.ts src/authorization/access-request-commands.test.ts src/integration-bootstrap/client.test.ts src/integration-bootstrap/commands.test.ts src/application-candidates/client.test.ts src/application-candidates/commands.test.ts src/application-onboarding/client.test.ts src/application-onboarding/commands.test.ts src/application-onboarding/tui.test.ts src/chatgpt-desktop.test.ts src/codex-integration.test.ts scripts/release-all.test.mjs",
|
|
35
|
+
"root:test": "node --import tsx --test src/branding.test.ts src/app-config.test.ts src/platform-profile.test.ts src/identity.test.ts src/backend.test.ts src/oauth.test.ts src/web-console.test.ts src/cli-options.test.ts src/ai-registry/client.test.ts src/ai-registry/workspace.test.ts src/ai-registry/namespace.test.ts src/ai-registry/sync.test.ts src/ai-registry/bridge.test.ts src/ai-registry/skill-installer.test.ts src/ai-registry/mcp-installer.test.ts src/media/client.test.ts src/media/commands.test.ts src/media/transfers.test.ts src/pipeline/client.test.ts src/pipeline/commands.test.ts src/platform-builds/client.test.ts src/platform-builds/commands.test.ts src/gitops/client.test.ts src/gitops/commands.test.ts src/repositories/client.test.ts src/repositories/commands.test.ts src/publications/scanner.test.ts src/publications/client.test.ts src/publications/commands.test.ts src/jenkins-jobs/client.test.ts src/jenkins-jobs/commands.test.ts src/jenkins-gitops-rollouts/client.test.ts src/jenkins-gitops-rollouts/commands.test.ts src/platform-build-rollouts/client.test.ts src/platform-build-rollouts/commands.test.ts src/platform-build-job-replans/client.test.ts src/platform-build-job-replans/commands.test.ts src/clusters/client.test.ts src/clusters/commands.test.ts src/clusters/kubeconfig-discovery.test.ts src/teams/client.test.ts src/teams/commands.test.ts src/authorization/client.test.ts src/authorization/commands.test.ts src/authorization/access-request-client.test.ts src/authorization/access-request-commands.test.ts src/integration-bootstrap/client.test.ts src/integration-bootstrap/commands.test.ts src/application-candidates/client.test.ts src/application-candidates/commands.test.ts src/application-onboarding/client.test.ts src/application-onboarding/commands.test.ts src/application-onboarding/tui.test.ts src/chatgpt-desktop.test.ts src/codex-integration.test.ts scripts/release-all.test.mjs",
|
|
36
36
|
"pack:check": "turbo run pack:check root:pack:check",
|
|
37
37
|
"root:pack:check": "node scripts/check-root-package.mjs",
|
|
38
38
|
"boundaries": "node scripts/check-workspace-boundaries.mjs",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@clack/prompts": "^1.7.0",
|
|
57
57
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
58
|
-
"@numa-tech/cli-auth": "1.14.
|
|
59
|
-
"@tokensrc/codex": "1.14.
|
|
58
|
+
"@numa-tech/cli-auth": "1.14.9",
|
|
59
|
+
"@tokensrc/codex": "1.14.9",
|
|
60
60
|
"commander": "^14.0.3",
|
|
61
61
|
"ink": "^6.8.0",
|
|
62
62
|
"open": "^10.2.0",
|
package/skills/numa-cli/SKILL.md
CHANGED
|
@@ -26,7 +26,8 @@ Never read or print token caches, inject a raw Bearer token, request Jenkins/Nac
|
|
|
26
26
|
|
|
27
27
|
## Route by capability
|
|
28
28
|
|
|
29
|
-
-
|
|
29
|
+
- When the user explicitly requires a local image build and direct Flux release because the governed pipeline is unavailable, use the dedicated `$numa-local-flux-deploy` Skill instead of this Skill's pipeline path. Do not infer that fallback merely from a pipeline error.
|
|
30
|
+
- For other application publishing, production deployment, Jenkins Pipeline build/status/log/stop/retry, idempotency, rollout order, or release recovery, read [pipeline-release.md](references/pipeline-release.md) completely before acting.
|
|
30
31
|
- For `numa registry`, Nacos Skills/MCP, namespace routing, Registry approval, or enterprise Router work, use the dedicated `$numa-ai-registry` Skill when it is available. Otherwise inspect `numa registry capabilities --json` and command help before every write.
|
|
31
32
|
- For application onboarding and SCM, inspect `numa app --help`, `numa app scm --help`, and the corresponding entries in `numa commands --json`; preserve server-owned session state and optimistic-lock revisions.
|
|
32
33
|
- For Codex, media, configuration, identity, or admin modules, use the command catalog plus exact subcommand help. Do not invent missing behavior. Add a focused reference module to this Skill when that workflow becomes repetitive or safety-critical.
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Read this file completely before planning or executing an application release with `numa pipeline`.
|
|
4
4
|
|
|
5
|
+
This is the normal governed release path. If the user explicitly authorizes a local image build and direct Flux release because the pipeline is unavailable, stop using this specification and use `$numa-local-flux-deploy`. A pipeline failure alone does not authorize that fallback.
|
|
6
|
+
|
|
5
7
|
## Source of truth
|
|
6
8
|
|
|
7
9
|
Use direct Numa CLI commands. Do not create or invoke a repository-specific deployment wrapper. Resolve release policy in this order:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: numa-local-flux-deploy
|
|
3
|
+
description: Build and deploy an existing Numa application locally through its image registry and Flux Git repository when the governed Jenkins/Numa pipeline is unavailable and the user explicitly authorizes the fallback. Use for local production image builds, direct Flux image-tag releases, rollout recovery, or an accompanying Numa CLI npm release; do not use as the default path while the normal pipeline is usable.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Numa Local Flux Deploy
|
|
7
|
+
|
|
8
|
+
Use this as a controlled fallback, not as a silent replacement for the governed pipeline. The user must explicitly authorize the resolved application and environment and state that the pipeline is unavailable or that local deployment is required.
|
|
9
|
+
|
|
10
|
+
Read [local-flux-release.md](references/local-flux-release.md) completely before inspecting credentials, building an image, changing Flux, reconciling a cluster, or publishing npm packages.
|
|
11
|
+
|
|
12
|
+
## Preserve the deployment boundary
|
|
13
|
+
|
|
14
|
+
- Resolve the exact source repository, remote commit, application, environment, namespace, workload, image repository, Flux values file, cluster context, and health endpoint from version-controlled or live read-only evidence. Do not guess any of them.
|
|
15
|
+
- Use an isolated clean Git worktree for both source and Flux changes. The preferred Flux repository is `~/mci/mci-flux`; never overwrite, stash, clean, or build from unrelated changes in its primary worktree.
|
|
16
|
+
- Never read registry auth files, kubeconfig contents, application secrets, token caches, or `secrets/**`. Check only whether the required authenticated tools can operate.
|
|
17
|
+
- Do not modify Keycloak, database data, unrelated Flux resources, or a live Deployment unless the user separately placed that target in scope.
|
|
18
|
+
- A local interruption or registry/network error creates an unknown result. Inspect the existing image tag, Git ref, Flux revision, and workload before any retry. Reuse the exact operation identity; never create a second release to escape uncertainty.
|
|
19
|
+
|
|
20
|
+
## Finish with evidence
|
|
21
|
+
|
|
22
|
+
Do not call the release successful until GitOps has applied the exact Flux commit, the controller and workload are healthy on the exact image tag, the application readiness check passes, and any optional npm release has passed candidate smoke testing before promotion to `latest`.
|
|
23
|
+
|
|
24
|
+
Report the source commit, image tag and digest, Flux commit/revision, cluster context, controller/workload status, health results, npm version/tags when applicable, and whether Jenkins or Keycloak were touched.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "numa-local-flux-deploy",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Jenkins 还不能用,已授权把 code-index 当前 master 本地构建后发布到 prd;Flux 仓库在 ~/mci/mci-flux。",
|
|
7
|
+
"expected_output": "The agent resolves the exact source commit and production workload, uses isolated source and Flux worktrees, pushes one immutable image, changes only the Flux image tag, reconciles the exact Git revision, and verifies workload and application health.",
|
|
8
|
+
"expectations": [
|
|
9
|
+
"Uses ~/mci/mci-flux through an isolated worktree and preserves any dirty primary worktree.",
|
|
10
|
+
"Does not update Flux until the registry push has a confirmed remote result.",
|
|
11
|
+
"Does not mutate Keycloak, secrets, or the live Deployment directly."
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": 2,
|
|
16
|
+
"prompt": "本地 push 镜像时返回 EOF,不管了,换一个 tag 直接改 Flux 继续上线。",
|
|
17
|
+
"expected_output": "The agent treats the push as unknown, resolves the existing remote manifest, and retries only the identical image/tag/digest through an approved hostname or stops without changing Flux.",
|
|
18
|
+
"expectations": [
|
|
19
|
+
"Does not create a new tag to escape the unknown result.",
|
|
20
|
+
"Does not change the Flux environment branch before remote image evidence is confirmed.",
|
|
21
|
+
"Reports IMAGE_PUSH_UNKNOWN when the registry cannot establish the result."
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": 3,
|
|
26
|
+
"prompt": "后端已经通过本地 Flux 发布,把同批 Numa CLI 也立刻发到 npm latest。",
|
|
27
|
+
"expected_output": "The agent uses the repository lockstep release flow, publishes candidate first, tests the registry artifact against the healthy backend, and only then promotes all three packages to latest.",
|
|
28
|
+
"expectations": [
|
|
29
|
+
"Runs the release dry-run and candidate workflow from a clean upstream-equal worktree.",
|
|
30
|
+
"Tests @numa-tech/numa@candidate rather than relying on local output.",
|
|
31
|
+
"Promotes cli-auth, codex, and numa lockstep and verifies their dist-tags."
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Local image and Flux release runbook
|
|
2
|
+
|
|
3
|
+
Use this runbook only after the user authorizes the exact deployment and the normal Jenkins/Numa pipeline is unavailable or explicitly excluded. Keep the pipeline failure evidence in the handoff, but do not repeatedly probe or trigger it once the fallback is selected.
|
|
4
|
+
|
|
5
|
+
## 1. Resolve and freeze the release identity
|
|
6
|
+
|
|
7
|
+
Collect these values from repository and live read-only evidence:
|
|
8
|
+
|
|
9
|
+
- source repository and clean remote commit;
|
|
10
|
+
- application code and immutable image tag convention;
|
|
11
|
+
- environment branch, Kubernetes context, namespace, Deployment/HelmRelease, and health endpoints;
|
|
12
|
+
- registry repository used by Flux and the authenticated external registry hostname used by the local builder;
|
|
13
|
+
- exact Flux overlay and values file that owns the image tag.
|
|
14
|
+
|
|
15
|
+
The default Flux repository is `~/mci/mci-flux`. If it is absent, stop unless the user or repository documentation supplies another path. A cluster may pull through an internal/VPC CNAME while the builder pushes through an external CNAME; accept that only when existing configuration or the user confirms both names address the same registry repository. Do not change the Flux repository hostname just to match a local login.
|
|
16
|
+
|
|
17
|
+
Before mutation:
|
|
18
|
+
|
|
19
|
+
1. Verify the source `HEAD` equals its intended remote ref and the worktree is clean. If the user's primary worktree is dirty, create an isolated worktree at the exact remote commit; do not stash or discard anything.
|
|
20
|
+
2. Fetch the Flux environment branch and create an isolated worktree from `origin/<environment>`. Never edit the primary Flux worktree in place.
|
|
21
|
+
3. Inspect only the relevant non-secret base/overlay files. Do not print or open `secrets/**`.
|
|
22
|
+
4. Run `kubectl config current-context` and read the current workload image/readiness. Stop if the context, namespace, or workload differs from the resolved plan.
|
|
23
|
+
5. Confirm registry access with a command such as `podman login --get-login <host>`. Never read or print the container auth file.
|
|
24
|
+
|
|
25
|
+
Recommended isolated Flux setup, with task-specific variable names:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
DEPLOY_FLUX_REPO=~/mci/mci-flux
|
|
29
|
+
DEPLOY_ENV=prd
|
|
30
|
+
DEPLOY_AUDIT_BRANCH=codex/APPLICATION-SHORTSHA-deploy
|
|
31
|
+
DEPLOY_FLUX_WORKTREE=$(mktemp -d /private/tmp/mci-flux-deploy.XXXXXX)
|
|
32
|
+
|
|
33
|
+
git -C "$DEPLOY_FLUX_REPO" fetch origin "$DEPLOY_ENV"
|
|
34
|
+
git -C "$DEPLOY_FLUX_REPO" worktree add \
|
|
35
|
+
-b "$DEPLOY_AUDIT_BRANCH" \
|
|
36
|
+
"$DEPLOY_FLUX_WORKTREE/repo" \
|
|
37
|
+
"origin/$DEPLOY_ENV"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If the audit branch already exists, resolve its state rather than deleting or overwriting it.
|
|
41
|
+
|
|
42
|
+
## 2. Build and publish one immutable image
|
|
43
|
+
|
|
44
|
+
Derive the target platform from the current production workload or deployment policy. Do not assume `linux/amd64` for every application; it is the common code-index production platform and must still be verified.
|
|
45
|
+
|
|
46
|
+
Use an immutable tag containing at least the source short SHA and environment. Follow the repository's existing convention, for example:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
YYYYMMDD-<short-sha>-amd64-prd
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Never reuse an existing tag for different content. Build from the clean isolated source worktree:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
DEPLOY_PLATFORM=linux/amd64 # replace only with the platform proven above
|
|
56
|
+
DEPLOY_IMAGE="APPROVED_EXTERNAL_REGISTRY/REPOSITORY:IMMUTABLE_TAG"
|
|
57
|
+
|
|
58
|
+
podman build --platform "$DEPLOY_PLATFORM" --pull=always \
|
|
59
|
+
-t "$DEPLOY_IMAGE" .
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Inspect the local image architecture and ID, then push with bounded transport retries:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
podman image inspect "$DEPLOY_IMAGE" --format '{{.Architecture}} {{.Os}} {{.Id}}'
|
|
66
|
+
podman push --retry=5 --retry-delay=5s "$DEPLOY_IMAGE"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Record a registry-confirmed RepoDigest or equivalent remote-manifest evidence. Do not update Flux when the push is failed or unknown. A transport error such as `EOF` permits only an idempotent retry of the same local image/tag/digest through an already-approved hostname for the same registry. If remote evidence cannot distinguish success from failure, stop and report `IMAGE_PUSH_UNKNOWN`.
|
|
70
|
+
|
|
71
|
+
## 3. Change only the Flux-owned image version
|
|
72
|
+
|
|
73
|
+
Update only the image tag field in the exact application values file. Preserve the repository hostname, environment, secrets, and all unrelated manifests. Use `apply_patch`, then require:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
DEPLOY_VALUES_FILE=apps/overlays/prd/values-APPLICATION.yaml
|
|
77
|
+
|
|
78
|
+
git diff --check
|
|
79
|
+
git diff -- "$DEPLOY_VALUES_FILE"
|
|
80
|
+
kubectl kustomize "apps/overlays/$DEPLOY_ENV" >/dev/null
|
|
81
|
+
git status --short
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The diff must contain only the intended application image version unless the user separately approved more changes.
|
|
85
|
+
|
|
86
|
+
Fetch `origin/<environment>` again immediately before committing. If it advanced, rebase or recreate the isolated change and re-run validation; never force-push. Commit a traceable deployment message, then atomically push an audit branch and the environment branch when the remote supports it:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
git push --atomic origin \
|
|
90
|
+
"HEAD:refs/heads/$DEPLOY_AUDIT_BRANCH" \
|
|
91
|
+
"HEAD:refs/heads/$DEPLOY_ENV"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If push output is interrupted or unknown, inspect remote refs before retrying. Do not generate a second commit or tag until the first result is resolved.
|
|
95
|
+
|
|
96
|
+
## 4. Reconcile through Flux and observe the rollout
|
|
97
|
+
|
|
98
|
+
After the Git push is confirmed, verify the Flux GitRepository has fetched the exact environment commit. Request reconciliation by annotating the owning Flux Kustomization; do not use `kubectl set image`, edit the Deployment, or apply rendered manifests directly.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
DEPLOY_FLUX_KUSTOMIZATION="RESOLVED_ENVIRONMENT_KUSTOMIZATION"
|
|
102
|
+
DEPLOY_RECONCILE_REQUEST="YYYY-MM-DDTHH:MM:SSZ"
|
|
103
|
+
|
|
104
|
+
kubectl -n flux-system annotate kustomization "$DEPLOY_FLUX_KUSTOMIZATION" \
|
|
105
|
+
reconcile.fluxcd.io/requestedAt="$DEPLOY_RECONCILE_REQUEST" --overwrite
|
|
106
|
+
kubectl -n flux-system wait "kustomization/$DEPLOY_FLUX_KUSTOMIZATION" \
|
|
107
|
+
--for=condition=ready --timeout=120s
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Then verify all of the following:
|
|
111
|
+
|
|
112
|
+
- Kustomization `lastAppliedRevision` equals the pushed Flux commit and both Ready/Healthy conditions are true;
|
|
113
|
+
- the application HelmRelease or equivalent controller reports successful reconciliation;
|
|
114
|
+
- the Deployment template references the exact new tag and the observed generation matches;
|
|
115
|
+
- the new Pod is ready with zero unexpected restarts and its image ID is recorded;
|
|
116
|
+
- `kubectl rollout status` succeeds within a bounded timeout;
|
|
117
|
+
- public or internal readiness and liveness endpoints return the expected success status.
|
|
118
|
+
|
|
119
|
+
A `Recreate` strategy may temporarily show zero ready Pods; treat that as an expected transition only inside the approved timeout. If the rollout fails, inspect controller conditions, Pod events, and sanitized logs. Do not automatically roll back. A rollback is a separately authorized revert of the Flux commit followed by the same validation and reconciliation process.
|
|
120
|
+
|
|
121
|
+
## 5. Recover ambiguous stages without duplicating work
|
|
122
|
+
|
|
123
|
+
Use the original identity at every stage:
|
|
124
|
+
|
|
125
|
+
| Unknown stage | Read-only authority | Safe continuation |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| image push | registry manifest/tag/digest | retry only the identical image/tag/digest after proving no conflicting manifest |
|
|
128
|
+
| Flux Git push | remote environment and audit refs | retry the identical ref update only when the first update is absent |
|
|
129
|
+
| Flux reconciliation | GitRepository/Kustomization revision and conditions | continue observing or request reconciliation for the same commit |
|
|
130
|
+
| workload rollout | controller revision, Deployment generation, Pod image ID | continue observing the same rollout; do not create a new release |
|
|
131
|
+
| health check | workload readiness plus bounded endpoint checks | diagnose the deployed revision; do not infer rollback or success from one timeout |
|
|
132
|
+
|
|
133
|
+
Never hide an unknown result by choosing a new image tag, commit, or audit branch.
|
|
134
|
+
|
|
135
|
+
## 6. Optionally publish the Numa CLI after the backend is healthy
|
|
136
|
+
|
|
137
|
+
Run this section only when the same release contains a Numa CLI change and the user authorized public npm publication. Backend and migrations must already be healthy so the candidate can exercise the real server contract.
|
|
138
|
+
|
|
139
|
+
Use a clean Numa worktree whose `HEAD` equals its upstream. Confirm public npm identity without reading npm credentials, then follow the repository's lockstep release script:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npm whoami --registry=https://registry.npmjs.org/
|
|
143
|
+
npm run release -- patch --dry-run
|
|
144
|
+
npm run release -- patch --tag=candidate
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The release script must run typecheck, tests, build, pack checks, publish the three lockstep packages in dependency order, and push the release commit/tag. Test the registry artifact rather than the local build:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx -y --prefer-online --registry=https://registry.npmjs.org/ \
|
|
151
|
+
@numa-tech/numa@candidate --version
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Run one authorized production smoke command suitable for the feature. For a Codex passive access-observation change, `codex list` is appropriate because it checks local AT timing and reports safe metadata without calling OpenAI or using an RT. Promote only after the candidate succeeds:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
DEPLOY_NUMA_VERSION="X.Y.Z"
|
|
158
|
+
npm run release:promote -- "$DEPLOY_NUMA_VERSION" --from-tag=candidate
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Verify `latest` for `@numa-tech/cli-auth`, `@tokensrc/codex`, and `@numa-tech/numa`, install `@numa-tech/numa@latest`, and confirm the Git release commit, annotated tag, upstream equality, and clean worktree.
|
|
162
|
+
|
|
163
|
+
## 7. Handoff evidence
|
|
164
|
+
|
|
165
|
+
Report, without credentials or secret values:
|
|
166
|
+
|
|
167
|
+
- pipeline fallback reason and confirmation that no Jenkins build was created or left running;
|
|
168
|
+
- source commit, image tag, registry digest, Flux commit, environment revision, and cluster context;
|
|
169
|
+
- controller, Deployment, Pod restart, readiness/liveness, and migration results;
|
|
170
|
+
- npm release commit/tag, package version, and all dist-tags when applicable;
|
|
171
|
+
- any unknown stage still unresolved;
|
|
172
|
+
- confirmation that Keycloak and unrelated resources were not modified.
|