@zhuk/spego 0.21.1 → 0.22.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.
- package/CHANGELOG.md +17 -0
- package/README.md +37 -229
- package/dist/artifacts/schemas.d.ts +1 -1
- package/dist/artifacts/schemas.js +12 -1
- package/dist/artifacts/schemas.js.map +1 -1
- package/dist/artifacts/types.d.ts +8 -0
- package/dist/artifacts/types.js +7 -0
- package/dist/artifacts/types.js.map +1 -1
- package/dist/cli/commands/board.js +38 -7
- package/dist/cli/commands/board.js.map +1 -1
- package/dist/cli/commands/record.d.ts +10 -0
- package/dist/cli/commands/record.js +80 -0
- package/dist/cli/commands/record.js.map +1 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/command-meta/registry.js +13 -0
- package/dist/command-meta/registry.js.map +1 -1
- package/dist/delivery/load.js +10 -4
- package/dist/delivery/load.js.map +1 -1
- package/dist/delivery/mirror.d.ts +34 -1
- package/dist/delivery/mirror.js +225 -1
- package/dist/delivery/mirror.js.map +1 -1
- package/dist/delivery/store.d.ts +14 -0
- package/dist/delivery/store.js +56 -0
- package/dist/delivery/store.js.map +1 -0
- package/dist/workflows/registry.js +2 -2
- package/dist/workflows/registry.js.map +1 -1
- package/dist/workspace/config.d.ts +289 -0
- package/dist/workspace/config.js +30 -0
- package/dist/workspace/config.js.map +1 -1
- package/dist/workspace/paths.d.ts +10 -0
- package/dist/workspace/paths.js +25 -0
- package/dist/workspace/paths.js.map +1 -1
- package/docs/agent-targets.md +32 -0
- package/docs/cli.md +49 -0
- package/docs/delivery-board.md +63 -0
- package/docs/estimation.md +90 -0
- package/docs/openspec-adapter.md +38 -0
- package/docs/workflows.md +129 -0
- package/package.json +2 -1
|
@@ -1,4 +1,141 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
/** Hours per Size Tier for one Flow profile or the shared human table. */
|
|
3
|
+
declare const tierHoursSchema: z.ZodObject<{
|
|
4
|
+
xs: z.ZodNumber;
|
|
5
|
+
s: z.ZodNumber;
|
|
6
|
+
m: z.ZodNumber;
|
|
7
|
+
l: z.ZodNumber;
|
|
8
|
+
xl: z.ZodNumber;
|
|
9
|
+
}, "strict", z.ZodTypeAny, {
|
|
10
|
+
xs: number;
|
|
11
|
+
s: number;
|
|
12
|
+
m: number;
|
|
13
|
+
l: number;
|
|
14
|
+
xl: number;
|
|
15
|
+
}, {
|
|
16
|
+
xs: number;
|
|
17
|
+
s: number;
|
|
18
|
+
m: number;
|
|
19
|
+
l: number;
|
|
20
|
+
xl: number;
|
|
21
|
+
}>;
|
|
22
|
+
export type TierHours = z.infer<typeof tierHoursSchema>;
|
|
23
|
+
/** Pricing configuration: per-Flow seed tables plus one shared human table. */
|
|
24
|
+
export declare const flowsSchema: z.ZodEffects<z.ZodObject<{
|
|
25
|
+
/** Flow profile that prices a change whose epic declares no `flow`. */
|
|
26
|
+
default: z.ZodString;
|
|
27
|
+
/** Per-Flow seed tables mapping Size Tier to Flow Hours. */
|
|
28
|
+
profiles: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
29
|
+
xs: z.ZodNumber;
|
|
30
|
+
s: z.ZodNumber;
|
|
31
|
+
m: z.ZodNumber;
|
|
32
|
+
l: z.ZodNumber;
|
|
33
|
+
xl: z.ZodNumber;
|
|
34
|
+
}, "strict", z.ZodTypeAny, {
|
|
35
|
+
xs: number;
|
|
36
|
+
s: number;
|
|
37
|
+
m: number;
|
|
38
|
+
l: number;
|
|
39
|
+
xl: number;
|
|
40
|
+
}, {
|
|
41
|
+
xs: number;
|
|
42
|
+
s: number;
|
|
43
|
+
m: number;
|
|
44
|
+
l: number;
|
|
45
|
+
xl: number;
|
|
46
|
+
}>>;
|
|
47
|
+
/** Human Hours table, shared across Flows. */
|
|
48
|
+
human: z.ZodObject<{
|
|
49
|
+
xs: z.ZodNumber;
|
|
50
|
+
s: z.ZodNumber;
|
|
51
|
+
m: z.ZodNumber;
|
|
52
|
+
l: z.ZodNumber;
|
|
53
|
+
xl: z.ZodNumber;
|
|
54
|
+
}, "strict", z.ZodTypeAny, {
|
|
55
|
+
xs: number;
|
|
56
|
+
s: number;
|
|
57
|
+
m: number;
|
|
58
|
+
l: number;
|
|
59
|
+
xl: number;
|
|
60
|
+
}, {
|
|
61
|
+
xs: number;
|
|
62
|
+
s: number;
|
|
63
|
+
m: number;
|
|
64
|
+
l: number;
|
|
65
|
+
xl: number;
|
|
66
|
+
}>;
|
|
67
|
+
/** Opt-in to the cross-project pricing rung; off keeps pricing reproducible from the repo alone. */
|
|
68
|
+
crossProject: z.ZodDefault<z.ZodBoolean>;
|
|
69
|
+
}, "strict", z.ZodTypeAny, {
|
|
70
|
+
default: string;
|
|
71
|
+
profiles: Record<string, {
|
|
72
|
+
xs: number;
|
|
73
|
+
s: number;
|
|
74
|
+
m: number;
|
|
75
|
+
l: number;
|
|
76
|
+
xl: number;
|
|
77
|
+
}>;
|
|
78
|
+
human: {
|
|
79
|
+
xs: number;
|
|
80
|
+
s: number;
|
|
81
|
+
m: number;
|
|
82
|
+
l: number;
|
|
83
|
+
xl: number;
|
|
84
|
+
};
|
|
85
|
+
crossProject: boolean;
|
|
86
|
+
}, {
|
|
87
|
+
default: string;
|
|
88
|
+
profiles: Record<string, {
|
|
89
|
+
xs: number;
|
|
90
|
+
s: number;
|
|
91
|
+
m: number;
|
|
92
|
+
l: number;
|
|
93
|
+
xl: number;
|
|
94
|
+
}>;
|
|
95
|
+
human: {
|
|
96
|
+
xs: number;
|
|
97
|
+
s: number;
|
|
98
|
+
m: number;
|
|
99
|
+
l: number;
|
|
100
|
+
xl: number;
|
|
101
|
+
};
|
|
102
|
+
crossProject?: boolean | undefined;
|
|
103
|
+
}>, {
|
|
104
|
+
default: string;
|
|
105
|
+
profiles: Record<string, {
|
|
106
|
+
xs: number;
|
|
107
|
+
s: number;
|
|
108
|
+
m: number;
|
|
109
|
+
l: number;
|
|
110
|
+
xl: number;
|
|
111
|
+
}>;
|
|
112
|
+
human: {
|
|
113
|
+
xs: number;
|
|
114
|
+
s: number;
|
|
115
|
+
m: number;
|
|
116
|
+
l: number;
|
|
117
|
+
xl: number;
|
|
118
|
+
};
|
|
119
|
+
crossProject: boolean;
|
|
120
|
+
}, {
|
|
121
|
+
default: string;
|
|
122
|
+
profiles: Record<string, {
|
|
123
|
+
xs: number;
|
|
124
|
+
s: number;
|
|
125
|
+
m: number;
|
|
126
|
+
l: number;
|
|
127
|
+
xl: number;
|
|
128
|
+
}>;
|
|
129
|
+
human: {
|
|
130
|
+
xs: number;
|
|
131
|
+
s: number;
|
|
132
|
+
m: number;
|
|
133
|
+
l: number;
|
|
134
|
+
xl: number;
|
|
135
|
+
};
|
|
136
|
+
crossProject?: boolean | undefined;
|
|
137
|
+
}>;
|
|
138
|
+
export type FlowsConfig = z.infer<typeof flowsSchema>;
|
|
2
139
|
export declare const workspaceConfigSchema: z.ZodObject<{
|
|
3
140
|
/** Schema version. Bump when config layout changes. */
|
|
4
141
|
version: z.ZodDefault<z.ZodLiteral<1>>;
|
|
@@ -18,6 +155,121 @@ export declare const workspaceConfigSchema: z.ZodObject<{
|
|
|
18
155
|
options?: Record<string, unknown> | undefined;
|
|
19
156
|
name?: string | undefined;
|
|
20
157
|
}>>;
|
|
158
|
+
/** Change pricing tables; absent means the workspace renders unpriced. */
|
|
159
|
+
flows: z.ZodOptional<z.ZodEffects<z.ZodObject<{
|
|
160
|
+
/** Flow profile that prices a change whose epic declares no `flow`. */
|
|
161
|
+
default: z.ZodString;
|
|
162
|
+
/** Per-Flow seed tables mapping Size Tier to Flow Hours. */
|
|
163
|
+
profiles: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
164
|
+
xs: z.ZodNumber;
|
|
165
|
+
s: z.ZodNumber;
|
|
166
|
+
m: z.ZodNumber;
|
|
167
|
+
l: z.ZodNumber;
|
|
168
|
+
xl: z.ZodNumber;
|
|
169
|
+
}, "strict", z.ZodTypeAny, {
|
|
170
|
+
xs: number;
|
|
171
|
+
s: number;
|
|
172
|
+
m: number;
|
|
173
|
+
l: number;
|
|
174
|
+
xl: number;
|
|
175
|
+
}, {
|
|
176
|
+
xs: number;
|
|
177
|
+
s: number;
|
|
178
|
+
m: number;
|
|
179
|
+
l: number;
|
|
180
|
+
xl: number;
|
|
181
|
+
}>>;
|
|
182
|
+
/** Human Hours table, shared across Flows. */
|
|
183
|
+
human: z.ZodObject<{
|
|
184
|
+
xs: z.ZodNumber;
|
|
185
|
+
s: z.ZodNumber;
|
|
186
|
+
m: z.ZodNumber;
|
|
187
|
+
l: z.ZodNumber;
|
|
188
|
+
xl: z.ZodNumber;
|
|
189
|
+
}, "strict", z.ZodTypeAny, {
|
|
190
|
+
xs: number;
|
|
191
|
+
s: number;
|
|
192
|
+
m: number;
|
|
193
|
+
l: number;
|
|
194
|
+
xl: number;
|
|
195
|
+
}, {
|
|
196
|
+
xs: number;
|
|
197
|
+
s: number;
|
|
198
|
+
m: number;
|
|
199
|
+
l: number;
|
|
200
|
+
xl: number;
|
|
201
|
+
}>;
|
|
202
|
+
/** Opt-in to the cross-project pricing rung; off keeps pricing reproducible from the repo alone. */
|
|
203
|
+
crossProject: z.ZodDefault<z.ZodBoolean>;
|
|
204
|
+
}, "strict", z.ZodTypeAny, {
|
|
205
|
+
default: string;
|
|
206
|
+
profiles: Record<string, {
|
|
207
|
+
xs: number;
|
|
208
|
+
s: number;
|
|
209
|
+
m: number;
|
|
210
|
+
l: number;
|
|
211
|
+
xl: number;
|
|
212
|
+
}>;
|
|
213
|
+
human: {
|
|
214
|
+
xs: number;
|
|
215
|
+
s: number;
|
|
216
|
+
m: number;
|
|
217
|
+
l: number;
|
|
218
|
+
xl: number;
|
|
219
|
+
};
|
|
220
|
+
crossProject: boolean;
|
|
221
|
+
}, {
|
|
222
|
+
default: string;
|
|
223
|
+
profiles: Record<string, {
|
|
224
|
+
xs: number;
|
|
225
|
+
s: number;
|
|
226
|
+
m: number;
|
|
227
|
+
l: number;
|
|
228
|
+
xl: number;
|
|
229
|
+
}>;
|
|
230
|
+
human: {
|
|
231
|
+
xs: number;
|
|
232
|
+
s: number;
|
|
233
|
+
m: number;
|
|
234
|
+
l: number;
|
|
235
|
+
xl: number;
|
|
236
|
+
};
|
|
237
|
+
crossProject?: boolean | undefined;
|
|
238
|
+
}>, {
|
|
239
|
+
default: string;
|
|
240
|
+
profiles: Record<string, {
|
|
241
|
+
xs: number;
|
|
242
|
+
s: number;
|
|
243
|
+
m: number;
|
|
244
|
+
l: number;
|
|
245
|
+
xl: number;
|
|
246
|
+
}>;
|
|
247
|
+
human: {
|
|
248
|
+
xs: number;
|
|
249
|
+
s: number;
|
|
250
|
+
m: number;
|
|
251
|
+
l: number;
|
|
252
|
+
xl: number;
|
|
253
|
+
};
|
|
254
|
+
crossProject: boolean;
|
|
255
|
+
}, {
|
|
256
|
+
default: string;
|
|
257
|
+
profiles: Record<string, {
|
|
258
|
+
xs: number;
|
|
259
|
+
s: number;
|
|
260
|
+
m: number;
|
|
261
|
+
l: number;
|
|
262
|
+
xl: number;
|
|
263
|
+
}>;
|
|
264
|
+
human: {
|
|
265
|
+
xs: number;
|
|
266
|
+
s: number;
|
|
267
|
+
m: number;
|
|
268
|
+
l: number;
|
|
269
|
+
xl: number;
|
|
270
|
+
};
|
|
271
|
+
crossProject?: boolean | undefined;
|
|
272
|
+
}>>;
|
|
21
273
|
}, "strict", z.ZodTypeAny, {
|
|
22
274
|
agents: string[];
|
|
23
275
|
demo: boolean;
|
|
@@ -27,6 +279,24 @@ export declare const workspaceConfigSchema: z.ZodObject<{
|
|
|
27
279
|
options: Record<string, unknown>;
|
|
28
280
|
name: string;
|
|
29
281
|
};
|
|
282
|
+
flows?: {
|
|
283
|
+
default: string;
|
|
284
|
+
profiles: Record<string, {
|
|
285
|
+
xs: number;
|
|
286
|
+
s: number;
|
|
287
|
+
m: number;
|
|
288
|
+
l: number;
|
|
289
|
+
xl: number;
|
|
290
|
+
}>;
|
|
291
|
+
human: {
|
|
292
|
+
xs: number;
|
|
293
|
+
s: number;
|
|
294
|
+
m: number;
|
|
295
|
+
l: number;
|
|
296
|
+
xl: number;
|
|
297
|
+
};
|
|
298
|
+
crossProject: boolean;
|
|
299
|
+
} | undefined;
|
|
30
300
|
}, {
|
|
31
301
|
agents?: string[] | undefined;
|
|
32
302
|
demo?: boolean | undefined;
|
|
@@ -36,6 +306,24 @@ export declare const workspaceConfigSchema: z.ZodObject<{
|
|
|
36
306
|
options?: Record<string, unknown> | undefined;
|
|
37
307
|
name?: string | undefined;
|
|
38
308
|
} | undefined;
|
|
309
|
+
flows?: {
|
|
310
|
+
default: string;
|
|
311
|
+
profiles: Record<string, {
|
|
312
|
+
xs: number;
|
|
313
|
+
s: number;
|
|
314
|
+
m: number;
|
|
315
|
+
l: number;
|
|
316
|
+
xl: number;
|
|
317
|
+
}>;
|
|
318
|
+
human: {
|
|
319
|
+
xs: number;
|
|
320
|
+
s: number;
|
|
321
|
+
m: number;
|
|
322
|
+
l: number;
|
|
323
|
+
xl: number;
|
|
324
|
+
};
|
|
325
|
+
crossProject?: boolean | undefined;
|
|
326
|
+
} | undefined;
|
|
39
327
|
}>;
|
|
40
328
|
export type WorkspaceConfig = z.infer<typeof workspaceConfigSchema>;
|
|
41
329
|
export declare function defaultConfig(overrides?: Partial<WorkspaceConfig>): WorkspaceConfig;
|
|
@@ -43,3 +331,4 @@ export declare function readConfig(configPath: string): Promise<WorkspaceConfig>
|
|
|
43
331
|
export declare function writeConfig(configPath: string, config: WorkspaceConfig): Promise<void>;
|
|
44
332
|
/** Returns the union of built-in and user-extended artifact types. */
|
|
45
333
|
export declare function knownArtifactTypes(config: WorkspaceConfig): Set<string>;
|
|
334
|
+
export {};
|
package/dist/workspace/config.js
CHANGED
|
@@ -3,6 +3,34 @@ import YAML from 'yaml';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { SpegoError } from '../errors.js';
|
|
5
5
|
import { BUILTIN_ARTIFACT_TYPES } from '../artifacts/types.js';
|
|
6
|
+
const hours = z.number().finite().nonnegative();
|
|
7
|
+
/** Hours per Size Tier for one Flow profile or the shared human table. */
|
|
8
|
+
const tierHoursSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
xs: hours,
|
|
11
|
+
s: hours,
|
|
12
|
+
m: hours,
|
|
13
|
+
l: hours,
|
|
14
|
+
xl: hours,
|
|
15
|
+
})
|
|
16
|
+
.strict();
|
|
17
|
+
/** Pricing configuration: per-Flow seed tables plus one shared human table. */
|
|
18
|
+
export const flowsSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
/** Flow profile that prices a change whose epic declares no `flow`. */
|
|
21
|
+
default: z.string().min(1),
|
|
22
|
+
/** Per-Flow seed tables mapping Size Tier to Flow Hours. */
|
|
23
|
+
profiles: z.record(z.string().min(1), tierHoursSchema),
|
|
24
|
+
/** Human Hours table, shared across Flows. */
|
|
25
|
+
human: tierHoursSchema,
|
|
26
|
+
/** Opt-in to the cross-project pricing rung; off keeps pricing reproducible from the repo alone. */
|
|
27
|
+
crossProject: z.boolean().default(false),
|
|
28
|
+
})
|
|
29
|
+
.strict()
|
|
30
|
+
.refine((flows) => Object.hasOwn(flows.profiles, flows.default), {
|
|
31
|
+
path: ['default'],
|
|
32
|
+
message: 'flows.default must name a declared profile',
|
|
33
|
+
});
|
|
6
34
|
export const workspaceConfigSchema = z
|
|
7
35
|
.object({
|
|
8
36
|
/** Schema version. Bump when config layout changes. */
|
|
@@ -19,6 +47,8 @@ export const workspaceConfigSchema = z
|
|
|
19
47
|
name: z.string().default('openspec'),
|
|
20
48
|
options: z.record(z.string(), z.unknown()).default({}),
|
|
21
49
|
}).default({ name: 'openspec', options: {} }),
|
|
50
|
+
/** Change pricing tables; absent means the workspace renders unpriced. */
|
|
51
|
+
flows: flowsSchema.optional(),
|
|
22
52
|
})
|
|
23
53
|
.strict();
|
|
24
54
|
export function defaultConfig(overrides = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/workspace/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC;KACnC,MAAM,CAAC;IACN,uDAAuD;IACvD,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAChC,8CAA8C;IAC9C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC/C,0CAA0C;IAC1C,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAChC,iEAAiE;IACjE,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,EAAE;QAC1E,OAAO,EAAE,uFAAuF;KACjG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACf,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC;QACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC;QACpC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACvD,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/workspace/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,16 @@ export interface WorkspacePaths {
|
|
|
26
26
|
}
|
|
27
27
|
export declare function resolveWorkspacePaths(projectRoot: string): WorkspacePaths;
|
|
28
28
|
export declare function artifactTypeDir(paths: WorkspacePaths, type: string): string;
|
|
29
|
+
/** Environment variable naming the cross-project store root; overrides the platform configuration directory. */
|
|
30
|
+
export declare const STORE_ROOT_ENV_VAR = "SPEGO_STORE_ROOT";
|
|
31
|
+
export declare const STORE_RUNS_FILE_NAME = "runs.jsonl";
|
|
32
|
+
/**
|
|
33
|
+
* Root of the cross-project run store: the environment override when set,
|
|
34
|
+
* else the platform configuration directory. The variable names the root, not
|
|
35
|
+
* the runs file, so the store's layout can change without a flag change.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveStoreRoot(env?: NodeJS.ProcessEnv): string;
|
|
38
|
+
export declare function storeRunsPath(storeRoot: string): string;
|
|
29
39
|
export declare function artifactFilePath(paths: WorkspacePaths, type: string, slug: string): string;
|
|
30
40
|
export declare function revisionFilePath(paths: WorkspacePaths, type: string, slug: string, revision: number): string;
|
|
31
41
|
/** Lstat-guard .spego then resolve realpath for containment root. */
|
package/dist/workspace/paths.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
2
3
|
import { SpegoError } from '../errors.js';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
/**
|
|
@@ -27,6 +28,30 @@ export function resolveWorkspacePaths(projectRoot) {
|
|
|
27
28
|
export function artifactTypeDir(paths, type) {
|
|
28
29
|
return path.join(paths.artifactsRoot, type);
|
|
29
30
|
}
|
|
31
|
+
/** Environment variable naming the cross-project store root; overrides the platform configuration directory. */
|
|
32
|
+
export const STORE_ROOT_ENV_VAR = 'SPEGO_STORE_ROOT';
|
|
33
|
+
export const STORE_RUNS_FILE_NAME = 'runs.jsonl';
|
|
34
|
+
/**
|
|
35
|
+
* Root of the cross-project run store: the environment override when set,
|
|
36
|
+
* else the platform configuration directory. The variable names the root, not
|
|
37
|
+
* the runs file, so the store's layout can change without a flag change.
|
|
38
|
+
*/
|
|
39
|
+
export function resolveStoreRoot(env = process.env) {
|
|
40
|
+
const override = env[STORE_ROOT_ENV_VAR];
|
|
41
|
+
if (override !== undefined && override.trim().length > 0)
|
|
42
|
+
return path.resolve(override);
|
|
43
|
+
const home = os.homedir();
|
|
44
|
+
if (process.platform === 'win32') {
|
|
45
|
+
return path.join(env.APPDATA ?? path.join(home, '.config'), 'spego');
|
|
46
|
+
}
|
|
47
|
+
if (process.platform === 'darwin') {
|
|
48
|
+
return path.join(home, 'Library', 'Application Support', 'spego');
|
|
49
|
+
}
|
|
50
|
+
return path.join(env.XDG_CONFIG_HOME ?? path.join(home, '.config'), 'spego');
|
|
51
|
+
}
|
|
52
|
+
export function storeRunsPath(storeRoot) {
|
|
53
|
+
return path.join(storeRoot, STORE_RUNS_FILE_NAME);
|
|
54
|
+
}
|
|
30
55
|
export function artifactFilePath(paths, type, slug) {
|
|
31
56
|
return path.join(paths.artifactsRoot, type, `${slug}.md`);
|
|
32
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/workspace/paths.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/workspace/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Agent targets and generated files
|
|
2
|
+
|
|
3
|
+
`spego init` generates agent-facing files for every target listed under `agents` in `.spego/config.yaml`. Run `spego skills` to regenerate them without reinitializing the workspace.
|
|
4
|
+
|
|
5
|
+
## Claude
|
|
6
|
+
|
|
7
|
+
- `.claude/skills/spego-<command>/SKILL.md` — skill definitions following Claude Code conventions
|
|
8
|
+
- `.claude/commands/spego/` — slash command wrappers
|
|
9
|
+
|
|
10
|
+
Workflow skills land at `.claude/skills/spego-<workflow>/SKILL.md`; the agent picks them up from the skill description.
|
|
11
|
+
|
|
12
|
+
## OpenCode
|
|
13
|
+
|
|
14
|
+
- `.opencode/commands/spego-apply.md` — implements pending tasks from an OpenSpec change in the active OpenCode instance
|
|
15
|
+
- `.opencode/commands/spego-verify.md` — checks completeness, correctness, coherence, and tests before archive
|
|
16
|
+
- `.opencode/commands/spego-explore.md` — a read-only exploration stance for ideas, problems, or OpenSpec changes
|
|
17
|
+
|
|
18
|
+
`/spego-apply` runs as a phased current-session workflow: select the change, load context, plan tasks, execute work, verify results, update task checkboxes, summarize status. It may use OpenCode-native subagents only inside the active OpenCode instance, for independent investigation, implementation review, or verification.
|
|
19
|
+
|
|
20
|
+
### Scope
|
|
21
|
+
|
|
22
|
+
spego does not start or control OpenCode through `opencode serve`, does not call the OpenCode REST API, does not create external OpenCode sessions, and does not own model selection. Configure models, variants, agents, and permissions in OpenCode itself.
|
|
23
|
+
|
|
24
|
+
There are no `spego apply`, `spego verify`, `spego explore`, or `spego orchestrate` CLI commands. Apply, verify, and explore are generated OpenCode workflows; spego remains the local artifact engine and read-only OpenSpec delivery view.
|
|
25
|
+
|
|
26
|
+
## Regeneration and stale files
|
|
27
|
+
|
|
28
|
+
During regeneration spego removes stale generated OpenCode compatibility files — old `opsx-*` commands, `openspec-*` skills, retired orchestration assets — only when they carry the `spego_generated: true` marker. User-owned files without that marker are preserved and reported as skipped.
|
|
29
|
+
|
|
30
|
+
## Related
|
|
31
|
+
|
|
32
|
+
- [Workflows](workflows.md) — what the generated workflow skills do
|
package/docs/cli.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# CLI reference
|
|
2
|
+
|
|
3
|
+
Every command accepts `--cwd <dir>` to set the project root, and the global `--json` flag to switch output modes.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
| Command | Description |
|
|
8
|
+
|---------|-------------|
|
|
9
|
+
| `spego init` | Initialize a `.spego/` workspace |
|
|
10
|
+
| `spego status` | Report workspace status |
|
|
11
|
+
| `spego create --type prd --title "My PRD"` | Create an artifact |
|
|
12
|
+
| `spego read --id <uuid>` | Read by id, type+slug, or path |
|
|
13
|
+
| `spego update --id <uuid> --body "new content"` | Update with revision control |
|
|
14
|
+
| `spego delete --id <uuid>` | Soft-delete, preserving history |
|
|
15
|
+
| `spego list` | List artifacts |
|
|
16
|
+
| `spego view` | Overview of artifacts as a table; `--detail` exports the full markdown bundle, `--json` exports full JSON |
|
|
17
|
+
| `spego commands` | List command metadata |
|
|
18
|
+
| `spego workflows` | List workflow skill metadata |
|
|
19
|
+
| `spego skills` | Regenerate agent skill files |
|
|
20
|
+
| `spego epics [name]` | List delivery epics, or get one by change name |
|
|
21
|
+
| `spego tasks <change> [task]` | List tasks for a change, or get one task |
|
|
22
|
+
| `spego sprints` | List sprint plans in board order |
|
|
23
|
+
| `spego board` | Show the delivery board — sprints, change signals, drift; `--sync` reconciles first |
|
|
24
|
+
| `spego sync` | Reconcile the delivery mirror: create missing epics, close finished sprints, retire epics of archived changes |
|
|
25
|
+
| `spego record <change>` | Record one measured run (`--flow`, `--hours`) against a change's epic `actuals`; appends, never overwrites |
|
|
26
|
+
| `spego index rebuild` | Rebuild the SQLite index from files |
|
|
27
|
+
|
|
28
|
+
## Output modes
|
|
29
|
+
|
|
30
|
+
Every command speaks two modes.
|
|
31
|
+
|
|
32
|
+
**Human (default)** — scannable terminal output. Each command renders a section: a single emoji header (`📦 📄 🛠️ 🧭 📚 ✅ ✨ 🗑 📋 🏃 🕸️ 🧩`), a blank line, then content. Summaries render as bordered boxes (`╭─ … ─╮`), lists as aligned tables. Errors print as `⚠️ [CODE] message` on stderr.
|
|
33
|
+
|
|
34
|
+
**JSON (opt-in)** — pass `--json` for deterministic, decoration-free JSON on stdout. Errors come back on stderr as `{ "error": { "code", "message", "details" } }`, where `details` is always an object.
|
|
35
|
+
|
|
36
|
+
Agents calling spego MUST pass `--json`. Humans normally do not.
|
|
37
|
+
|
|
38
|
+
`view` defaults to an overview — a totals box plus one table per artifact type, with `epic` rows carrying delivery-derived status. `view --detail` renders the full markdown bundle instead, separating artifacts with `────` dividers.
|
|
39
|
+
|
|
40
|
+
## Artifact payloads
|
|
41
|
+
|
|
42
|
+
`read --json` and `update --json` both return artifact records with `frontmatter`, `body`, and `path`; `update` also keeps the compatibility fields `id` and `revision`.
|
|
43
|
+
|
|
44
|
+
`create` and `update` accept body content through `--body`, `--body-file <path>`, or stdin via `--body-file -`.
|
|
45
|
+
|
|
46
|
+
## Related
|
|
47
|
+
|
|
48
|
+
- [Delivery board](delivery-board.md) — what `board`, `sync`, and `epics` derive
|
|
49
|
+
- [Estimation](estimation.md) — what `record` feeds and how prices resolve
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Delivery board
|
|
2
|
+
|
|
3
|
+
`spego board` derives the delivery mirror on demand. It never writes artifacts or OpenSpec state.
|
|
4
|
+
|
|
5
|
+
The board combines active and archived OpenSpec changes with `epic` and `sprint-plan` artifacts into a sprint board: sprints in date order (undated last), each sprint's changes in dependency order, then per-change status, blockers, gaps, and missing artifacts (`requires` minus resolvable `links`).
|
|
6
|
+
|
|
7
|
+
A change is blocked when a dependency is not `done` or `completed` and is not scheduled in the same or an earlier sprint. Archived changes are discovered from `openspec/changes/archive/<date>-<slug>/`, with the date prefix stripped to derive the slug, and always resolve to `completed` — so a dependency that resolved through the archive no longer trips `dangling-dep`.
|
|
8
|
+
|
|
9
|
+
## Status
|
|
10
|
+
|
|
11
|
+
A change's status is one of `backlog`, `in-progress`, `done`, `completed`, `blocked`, `paused`, or `unknown`.
|
|
12
|
+
|
|
13
|
+
`done` and `completed` both satisfy a dependent's blocker check but mean different things: `done` is all tasks checked and not yet archived; `completed` is archived — a filesystem fact that always wins, even over a manual override. Human output (`board`, `epics`, and `view`'s epic rows) prints `completed` as `archived`, since that is the fact that explains why the change is finished. `--json` keeps `completed` unchanged, so agents see no contract change.
|
|
14
|
+
|
|
15
|
+
`blocked` and `paused` have no signal in OpenSpec's plain-text files, so they are set by hand on the `epic` artifact's `status` meta. That override applies only to a change with a real backing OpenSpec change, never forces `done`/`completed`/`in-progress`/`backlog`, and is dropped once the change is archived. An orphan epic — no backing change at all — has no other source of truth, so its `status` meta accepts any of the seven values.
|
|
16
|
+
|
|
17
|
+
## Identity and conflict tracks
|
|
18
|
+
|
|
19
|
+
Every change carries a stable `id`: `c` plus a 4+ hex-char slice of the slug's sha1 hash (`c4f2a`), longer only for the rare slug that collides with another on the same board. The id depends only on the slug, so adding, removing, or archiving other changes never shifts an existing id. Blockers are reported by `id`, not slug.
|
|
20
|
+
|
|
21
|
+
`group` names the change's conflict track — the epic's `track` meta, set during grooming from file and subsystem overlap. Two changes sharing a track are expected to conflict and must run sequentially; changes in different tracks are parallel-safe. A pending change whose epic has no track shows `?` — grooming debt to clear with `spego groom`. A `done` or `completed` change shows `—`. Unlike `id`, `group` is a live value expected to shift as tracks are assigned and work completes.
|
|
22
|
+
|
|
23
|
+
## Modes and filters
|
|
24
|
+
|
|
25
|
+
The default output is the human board.
|
|
26
|
+
|
|
27
|
+
- `--graph` shows dependency edges.
|
|
28
|
+
- `--gaps` focuses on gap flags and missing artifacts.
|
|
29
|
+
- `--sync` applies the mechanical reconciliation plan before rendering.
|
|
30
|
+
- `--archived` restores archived changes to the `Ungrouped` list, which excludes them by default. They still resolve dependencies and blockers either way, and a sprint's own change list is never filtered — an archived change still scheduled in a sprint keeps showing there, struck through as satisfied.
|
|
31
|
+
- `--closed` renders a sprint whose changes are all `done`/`completed`, which is otherwise hidden behind a trailing `N closed sprints hidden (--closed to show).` note and rendered muted when shown. This is purely a display filter: `--json` always lists every sprint, and hiding never writes `status: closed` to the sprint-plan artifact — that persistence belongs to the groom workflow, after your confirmation.
|
|
32
|
+
|
|
33
|
+
`--graph` and `--gaps` also carry the `id` column. The global `--json` flag emits a deterministic `{ sprints, ungrouped, warnings, next }` document in all modes; `next` names the first pending, unblocked change, or is `null` with a hint to groom.
|
|
34
|
+
|
|
35
|
+
## Rendering
|
|
36
|
+
|
|
37
|
+
Each sprint — and the `Ungrouped` list and the trailing `Warnings` table — renders as a bordered panel: a left rail closed on the right with `│`, corners `╮`/`╯`, and its title embedded in the top rail as `<title> · <status> · <slug>`, bolded.
|
|
38
|
+
|
|
39
|
+
Every panel on a board renders at the same width: whichever is wider between the shared table grid and the longest panel title, capped at the terminal width. A title too long for that width truncates with `…` rather than widening its panel past its siblings.
|
|
40
|
+
|
|
41
|
+
The default change table carries `id`, `change`, `status`, `group`, and `signals` — plus `hours` between `group` and `signals` when the workspace declares a `flows` block — on one shared grid across every panel. Columns shrink together, widest first, to fit the terminal width, or 120 columns when not a TTY. The `change` column is protected: it never truncates, so every slug shows in full no matter how narrow the terminal gets, and the other columns absorb the deficit.
|
|
42
|
+
|
|
43
|
+
The `signals` column summarizes drift as nonzero counts joined by `·` — `N blk` (blockers), `N gap` (gap flags), `N mis` (missing artifacts) — or `—` when the change is clean. The full text lives in `spego board --gaps`.
|
|
44
|
+
|
|
45
|
+
The footer adds a dim `spego board --gaps` hint when any rendered change carries a signal, and a dim `N mechanical fixes — run spego sync` line when the reconciliation plan is non-empty.
|
|
46
|
+
|
|
47
|
+
## Drift warnings
|
|
48
|
+
|
|
49
|
+
Every rendering attaches drift warnings: `dangling-dep`, `dep-cycle`, `out-of-order-dep`, `ungroomed-change`, `orphan-epic`, `closable-sprint`, and `stale-profile`. `out-of-order-dep` flags a scheduled change blocked by a dependency scheduled into a later sprint.
|
|
50
|
+
|
|
51
|
+
The mechanical subset is repaired by `spego sync`:
|
|
52
|
+
|
|
53
|
+
- `ungroomed-change` — create the epic
|
|
54
|
+
- `closable-sprint` — close the sprint
|
|
55
|
+
- `orphan-epic` whose change is archived — retire the epic
|
|
56
|
+
|
|
57
|
+
The judgment-only warnings — `orphan-epic` whose change is missing, `dangling-dep`, `dep-cycle`, `out-of-order-dep`, and [`stale-profile`](estimation.md#bias) — belong to the groom workflow. The board only reports; pass `--sync` to apply the mechanical plan and re-render in one step.
|
|
58
|
+
|
|
59
|
+
## Related
|
|
60
|
+
|
|
61
|
+
- [Estimation](estimation.md) — the `hours` column and sprint totals
|
|
62
|
+
- [OpenSpec adapter](openspec-adapter.md) — where change state comes from
|
|
63
|
+
- [Workflows](workflows.md#groom) — the groom workflow that clears judgment debt
|