@gonovus-ai/spec-flow-cli 0.4.0 → 0.6.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.
- package/README.md +190 -28
- package/dist/bin.js +6 -50
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +126 -397
- package/dist/cli.js.map +1 -1
- package/dist/commands/work-item-output.d.ts +390 -0
- package/dist/commands/work-item-output.js +36 -0
- package/dist/commands/work-item-output.js.map +1 -0
- package/dist/custom-field-color-commands.d.ts +7 -0
- package/dist/custom-field-color-commands.js +22 -0
- package/dist/custom-field-color-commands.js.map +1 -0
- package/dist/github-connection-commands.js +23 -3
- package/dist/github-connection-commands.js.map +1 -1
- package/dist/http-origin.js +3 -0
- package/dist/http-origin.js.map +1 -1
- package/dist/index.js +50 -28
- package/dist/index.js.map +1 -1
- package/dist/input/text-source.d.ts +9 -0
- package/dist/input/text-source.js +74 -0
- package/dist/input/text-source.js.map +1 -0
- package/dist/product-map-commands.d.ts +2 -0
- package/dist/product-map-commands.js +2 -0
- package/dist/product-map-commands.js.map +1 -1
- package/dist/program.d.ts +3 -0
- package/dist/program.js +19 -0
- package/dist/program.js.map +1 -0
- package/dist/project-administration-commands.d.ts +3 -0
- package/dist/project-administration-commands.js +31 -0
- package/dist/project-administration-commands.js.map +1 -0
- package/dist/resource-command-runtime.d.ts +16 -0
- package/dist/resource-command-runtime.js +2 -0
- package/dist/resource-command-runtime.js.map +1 -0
- package/dist/runtime/errors.d.ts +28 -0
- package/dist/runtime/errors.js +133 -0
- package/dist/runtime/errors.js.map +1 -0
- package/dist/runtime/execute.d.ts +23 -0
- package/dist/runtime/execute.js +25 -0
- package/dist/runtime/execute.js.map +1 -0
- package/dist/runtime/identity.d.ts +183 -0
- package/dist/runtime/identity.js +17 -0
- package/dist/runtime/identity.js.map +1 -0
- package/dist/runtime/output.d.ts +3 -0
- package/dist/runtime/output.js +13 -0
- package/dist/runtime/output.js.map +1 -0
- package/dist/runtime/session.d.ts +16 -0
- package/dist/runtime/session.js +123 -0
- package/dist/runtime/session.js.map +1 -0
- package/dist/screen-image-commands.d.ts +10 -0
- package/dist/screen-image-commands.js +77 -0
- package/dist/screen-image-commands.js.map +1 -0
- package/dist/spec-discussion-commands.d.ts +3 -0
- package/dist/spec-discussion-commands.js +56 -0
- package/dist/spec-discussion-commands.js.map +1 -0
- package/dist/spec-owner-commands.d.ts +3 -0
- package/dist/spec-owner-commands.js +37 -0
- package/dist/spec-owner-commands.js.map +1 -0
- package/dist/work-item-asset-commands.d.ts +13 -0
- package/dist/work-item-asset-commands.js +10 -9
- package/dist/work-item-asset-commands.js.map +1 -1
- package/dist/work-item-query-commands.d.ts +3 -0
- package/dist/work-item-query-commands.js +29 -0
- package/dist/work-item-query-commands.js.map +1 -0
- package/package.json +1 -1
- package/dist/work-item-time-entry-input.d.ts +0 -4
- package/dist/work-item-time-entry-input.js +0 -27
- package/dist/work-item-time-entry-input.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/runtime/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type createClient from "openapi-fetch";
|
|
2
|
+
import type { paths } from "@spec-flow/api-client";
|
|
3
|
+
import { type SkillError } from "./errors.js";
|
|
4
|
+
export interface ApiResult<T> {
|
|
5
|
+
readonly data?: T;
|
|
6
|
+
readonly error?: unknown;
|
|
7
|
+
readonly response: Response;
|
|
8
|
+
}
|
|
9
|
+
export interface ExecuteOptions {
|
|
10
|
+
readonly ambiguousOutcomeMessage?: string;
|
|
11
|
+
readonly rejectWorkspaceReadToken?: boolean;
|
|
12
|
+
readonly requireUserSession?: boolean;
|
|
13
|
+
readonly retryTransportOnce?: boolean;
|
|
14
|
+
readonly validateSuccess?: (data: unknown) => SkillError | null;
|
|
15
|
+
}
|
|
16
|
+
export type ExecutionResult<T> = {
|
|
17
|
+
readonly ok: true;
|
|
18
|
+
readonly data: T;
|
|
19
|
+
} | {
|
|
20
|
+
readonly ok: false;
|
|
21
|
+
readonly error: SkillError;
|
|
22
|
+
};
|
|
23
|
+
export declare function execute<T>(request: (client: ReturnType<typeof createClient<paths>>) => Promise<ApiResult<T>>, client: ReturnType<typeof createClient<paths>>, options?: ExecuteOptions): Promise<ExecutionResult<T>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { mapHttpFailure } from "./errors.js";
|
|
2
|
+
export async function execute(request, client, options = {}) {
|
|
3
|
+
let result;
|
|
4
|
+
try {
|
|
5
|
+
result = await request(client);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return { ok: false, error: options.retryTransportOnce === true ? ambiguousMutationError(options.ambiguousOutcomeMessage) : { message: "SpecFlow is temporarily unavailable", reason: "Temporary Failure", retryable: true } };
|
|
9
|
+
}
|
|
10
|
+
if (result.response.ok && result.data !== undefined) {
|
|
11
|
+
const error = options.validateSuccess?.(result.data) ?? null;
|
|
12
|
+
return error === null ? { ok: true, data: result.data } : { ok: false, error };
|
|
13
|
+
}
|
|
14
|
+
return { ok: false, error: result.response.ok && options.retryTransportOnce === true ? ambiguousMutationError(options.ambiguousOutcomeMessage) : mapHttpFailure(result.response, result.error) };
|
|
15
|
+
}
|
|
16
|
+
function ambiguousMutationError(message) {
|
|
17
|
+
return {
|
|
18
|
+
message: message ??
|
|
19
|
+
"Write outcome is unknown; read the target resource before trying a new command identity",
|
|
20
|
+
code: "EXECUTION_OUTCOME_UNKNOWN",
|
|
21
|
+
reason: "Temporary Failure",
|
|
22
|
+
retryable: false,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/runtime/execute.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAmB,MAAM,aAAa,CAAC;AAW9D,MAAM,CAAC,KAAK,UAAU,OAAO,CAAI,OAAkF,EAAE,MAA8C,EAAE,UAA0B,EAAE;IAC/L,IAAI,MAAoB,CAAC;IACzB,IAAI,CAAC;QAAC,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IACvC,MAAM,CAAC;QAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,qCAAqC,EAAE,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC;IAAC,CAAC;IACxO,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;QAC7D,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACjF,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACnM,CAAC;AACD,SAAS,sBAAsB,CAAC,OAAgB;IAC9C,OAAO;QACL,OAAO,EACL,OAAO;YACP,yFAAyF;QAC3F,IAAI,EAAE,2BAA2B;QACjC,MAAM,EAAE,mBAAmB;QAC3B,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import type createClient from "openapi-fetch";
|
|
2
|
+
import type { paths } from "@spec-flow/api-client";
|
|
3
|
+
export declare function readIdentity(client: ReturnType<typeof createClient<paths>>): Promise<import("openapi-fetch").FetchResponse<{
|
|
4
|
+
parameters: {
|
|
5
|
+
query?: never;
|
|
6
|
+
header?: never;
|
|
7
|
+
path?: never;
|
|
8
|
+
cookie?: never;
|
|
9
|
+
};
|
|
10
|
+
requestBody?: never;
|
|
11
|
+
responses: {
|
|
12
|
+
200: {
|
|
13
|
+
headers: {
|
|
14
|
+
[name: string]: unknown;
|
|
15
|
+
};
|
|
16
|
+
content: {
|
|
17
|
+
"application/json": {
|
|
18
|
+
user: {
|
|
19
|
+
id: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
400: {
|
|
25
|
+
headers: {
|
|
26
|
+
[name: string]: unknown;
|
|
27
|
+
};
|
|
28
|
+
content: {
|
|
29
|
+
"application/json": {
|
|
30
|
+
code: string;
|
|
31
|
+
message: string;
|
|
32
|
+
issues?: {
|
|
33
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
34
|
+
path: (string | number)[];
|
|
35
|
+
rule: string;
|
|
36
|
+
message: string;
|
|
37
|
+
}[];
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
401: {
|
|
42
|
+
headers: {
|
|
43
|
+
[name: string]: unknown;
|
|
44
|
+
};
|
|
45
|
+
content: {
|
|
46
|
+
"application/json": {
|
|
47
|
+
code: string;
|
|
48
|
+
message: string;
|
|
49
|
+
issues?: {
|
|
50
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
51
|
+
path: (string | number)[];
|
|
52
|
+
rule: string;
|
|
53
|
+
message: string;
|
|
54
|
+
}[];
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
403: {
|
|
59
|
+
headers: {
|
|
60
|
+
[name: string]: unknown;
|
|
61
|
+
};
|
|
62
|
+
content: {
|
|
63
|
+
"application/json": {
|
|
64
|
+
code: string;
|
|
65
|
+
message: string;
|
|
66
|
+
issues?: {
|
|
67
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
68
|
+
path: (string | number)[];
|
|
69
|
+
rule: string;
|
|
70
|
+
message: string;
|
|
71
|
+
}[];
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
503: {
|
|
76
|
+
headers: {
|
|
77
|
+
[name: string]: unknown;
|
|
78
|
+
};
|
|
79
|
+
content: {
|
|
80
|
+
"application/json": {
|
|
81
|
+
code: string;
|
|
82
|
+
message: string;
|
|
83
|
+
issues?: {
|
|
84
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
85
|
+
path: (string | number)[];
|
|
86
|
+
rule: string;
|
|
87
|
+
message: string;
|
|
88
|
+
}[];
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
}, import("openapi-fetch").FetchOptions<{
|
|
94
|
+
parameters: {
|
|
95
|
+
query?: never;
|
|
96
|
+
header?: never;
|
|
97
|
+
path?: never;
|
|
98
|
+
cookie?: never;
|
|
99
|
+
};
|
|
100
|
+
requestBody?: never;
|
|
101
|
+
responses: {
|
|
102
|
+
200: {
|
|
103
|
+
headers: {
|
|
104
|
+
[name: string]: unknown;
|
|
105
|
+
};
|
|
106
|
+
content: {
|
|
107
|
+
"application/json": {
|
|
108
|
+
user: {
|
|
109
|
+
id: string;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
400: {
|
|
115
|
+
headers: {
|
|
116
|
+
[name: string]: unknown;
|
|
117
|
+
};
|
|
118
|
+
content: {
|
|
119
|
+
"application/json": {
|
|
120
|
+
code: string;
|
|
121
|
+
message: string;
|
|
122
|
+
issues?: {
|
|
123
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
124
|
+
path: (string | number)[];
|
|
125
|
+
rule: string;
|
|
126
|
+
message: string;
|
|
127
|
+
}[];
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
401: {
|
|
132
|
+
headers: {
|
|
133
|
+
[name: string]: unknown;
|
|
134
|
+
};
|
|
135
|
+
content: {
|
|
136
|
+
"application/json": {
|
|
137
|
+
code: string;
|
|
138
|
+
message: string;
|
|
139
|
+
issues?: {
|
|
140
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
141
|
+
path: (string | number)[];
|
|
142
|
+
rule: string;
|
|
143
|
+
message: string;
|
|
144
|
+
}[];
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
403: {
|
|
149
|
+
headers: {
|
|
150
|
+
[name: string]: unknown;
|
|
151
|
+
};
|
|
152
|
+
content: {
|
|
153
|
+
"application/json": {
|
|
154
|
+
code: string;
|
|
155
|
+
message: string;
|
|
156
|
+
issues?: {
|
|
157
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
158
|
+
path: (string | number)[];
|
|
159
|
+
rule: string;
|
|
160
|
+
message: string;
|
|
161
|
+
}[];
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
503: {
|
|
166
|
+
headers: {
|
|
167
|
+
[name: string]: unknown;
|
|
168
|
+
};
|
|
169
|
+
content: {
|
|
170
|
+
"application/json": {
|
|
171
|
+
code: string;
|
|
172
|
+
message: string;
|
|
173
|
+
issues?: {
|
|
174
|
+
location: "body" | "query" | "path" | "headers" | "tool";
|
|
175
|
+
path: (string | number)[];
|
|
176
|
+
rule: string;
|
|
177
|
+
message: string;
|
|
178
|
+
}[];
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
}> | undefined, `${string}/${string}`>>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const identitySchema = z.object({ user: z.object({ id: z.string().min(1) }) });
|
|
3
|
+
export async function readIdentity(client) {
|
|
4
|
+
const result = await client.GET("/v1/identity");
|
|
5
|
+
// Only Fastify's recognizable missing-route response means an older API.
|
|
6
|
+
// Authorization failures and resource 404s retain their ordinary categories.
|
|
7
|
+
const payload = result.error;
|
|
8
|
+
const missingRoute = z.object({ message: z.literal("Route GET:/v1/identity not found"), error: z.literal("Not Found"), statusCode: z.literal(404) }).safeParse(payload).success;
|
|
9
|
+
const missingCode = typeof payload === "object" && payload !== null && "code" in payload && payload.code === "FST_ERR_NOT_FOUND";
|
|
10
|
+
if (result.response.status === 404 && (missingRoute || missingCode)) {
|
|
11
|
+
return { response: result.response, error: { code: "IDENTITY_NOT_SUPPORTED", message: "This server version does not support current identity; upgrade the server or provide a User ID" } };
|
|
12
|
+
}
|
|
13
|
+
if (result.response.ok && !identitySchema.safeParse(result.data).success)
|
|
14
|
+
throw new Error("Invalid current identity response");
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/runtime/identity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAA+B,CAAC;AAE7G,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAA8C;IAC/E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChD,yEAAyE;IACzE,6EAA6E;IAC7E,MAAM,OAAO,GAAY,MAAM,CAAC,KAAK,CAAC;IACtC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,kCAAkC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;IAChL,MAAM,WAAW,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,MAAM,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,mBAAmB,CAAC;IACjI,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,WAAW,CAAC,EAAE,CAAC;QACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,gGAAgG,EAAE,EAAE,CAAC;IAC7L,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAC/H,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { writeSkillError } from "./errors.js";
|
|
2
|
+
/** Local failures never enter transport retry or claim that a write failed. */
|
|
3
|
+
export function writeResult(dependencies, project) {
|
|
4
|
+
try {
|
|
5
|
+
dependencies.stdout(`${JSON.stringify(project())}\n`);
|
|
6
|
+
return 0;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
writeSkillError(dependencies, { code: "LOCAL_OUTPUT_FAILED", message: "The result could not be written locally; the server operation may have completed. Read the resource before retrying", reason: "Temporary Failure", retryable: false });
|
|
10
|
+
return 4;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/runtime/output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,+EAA+E;AAC/E,MAAM,UAAU,WAAW,CAAC,YAA6B,EAAE,OAAsB;IAC/E,IAAI,CAAC;QACH,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;QACtD,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,qHAAqH,EAAE,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9O,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { paths } from "@spec-flow/api-client";
|
|
2
|
+
import type { CliDependencies } from "../cli.js";
|
|
3
|
+
import type { ExecuteOptions } from "./execute.js";
|
|
4
|
+
export declare function selectSession(dependencies: CliDependencies, options: ExecuteOptions, serverFlag?: unknown, apiKeyIdFlag?: unknown): Promise<{
|
|
5
|
+
exitCode: number;
|
|
6
|
+
client?: never;
|
|
7
|
+
identityClient?: never;
|
|
8
|
+
credentialKind?: never;
|
|
9
|
+
} | {
|
|
10
|
+
client: import("openapi-fetch").Client<paths, `${string}/${string}`>;
|
|
11
|
+
identityClient: import("openapi-fetch").Client<paths, `${string}/${string}`>;
|
|
12
|
+
credentialKind: "api-key" | "workspace-read-token" | "session";
|
|
13
|
+
exitCode?: never;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function rejectWorkspaceReadTokenOperation(dependencies: CliDependencies): number;
|
|
16
|
+
export declare function hasWorkspaceReadToken(environment: Readonly<Record<string, string | undefined>>): boolean;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import createClient from "openapi-fetch";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { parseHttpOrigin, unresolvedSpecFlowApiOrigin } from "../http-origin.js";
|
|
4
|
+
import { specFlowCliUserAgent } from "../user-agent.js";
|
|
5
|
+
import { writeSkillError } from "./errors.js";
|
|
6
|
+
export async function selectSession(dependencies, options, serverFlag, apiKeyIdFlag) {
|
|
7
|
+
if (dependencies.environment.SPEC_FLOW_PROJECT_READ_TOKEN !== undefined) {
|
|
8
|
+
writeSkillError(dependencies, { message: "Project Read Tokens are retired; use a Workspace read-only Token", reason: "Authentication Failed", retryable: false });
|
|
9
|
+
return { exitCode: 2 };
|
|
10
|
+
}
|
|
11
|
+
const environmentCredential = dependencies.environment.SPEC_FLOW_WORKSPACE_READ_TOKEN;
|
|
12
|
+
const apiKeyEnvironment = dependencies.environment.SPEC_FLOW_API_KEY;
|
|
13
|
+
const usesApiKey = apiKeyEnvironment !== undefined || apiKeyIdFlag !== undefined;
|
|
14
|
+
if (options.requireUserSession === true && (usesApiKey || hasWorkspaceReadToken(dependencies.environment))) {
|
|
15
|
+
writeSkillError(dependencies, { message: "A User Session is required for account management", reason: "Permission Denied", retryable: false });
|
|
16
|
+
return { exitCode: 3 };
|
|
17
|
+
}
|
|
18
|
+
if ((apiKeyEnvironment !== undefined && apiKeyIdFlag !== undefined) || (usesApiKey && hasWorkspaceReadToken(dependencies.environment))) {
|
|
19
|
+
writeSkillError(dependencies, { message: "Select exactly one API Key or Workspace read-only Token credential", reason: "Invalid Operation", retryable: false });
|
|
20
|
+
return { exitCode: 2 };
|
|
21
|
+
}
|
|
22
|
+
if (apiKeyIdFlag !== undefined && !z.uuid().safeParse(apiKeyIdFlag).success) {
|
|
23
|
+
writeSkillError(dependencies, { message: "API Key ID must be a UUID", reason: "Invalid Operation", retryable: false });
|
|
24
|
+
return { exitCode: 2 };
|
|
25
|
+
}
|
|
26
|
+
if (apiKeyEnvironment !== undefined && !/^sfk_[A-Za-z0-9_-]{43}$/u.test(apiKeyEnvironment)) {
|
|
27
|
+
writeSkillError(dependencies, { message: "SPEC_FLOW_API_KEY does not contain a User API Key", reason: "Authentication Failed", retryable: false });
|
|
28
|
+
return { exitCode: 2 };
|
|
29
|
+
}
|
|
30
|
+
if (options.rejectWorkspaceReadToken === true &&
|
|
31
|
+
hasWorkspaceReadToken(dependencies.environment)) {
|
|
32
|
+
return { exitCode: rejectWorkspaceReadTokenOperation(dependencies) };
|
|
33
|
+
}
|
|
34
|
+
const baseUrl = resolveApiOrigin(dependencies, serverFlag);
|
|
35
|
+
if (baseUrl === null) {
|
|
36
|
+
return { exitCode: 2 };
|
|
37
|
+
}
|
|
38
|
+
let credential;
|
|
39
|
+
try {
|
|
40
|
+
if (apiKeyEnvironment !== undefined)
|
|
41
|
+
credential = apiKeyEnvironment;
|
|
42
|
+
else if (typeof apiKeyIdFlag === "string") {
|
|
43
|
+
if (dependencies.credentialStore.readApiKey === undefined)
|
|
44
|
+
throw new Error("API Key storage is unavailable");
|
|
45
|
+
credential = await dependencies.credentialStore.readApiKey(apiKeyIdFlag.toLowerCase());
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
credential = environmentCredential ?? await dependencies.credentialStore.read();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
writeSkillError(dependencies, {
|
|
53
|
+
message: "The CLI credential store is temporarily unavailable",
|
|
54
|
+
reason: "Temporary Failure",
|
|
55
|
+
retryable: true,
|
|
56
|
+
});
|
|
57
|
+
return { exitCode: 4 };
|
|
58
|
+
}
|
|
59
|
+
if (credential === null || credential.trim().length === 0) {
|
|
60
|
+
writeSkillError(dependencies, {
|
|
61
|
+
message: "An authenticated CLI Session, User API Key or Workspace read-only Token is required",
|
|
62
|
+
reason: "Authentication Failed",
|
|
63
|
+
retryable: false,
|
|
64
|
+
});
|
|
65
|
+
return { exitCode: 2 };
|
|
66
|
+
}
|
|
67
|
+
const configuration = {
|
|
68
|
+
baseUrl,
|
|
69
|
+
...(usesApiKey || options.requireUserSession === true ? { redirect: "error" } : {}),
|
|
70
|
+
headers: {
|
|
71
|
+
...(usesApiKey ? { "x-api-key": credential } : { authorization: `Bearer ${credential}` }),
|
|
72
|
+
"user-agent": specFlowCliUserAgent,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
const client = createClient({ ...configuration,
|
|
76
|
+
fetch: options.retryTransportOnce === true
|
|
77
|
+
? retryTransportOnce(dependencies.fetch)
|
|
78
|
+
: dependencies.fetch,
|
|
79
|
+
});
|
|
80
|
+
// Identity is a new prerequisite read, not a mutation transport retry. Both
|
|
81
|
+
// clients reuse the one already selected origin and credential.
|
|
82
|
+
const identityClient = options.retryTransportOnce === true ? createClient({ ...configuration, fetch: dependencies.fetch }) : client;
|
|
83
|
+
return { client, identityClient, credentialKind: usesApiKey ? "api-key" : hasWorkspaceReadToken(dependencies.environment) ? "workspace-read-token" : "session" };
|
|
84
|
+
}
|
|
85
|
+
function retryTransportOnce(fetch) {
|
|
86
|
+
return async (request) => {
|
|
87
|
+
const retryRequest = request.clone();
|
|
88
|
+
try {
|
|
89
|
+
return await fetch(request);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return fetch(retryRequest);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function resolveApiOrigin(dependencies, serverFlag) {
|
|
97
|
+
const flag = typeof serverFlag === "string" ? serverFlag : undefined;
|
|
98
|
+
const result = parseHttpOrigin(unresolvedSpecFlowApiOrigin(flag, dependencies.environment.SPEC_FLOW_API_URL));
|
|
99
|
+
if (result.valid) {
|
|
100
|
+
return result.origin;
|
|
101
|
+
}
|
|
102
|
+
writeSkillError(dependencies, {
|
|
103
|
+
message: flag === undefined
|
|
104
|
+
? "SPEC_FLOW_API_URL must be an HTTP(S) origin without a path"
|
|
105
|
+
: "--server must be an HTTP(S) origin without a path",
|
|
106
|
+
reason: "Invalid Operation",
|
|
107
|
+
retryable: false,
|
|
108
|
+
});
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
export function rejectWorkspaceReadTokenOperation(dependencies) {
|
|
112
|
+
writeSkillError(dependencies, {
|
|
113
|
+
message: "Workspace read-only Token does not permit this operation",
|
|
114
|
+
reason: "Permission Denied",
|
|
115
|
+
retryable: false,
|
|
116
|
+
});
|
|
117
|
+
return 3;
|
|
118
|
+
}
|
|
119
|
+
export function hasWorkspaceReadToken(environment) {
|
|
120
|
+
const credential = environment.SPEC_FLOW_WORKSPACE_READ_TOKEN;
|
|
121
|
+
return credential !== undefined && credential.trim().length > 0;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/runtime/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { CliDependencies } from "./cli.js";
|
|
3
|
+
import type { ResourceCommandRuntime } from "./resource-command-runtime.js";
|
|
4
|
+
interface Runtime extends Pick<ResourceCommandRuntime, "run" | "setExitCode" | "parseOpaqueVersion"> {
|
|
5
|
+
readonly dependencies: CliDependencies;
|
|
6
|
+
readonly canWrite: () => boolean;
|
|
7
|
+
readonly rejectWrite: () => number;
|
|
8
|
+
}
|
|
9
|
+
export declare function registerScreenImageCommands(screen: Command, runtime: Runtime): void;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { open } from "node:fs/promises";
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
import { readBoundedFile, reservationSchema, validateUploadReservation } from "./work-item-asset-commands.js";
|
|
4
|
+
const maximumBytes = 10 * 1024 * 1024;
|
|
5
|
+
const invalid = (message) => ({ response: new Response(null, { status: 400 }), error: { code: "INVALID_IMAGE_INPUT", message } });
|
|
6
|
+
export function registerScreenImageCommands(screen, runtime) {
|
|
7
|
+
screen.command("image-upload").description("Reserve, PUT local bytes, then finalize a private Screen image")
|
|
8
|
+
.requiredOption("--workspace-id <id>").requiredOption("--screen-id <id>").requiredOption("--file <path>")
|
|
9
|
+
.requiredOption("--content-type <type>").requiredOption("--expected-version <version>", "Observed Screen version", runtime.parseOpaqueVersion)
|
|
10
|
+
.requiredOption("--idempotency-key <key>", "Reservation identity; reuse with identical inputs")
|
|
11
|
+
.requiredOption("--finalize-key <key>", "Separate finalization identity; reuse with identical inputs")
|
|
12
|
+
.action(async (o) => {
|
|
13
|
+
if (!runtime.canWrite()) {
|
|
14
|
+
runtime.setExitCode(runtime.rejectWrite());
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
runtime.setExitCode(await runtime.run(async (c) => {
|
|
18
|
+
let bytes;
|
|
19
|
+
try {
|
|
20
|
+
bytes = await readBoundedFile(o.file, maximumBytes);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return invalid("Image input must be a readable nonempty regular file of at most 10 MiB");
|
|
24
|
+
}
|
|
25
|
+
const params = { path: { workspaceId: o.workspaceId, screenId: o.screenId }, header: { "if-match": o.expectedVersion, "idempotency-key": o.idempotencyKey } };
|
|
26
|
+
const reserved = await c.POST("/v1/workspaces/{workspaceId}/screens/{screenId}/image/uploads", { params, body: { filename: basename(o.file), contentType: o.contentType, size: bytes.byteLength } });
|
|
27
|
+
if (reserved.data === undefined)
|
|
28
|
+
return reserved;
|
|
29
|
+
let request;
|
|
30
|
+
try {
|
|
31
|
+
const reservation = reservationSchema.parse(reserved.data);
|
|
32
|
+
request = new Request(validateUploadReservation(reservation), { method: "PUT", headers: { "Content-Type": reservation.headers["Content-Type"], ...(reservation.headers["x-ms-blob-type"] === undefined ? {} : { "x-ms-blob-type": reservation.headers["x-ms-blob-type"] }) }, body: new Uint8Array(bytes), redirect: "error", credentials: "omit", signal: AbortSignal.timeout(60_000) });
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return invalid("Server upload reservation is invalid or expired; no bytes were sent");
|
|
36
|
+
}
|
|
37
|
+
const retry = request.clone();
|
|
38
|
+
let response;
|
|
39
|
+
try {
|
|
40
|
+
response = await runtime.dependencies.fetch(request);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
response = await runtime.dependencies.fetch(retry);
|
|
44
|
+
}
|
|
45
|
+
await response.body?.cancel();
|
|
46
|
+
if (!response.ok)
|
|
47
|
+
return { response, error: { code: "SCREEN_IMAGE_UPLOAD_FAILED", message: "Upload failed; retain the original inputs and keys" } };
|
|
48
|
+
return c.POST("/v1/workspaces/{workspaceId}/screens/{screenId}/image/finalize", { params: { ...params, header: { ...params.header, "idempotency-key": o.finalizeKey } }, body: { uploadId: reserved.data.uploadId } });
|
|
49
|
+
}));
|
|
50
|
+
});
|
|
51
|
+
screen.command("image-download").description("Download an authorized asset identity into a new owner-only file")
|
|
52
|
+
.requiredOption("--workspace-id <id>").requiredOption("--screen-id <id>").requiredOption("--asset-id <id>").requiredOption("--output-file <path>")
|
|
53
|
+
.action(async (o) => {
|
|
54
|
+
runtime.setExitCode(await runtime.run(async (c) => {
|
|
55
|
+
const result = await c.GET("/v1/workspaces/{workspaceId}/screens/{screenId}/image/assets/{assetId}", { params: { path: { workspaceId: o.workspaceId, screenId: o.screenId, assetId: o.assetId } }, parseAs: "arrayBuffer" });
|
|
56
|
+
if (result.data === undefined)
|
|
57
|
+
return result;
|
|
58
|
+
if (result.data.byteLength > maximumBytes)
|
|
59
|
+
return invalid("Image exceeds the CLI download size limit");
|
|
60
|
+
let file;
|
|
61
|
+
try {
|
|
62
|
+
file = await open(o.outputFile, "wx", 0o600);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return invalid("Choose a writable new output path; existing files are never overwritten");
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
await file.writeFile(new Uint8Array(result.data));
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
await file.close();
|
|
72
|
+
}
|
|
73
|
+
return { response: result.response, data: { assetId: o.assetId, size: result.data.byteLength, outputFile: o.outputFile } };
|
|
74
|
+
}));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=screen-image-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen-image-commands.js","sourceRoot":"","sources":["../src/screen-image-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { InvalidArgumentError } from "commander";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const parse = (schema, message) => (value) => {
|
|
4
|
+
const parsed = schema.safeParse(value);
|
|
5
|
+
if (!parsed.success)
|
|
6
|
+
throw new InvalidArgumentError(message);
|
|
7
|
+
return parsed.data;
|
|
8
|
+
};
|
|
9
|
+
const uuid = parse(z.uuid(), "Thread, comment and command identities must be UUIDs");
|
|
10
|
+
const scenario = parse(z.string().regex(/^[A-Z]{2,10}-S[1-9][0-9]*-[1-9][0-9]*$/u), "Use an allocated stable Scenario identity");
|
|
11
|
+
const content = parse(z.string().trim().min(1).max(10000).regex(/^[^\0]*$/u), "Comment must contain 1 to 10000 characters without NUL");
|
|
12
|
+
const contextHash = parse(z.string().regex(/^[a-f0-9]{64}$/u), "Use the observed server context hash");
|
|
13
|
+
export function registerSpecDiscussionCommands(spec, runtime) {
|
|
14
|
+
const discussion = spec.command("discussion").description("Discuss stable Scenarios in explicit Published or WorkingDraft context");
|
|
15
|
+
const scoped = (command) => command.requiredOption("--workspace-id <id>").requiredOption("--spec-id <id>")
|
|
16
|
+
.option("--context-kind <kind>", "Content view: Published or WorkingDraft", parse(z.enum(["Published", "WorkingDraft"]), "Choose Published or WorkingDraft"), "Published")
|
|
17
|
+
.option("--json", "Emit structured JSON (the default)");
|
|
18
|
+
const thread = (command) => scoped(command).requiredOption("--thread-id <id>", "Thread UUID", uuid);
|
|
19
|
+
const comment = (command) => thread(command).requiredOption("--comment-id <id>", "Comment UUID", uuid);
|
|
20
|
+
const paged = (command) => command.option("--limit <limit>", "Maximum entries, 1 through 100", runtime.parseLimit, 30).option("--cursor <cursor>", "Opaque nextCursor from this view");
|
|
21
|
+
const write = (command) => command.requiredOption("--idempotency-key <key>", "Retain this UUID for the same intent", uuid);
|
|
22
|
+
const observed = (command, resource) => write(command).requiredOption("--expected-version <version>", `Observed ${resource} version`, runtime.parseOpaqueVersion);
|
|
23
|
+
const path = (options) => ({ workspaceId: options.workspaceId, specId: options.specId });
|
|
24
|
+
const threadPath = (options) => ({ ...path(options), threadId: options.threadId });
|
|
25
|
+
const commentPath = (options) => ({ ...threadPath(options), commentId: options.commentId });
|
|
26
|
+
const headers = (options) => ({ "if-match": options.expectedVersion, "idempotency-key": options.idempotencyKey });
|
|
27
|
+
const page = (options) => ({ contextKind: options.contextKind, limit: options.limit, ...(options.cursor === undefined ? {} : { cursor: options.cursor }) });
|
|
28
|
+
const run = async (request, mutation = false) => {
|
|
29
|
+
runtime.setExitCode(await runtime.run(request, { rejectWorkspaceReadToken: true, retryTransportOnce: mutation }));
|
|
30
|
+
};
|
|
31
|
+
scoped(discussion.command("targets")).action(async (options) => run(client => client.GET("/v1/workspaces/{workspaceId}/specs/{specId}/discussion-targets", { params: { path: path(options), query: { contextKind: options.contextKind } } })));
|
|
32
|
+
paged(scoped(discussion.command("list"))).option("--scenario-id <id>", "Filter by allocated Scenario", scenario).action(async (options) => run(client => client.GET("/v1/workspaces/{workspaceId}/specs/{specId}/discussions", { params: { path: path(options), query: { ...page(options), ...(options.scenarioId === undefined ? {} : { scenarioId: options.scenarioId }) } } })));
|
|
33
|
+
paged(thread(discussion.command("comments"))).action(async (options) => run(client => client.GET("/v1/workspaces/{workspaceId}/specs/{specId}/discussions/{threadId}/comments", { params: { path: threadPath(options), query: page(options) } })));
|
|
34
|
+
write(scoped(discussion.command("start"))).requiredOption("--scenario-id <id>", "Allocated Scenario from targets", scenario)
|
|
35
|
+
.requiredOption("--context-hash <hash>", "Hash from targets in the selected view", contextHash).requiredOption("--content <markdown>", "Comment text", content)
|
|
36
|
+
.action(async (options) => run(client => client.POST("/v1/workspaces/{workspaceId}/specs/{specId}/discussions", {
|
|
37
|
+
params: { path: path(options), header: { "idempotency-key": options.idempotencyKey } }, body: { contextKind: options.contextKind, contextHash: options.contextHash, scenarioId: options.scenarioId, content: options.content },
|
|
38
|
+
}), true));
|
|
39
|
+
write(thread(discussion.command("reply"))).requiredOption("--context-hash <hash>", "Hash from targets in the selected view", contextHash).requiredOption("--content <markdown>", "Comment text", content)
|
|
40
|
+
.action(async (options) => run(client => client.POST("/v1/workspaces/{workspaceId}/specs/{specId}/discussions/{threadId}/comments", {
|
|
41
|
+
params: { path: threadPath(options), header: { "idempotency-key": options.idempotencyKey } }, body: { contextKind: options.contextKind, contextHash: options.contextHash, content: options.content },
|
|
42
|
+
}), true));
|
|
43
|
+
observed(comment(discussion.command("edit-comment")), "comment").requiredOption("--content <markdown>", "Replacement for your own comment", content)
|
|
44
|
+
.action(async (options) => run(client => client.PATCH("/v1/workspaces/{workspaceId}/specs/{specId}/discussions/{threadId}/comments/{commentId}", {
|
|
45
|
+
params: { path: commentPath(options), header: headers(options) }, body: { contextKind: options.contextKind, content: options.content },
|
|
46
|
+
}), true));
|
|
47
|
+
observed(comment(discussion.command("delete-comment")), "comment").action(async (options) => run(client => client.DELETE("/v1/workspaces/{workspaceId}/specs/{specId}/discussions/{threadId}/comments/{commentId}", {
|
|
48
|
+
params: { path: commentPath(options), header: headers(options), query: { contextKind: options.contextKind } },
|
|
49
|
+
}), true));
|
|
50
|
+
for (const operation of ["resolve", "reopen"]) {
|
|
51
|
+
observed(thread(discussion.command(operation)), "thread").action(async (options) => run(client => client.PATCH("/v1/workspaces/{workspaceId}/specs/{specId}/discussions/{threadId}/status", {
|
|
52
|
+
params: { path: threadPath(options), header: headers(options) }, body: { contextKind: options.contextKind, status: operation === "resolve" ? "Resolved" : "Open" },
|
|
53
|
+
}), true));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=spec-discussion-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-discussion-commands.js","sourceRoot":"","sources":["../src/spec-discussion-commands.ts"],"names":[],"mappings":"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"}
|