@owlmeans/viable-common 0.0.18 → 0.0.20
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 +3 -3
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/agent-presentation/SKILL.md +2 -0
- package/agent-meta/skills/viable-common/SKILL.md +195 -10
- package/build/ba/consts.d.ts +2 -3
- package/build/ba/consts.d.ts.map +1 -1
- package/build/ba/consts.js +2 -3
- package/build/ba/consts.js.map +1 -1
- package/build/ba/helpers.d.ts +2 -1
- package/build/ba/helpers.d.ts.map +1 -1
- package/build/ba/helpers.js +3 -2
- package/build/ba/helpers.js.map +1 -1
- package/build/ba/types.d.ts +17 -2
- package/build/ba/types.d.ts.map +1 -1
- package/build/blueprint/case.js +3 -3
- package/build/connect/consts.d.ts +5 -8
- package/build/connect/consts.d.ts.map +1 -1
- package/build/connect/consts.js +5 -8
- package/build/connect/consts.js.map +1 -1
- package/build/connect/entrypoints.d.ts +1 -43
- package/build/connect/entrypoints.d.ts.map +1 -1
- package/build/connect/entrypoints.js +1 -18
- package/build/connect/entrypoints.js.map +1 -1
- package/build/connect/index.d.ts +1 -0
- package/build/connect/index.d.ts.map +1 -1
- package/build/connect/index.js +1 -0
- package/build/connect/index.js.map +1 -1
- package/build/connect/jobs.d.ts +25 -0
- package/build/connect/jobs.d.ts.map +1 -0
- package/build/connect/jobs.js +29 -0
- package/build/connect/jobs.js.map +1 -0
- package/build/connect/references.d.ts +1 -40
- package/build/connect/references.d.ts.map +1 -1
- package/build/connect/references.js +0 -8
- package/build/connect/references.js.map +1 -1
- package/build/connect/schemas.d.ts +1 -7
- package/build/connect/schemas.d.ts.map +1 -1
- package/build/connect/schemas.js +1 -25
- package/build/connect/schemas.js.map +1 -1
- package/build/connect/types.d.ts +30 -45
- package/build/connect/types.d.ts.map +1 -1
- package/build/design/consts.d.ts +0 -2
- package/build/design/consts.d.ts.map +1 -1
- package/build/design/consts.js +0 -2
- package/build/design/consts.js.map +1 -1
- package/build/design/helpers.d.ts +6 -2
- package/build/design/helpers.d.ts.map +1 -1
- package/build/design/helpers.js +6 -2
- package/build/design/helpers.js.map +1 -1
- package/build/design/types.d.ts +12 -11
- package/build/design/types.d.ts.map +1 -1
- package/build/execution/types.d.ts +11 -0
- package/build/execution/types.d.ts.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/planning/consts.d.ts +141 -0
- package/build/planning/consts.d.ts.map +1 -0
- package/build/planning/consts.js +170 -0
- package/build/planning/consts.js.map +1 -0
- package/build/planning/errors.d.ts +64 -0
- package/build/planning/errors.d.ts.map +1 -0
- package/build/planning/errors.js +99 -0
- package/build/planning/errors.js.map +1 -0
- package/build/planning/flows.d.ts +34 -0
- package/build/planning/flows.d.ts.map +1 -0
- package/build/planning/flows.js +174 -0
- package/build/planning/flows.js.map +1 -0
- package/build/planning/helpers.d.ts +54 -0
- package/build/planning/helpers.d.ts.map +1 -0
- package/build/planning/helpers.js +101 -0
- package/build/planning/helpers.js.map +1 -0
- package/build/planning/index.d.ts +7 -0
- package/build/planning/index.d.ts.map +1 -0
- package/build/planning/index.js +6 -0
- package/build/planning/index.js.map +1 -0
- package/build/planning/schemas.d.ts +23 -0
- package/build/planning/schemas.d.ts.map +1 -0
- package/build/planning/schemas.js +65 -0
- package/build/planning/schemas.js.map +1 -0
- package/build/planning/types.d.ts +70 -0
- package/build/planning/types.d.ts.map +1 -0
- package/build/planning/types.js +2 -0
- package/build/planning/types.js.map +1 -0
- package/build/scaffold/schemas.d.ts.map +1 -1
- package/build/scaffold/schemas.js +7 -2
- package/build/scaffold/schemas.js.map +1 -1
- package/build/scaffold/types.d.ts +5 -1
- package/build/scaffold/types.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/ba/consts.ts +2 -3
- package/src/ba/helpers.ts +3 -2
- package/src/ba/types.ts +17 -2
- package/src/blueprint/case.ts +3 -3
- package/src/connect/consts.ts +5 -8
- package/src/connect/entrypoints.ts +2 -41
- package/src/connect/index.ts +1 -0
- package/src/connect/jobs.ts +40 -0
- package/src/connect/references.ts +1 -22
- package/src/connect/schemas.ts +2 -29
- package/src/connect/types.ts +30 -51
- package/src/design/consts.ts +0 -3
- package/src/design/helpers.ts +6 -2
- package/src/design/types.ts +12 -11
- package/src/execution/types.ts +11 -0
- package/src/index.ts +1 -0
- package/src/planning/consts.ts +182 -0
- package/src/planning/errors.ts +117 -0
- package/src/planning/flows.ts +204 -0
- package/src/planning/helpers.ts +133 -0
- package/src/planning/index.ts +6 -0
- package/src/planning/schemas.ts +70 -0
- package/src/planning/types.ts +75 -0
- package/src/scaffold/schemas.ts +7 -2
- package/src/scaffold/types.ts +10 -1
- package/tests/branding.spec.ts +37 -0
- package/tests/connect-entrypoints.spec.ts +35 -3
- package/tests/design.spec.ts +3 -3
- package/tests/planning.spec.ts +356 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ConnectJobKind } from './consts.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The separator a job id is joined with.
|
|
5
|
+
*
|
|
6
|
+
* `~`, because every other separator in play is already spoken for: a route alias is
|
|
7
|
+
* colon-delimited and so is every run id (`init:<projectId>`, `story:<storyId>`), so a job id
|
|
8
|
+
* built with one could not be split back apart.
|
|
9
|
+
*/
|
|
10
|
+
export const JOB_SEPARATOR = '~'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A job's id: its kind, the project card it belongs to, and the subject it is about.
|
|
14
|
+
*
|
|
15
|
+
* The suffix is a CARD id for a story job and a run id for a pipeline job — never a story code.
|
|
16
|
+
* Declared here rather than by whoever answers the job, because the SDK composes the id it then
|
|
17
|
+
* polls for: two spellings of one id is a job nobody can find.
|
|
18
|
+
*/
|
|
19
|
+
export const jobIdOf = (kind: ConnectJobKind, projectId: string, suffix?: string): string =>
|
|
20
|
+
[kind, projectId, ...(suffix != null ? [suffix] : [])].join(JOB_SEPARATOR)
|
|
21
|
+
|
|
22
|
+
export interface ParsedJobId {
|
|
23
|
+
kind: ConnectJobKind
|
|
24
|
+
projectId: string
|
|
25
|
+
suffix?: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Split a job id back into what {@link jobIdOf} composed it from. */
|
|
29
|
+
export const parseJobId = (jobId: string): ParsedJobId => {
|
|
30
|
+
const [kind, projectId, ...rest] = jobId.split(JOB_SEPARATOR)
|
|
31
|
+
// A suffix may carry the separator back if one ever ends up in a card or run id, so the tail is
|
|
32
|
+
// rejoined rather than taken as its first segment.
|
|
33
|
+
const suffix = rest.length > 0 ? rest.join(JOB_SEPARATOR) : undefined
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
kind: kind as ConnectJobKind,
|
|
37
|
+
projectId: projectId ?? '',
|
|
38
|
+
...(suffix != null ? { suffix } : {}),
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -10,8 +10,7 @@ import type {
|
|
|
10
10
|
ConnectModifyBody, ConnectOpSubmission, ConnectPipelineParams, ConnectPipelineResumeBody,
|
|
11
11
|
ConnectPipelineState, ConnectProjectLlmBody, ConnectProjectSettings, ConnectProjectStatus,
|
|
12
12
|
ConnectProjectSummary, ConnectSessionOpen, ConnectSessionParams, ConnectSessionView,
|
|
13
|
-
|
|
14
|
-
ConnectStoryQuery, ConnectWaitQuery, ConversionStatusView, ConvertCheck,
|
|
13
|
+
ConnectWaitQuery, ConversionStatusView, ConvertCheck,
|
|
15
14
|
} from './types.js'
|
|
16
15
|
|
|
17
16
|
type ConnectReference<Request extends RequestShape, Response> =
|
|
@@ -47,16 +46,6 @@ export interface ConnectReferences {
|
|
|
47
46
|
}, ConnectProjectSettings>
|
|
48
47
|
job: ConnectReference<{ params: ConnectJobParams, query: ConnectWaitQuery }, ConnectJob>
|
|
49
48
|
}
|
|
50
|
-
story: {
|
|
51
|
-
list: ConnectReference<{ params: { id: string }, query: ConnectStoryQuery }, ConnectStoryList>
|
|
52
|
-
get: ConnectReference<{ params: { id: string, storyId: string } }, ConnectStoryItem>
|
|
53
|
-
create: ConnectReference<{ params: { id: string }, body: ConnectStoryBody }, ConnectStoryMutation>
|
|
54
|
-
update: ConnectReference<{
|
|
55
|
-
params: { id: string, storyId: string }, body: ConnectStoryBody
|
|
56
|
-
}, ConnectStoryMutation>
|
|
57
|
-
delete: ConnectReference<{ params: { id: string, storyId: string } }, ConnectStoryDeletion>
|
|
58
|
-
develop: ConnectReference<{ params: { id: string, storyId: string } }, ConnectJob>
|
|
59
|
-
}
|
|
60
49
|
files: {
|
|
61
50
|
list: ConnectReference<{ params: { id: string } }, string[]>
|
|
62
51
|
}
|
|
@@ -139,16 +128,6 @@ export const connectRef: ConnectReferences = {
|
|
|
139
128
|
params: { id: string, inquiryId: string }, body: ConnectInquiryAnswerBody
|
|
140
129
|
}, unknown>(connect.inquiry.answer),
|
|
141
130
|
},
|
|
142
|
-
story: {
|
|
143
|
-
list: entrypointRef<{ params: { id: string }, query: ConnectStoryQuery }, ConnectStoryList>(connect.story.list),
|
|
144
|
-
get: entrypointRef<{ params: { id: string, storyId: string } }, ConnectStoryItem>(connect.story.get),
|
|
145
|
-
create: entrypointRef<{ params: { id: string }, body: ConnectStoryBody }, ConnectStoryMutation>(connect.story.create),
|
|
146
|
-
update: entrypointRef<{
|
|
147
|
-
params: { id: string, storyId: string }, body: ConnectStoryBody
|
|
148
|
-
}, ConnectStoryMutation>(connect.story.update),
|
|
149
|
-
delete: entrypointRef<{ params: { id: string, storyId: string } }, ConnectStoryDeletion>(connect.story.delete),
|
|
150
|
-
develop: entrypointRef<{ params: { id: string, storyId: string } }, ConnectJob>(connect.story.develop),
|
|
151
|
-
},
|
|
152
131
|
files: {
|
|
153
132
|
list: entrypointRef<{ params: { id: string } }, string[]>(connect.files.list),
|
|
154
133
|
},
|
package/src/connect/schemas.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
ConnectAttachBody, ConnectConfirmBody, ConnectConvertCreateBody, ConnectConvertProceedBody,
|
|
10
10
|
ConnectCreateBody, ConnectJobParams, ConnectLlmBody, ConnectModifyBody, ConnectPipelineParams,
|
|
11
11
|
ConnectPipelineResumeBody, ConnectProjectLlmBody, ConnectSession, ConnectSessionOpen,
|
|
12
|
-
ConnectSessionParams,
|
|
12
|
+
ConnectSessionParams, ConnectWaitQuery
|
|
13
13
|
} from './types.js'
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -26,7 +26,6 @@ import type {
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
const idValue = { type: 'string', minLength: 1, maxLength: 128 } as const
|
|
29
|
-
const textValue = { type: 'string', minLength: 1, maxLength: 65536 } as const
|
|
30
29
|
|
|
31
30
|
export const ConnectCapabilitiesSchema = {
|
|
32
31
|
type: 'object',
|
|
@@ -156,13 +155,6 @@ export const ConnectProjectIdSchema = {
|
|
|
156
155
|
additionalProperties: false,
|
|
157
156
|
} as JSONSchemaType<{ id: string }>
|
|
158
157
|
|
|
159
|
-
export const ConnectStoryParamsSchema = {
|
|
160
|
-
type: 'object',
|
|
161
|
-
properties: { id: idValue, storyId: idValue },
|
|
162
|
-
required: ['id', 'storyId'],
|
|
163
|
-
additionalProperties: false,
|
|
164
|
-
} as JSONSchemaType<{ id: string, storyId: string }>
|
|
165
|
-
|
|
166
158
|
export const ConnectOpParamsSchema = {
|
|
167
159
|
type: 'object',
|
|
168
160
|
properties: { sessionId: idValue, opId: idValue },
|
|
@@ -177,19 +169,6 @@ export const ConnectJobParamsSchema = {
|
|
|
177
169
|
additionalProperties: false,
|
|
178
170
|
} as JSONSchemaType<ConnectJobParams>
|
|
179
171
|
|
|
180
|
-
export const ConnectStoryQuerySchema = {
|
|
181
|
-
type: 'object',
|
|
182
|
-
properties: {
|
|
183
|
-
page: { type: 'integer', minimum: 0, nullable: true },
|
|
184
|
-
size: { type: 'integer', minimum: 1, maximum: 100, nullable: true },
|
|
185
|
-
status: { type: 'string', maxLength: 32, nullable: true },
|
|
186
|
-
area: { type: 'string', maxLength: 32, nullable: true },
|
|
187
|
-
q: { type: 'string', maxLength: 256, nullable: true },
|
|
188
|
-
},
|
|
189
|
-
required: [],
|
|
190
|
-
additionalProperties: false,
|
|
191
|
-
} as JSONSchemaType<ConnectStoryQuery>
|
|
192
|
-
|
|
193
172
|
export const ConnectCreateBodySchema = {
|
|
194
173
|
type: 'object',
|
|
195
174
|
properties: {
|
|
@@ -207,6 +186,7 @@ export const ConnectConfirmBodySchema = {
|
|
|
207
186
|
description: { type: 'string', maxLength: 16384, nullable: true },
|
|
208
187
|
specification: { type: 'string', maxLength: 262144, nullable: true },
|
|
209
188
|
vision: { type: 'string', maxLength: 16384, nullable: true },
|
|
189
|
+
designSystem: { type: 'string', maxLength: 262144, nullable: true },
|
|
210
190
|
target: { type: 'string', enum: [...Object.values(ConnectTarget), null], nullable: true },
|
|
211
191
|
},
|
|
212
192
|
required: [],
|
|
@@ -220,13 +200,6 @@ export const ConnectModifyBodySchema = {
|
|
|
220
200
|
additionalProperties: false,
|
|
221
201
|
} as JSONSchemaType<ConnectModifyBody>
|
|
222
202
|
|
|
223
|
-
export const ConnectStoryBodySchema = {
|
|
224
|
-
type: 'object',
|
|
225
|
-
properties: { story: textValue },
|
|
226
|
-
required: ['story'],
|
|
227
|
-
additionalProperties: false,
|
|
228
|
-
} as JSONSchemaType<ConnectStoryBody>
|
|
229
|
-
|
|
230
203
|
export const ConnectAttachBodySchema = {
|
|
231
204
|
type: 'object',
|
|
232
205
|
properties: {
|
package/src/connect/types.ts
CHANGED
|
@@ -86,15 +86,24 @@ export interface ConnectSessionView {
|
|
|
86
86
|
* A derived view of "what the platform is doing for this project right now".
|
|
87
87
|
*
|
|
88
88
|
* Never stored. It is composed per request from the project lock, the slot record, the story
|
|
89
|
-
*
|
|
89
|
+
* card, the latest pipeline run row and the operations queued for the project — the same facts
|
|
90
90
|
* the manager UI reads, arranged for a caller that has one question ("may I stop waiting?") and
|
|
91
91
|
* one follow-up ("what do I call next?").
|
|
92
|
+
*
|
|
93
|
+
* Its `id` is composed and parsed only through `jobIdOf` / `parseJobId`.
|
|
92
94
|
*/
|
|
93
95
|
export interface ConnectJob {
|
|
94
96
|
id: string
|
|
95
97
|
kind: ConnectJobKind
|
|
96
98
|
status: ConnectJobStatus
|
|
99
|
+
/** The project CARD id. */
|
|
97
100
|
projectId: string
|
|
101
|
+
/**
|
|
102
|
+
* The story CARD id — never the story's code.
|
|
103
|
+
*
|
|
104
|
+
* The name is kept because a parent agent reads it: a wire field name is that agent's
|
|
105
|
+
* vocabulary and is never renamed, only re-documented.
|
|
106
|
+
*/
|
|
98
107
|
storyId?: string
|
|
99
108
|
runId?: string
|
|
100
109
|
/** The pipeline step in flight, when a run row says. */
|
|
@@ -137,43 +146,27 @@ export interface ConnectWaitQuery {
|
|
|
137
146
|
wait?: number
|
|
138
147
|
}
|
|
139
148
|
|
|
140
|
-
/** Paging and filtering for the story list a connector reads. */
|
|
141
|
-
export interface ConnectStoryQuery {
|
|
142
|
-
page?: number
|
|
143
|
-
size?: number
|
|
144
|
-
status?: string
|
|
145
|
-
area?: string
|
|
146
|
-
/** Free-text match against the story narrative and its code. */
|
|
147
|
-
q?: string
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export interface ConnectStoryList {
|
|
151
|
-
items: ConnectStoryItem[]
|
|
152
|
-
page: number
|
|
153
|
-
size: number
|
|
154
|
-
total: number
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export interface ConnectStoryItem {
|
|
158
|
-
id: string
|
|
159
|
-
code?: string
|
|
160
|
-
story: string
|
|
161
|
-
area?: string
|
|
162
|
-
status: string
|
|
163
|
-
primary: boolean
|
|
164
|
-
warning?: string
|
|
165
|
-
createdAt: string
|
|
166
|
-
}
|
|
167
|
-
|
|
168
149
|
/** What a connector needs to know about a project in one call. */
|
|
169
150
|
export interface ConnectProjectStatus {
|
|
151
|
+
/**
|
|
152
|
+
* The project card, flattened into the names a parent agent already reads.
|
|
153
|
+
*
|
|
154
|
+
* `name` is the card's `title` and `alias` its `code`; the three brief parts are the bodies of
|
|
155
|
+
* the project's `specification`, `vision` and `design-system` specifications. `status` and
|
|
156
|
+
* `intrinsic` are the card's own — a key of the project flow and the intrinsic state it maps to —
|
|
157
|
+
* typed as plain strings because this view crosses a version skew and a newer platform may
|
|
158
|
+
* answer with a status an older connector has never heard of.
|
|
159
|
+
*/
|
|
170
160
|
project: {
|
|
171
161
|
id: string
|
|
172
162
|
name: string
|
|
173
163
|
alias: string
|
|
174
164
|
description?: string
|
|
165
|
+
status: string
|
|
166
|
+
intrinsic: string
|
|
175
167
|
specification?: string
|
|
176
168
|
vision?: string
|
|
169
|
+
designSystem?: string
|
|
177
170
|
}
|
|
178
171
|
slot?: {
|
|
179
172
|
id: string
|
|
@@ -297,12 +290,19 @@ export interface ConnectCreateBody {
|
|
|
297
290
|
target?: ConnectTarget
|
|
298
291
|
}
|
|
299
292
|
|
|
300
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* Confirm a drafted project, optionally editing what the analysis produced.
|
|
295
|
+
*
|
|
296
|
+
* The keys are a parent agent's vocabulary and stay as they are: `name` becomes the card's
|
|
297
|
+
* `title`, and each brief part present is written into the project's specification of that
|
|
298
|
+
* category before the confirm transition runs.
|
|
299
|
+
*/
|
|
301
300
|
export interface ConnectConfirmBody {
|
|
302
301
|
name?: string
|
|
303
302
|
description?: string
|
|
304
303
|
specification?: string
|
|
305
304
|
vision?: string
|
|
305
|
+
designSystem?: string
|
|
306
306
|
target?: ConnectTarget
|
|
307
307
|
}
|
|
308
308
|
|
|
@@ -310,10 +310,6 @@ export interface ConnectModifyBody {
|
|
|
310
310
|
prompt: string
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
export interface ConnectStoryBody {
|
|
314
|
-
story: string
|
|
315
|
-
}
|
|
316
|
-
|
|
317
313
|
export interface ConnectPipelineParams {
|
|
318
314
|
id: string
|
|
319
315
|
runId: string
|
|
@@ -419,23 +415,6 @@ export interface ConnectProjectSummary {
|
|
|
419
415
|
alias: string
|
|
420
416
|
}
|
|
421
417
|
|
|
422
|
-
/** A story item returned after creating, editing or fetching one story. */
|
|
423
|
-
export interface ConnectStoryMutation {
|
|
424
|
-
id: string
|
|
425
|
-
code?: string
|
|
426
|
-
story: string
|
|
427
|
-
area?: string
|
|
428
|
-
status: string
|
|
429
|
-
primary: boolean
|
|
430
|
-
warning?: string
|
|
431
|
-
createdAt: string
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/** The success answer for deleting a story. */
|
|
435
|
-
export interface ConnectStoryDeletion {
|
|
436
|
-
deleted: boolean
|
|
437
|
-
}
|
|
438
|
-
|
|
439
418
|
/** The persistent state of one pipeline run, read by a connector without platform internals. */
|
|
440
419
|
export interface ConnectPipelineState {
|
|
441
420
|
runId: string
|
package/src/design/consts.ts
CHANGED
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export const STORY_DESIGN_VERSION = 1
|
|
10
10
|
|
|
11
|
-
/** The code a scaffold plan is filed under, since it belongs to a project rather than a story. */
|
|
12
|
-
export const SCAFFOLD_CODE = 'scaffold'
|
|
13
|
-
|
|
14
11
|
/** How far a design may drift from the project it was written against before it is stale. */
|
|
15
12
|
export enum DesignStaleness {
|
|
16
13
|
/** Usable as it stands. */
|
package/src/design/helpers.ts
CHANGED
|
@@ -4,15 +4,19 @@ import { DesignStaleness, STORY_DESIGN_VERSION } from './consts.js'
|
|
|
4
4
|
import type { StoryDesign } from './types.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* The in-memory aggregate the coders take, derived from the design.
|
|
7
|
+
* The in-memory aggregate the coders take, derived from the design ALONE.
|
|
8
8
|
*
|
|
9
9
|
* Derived rather than stored, and derived HERE rather than at the platform: the aggregate is what
|
|
10
10
|
* every generation helper reads, and a second place that assembles it is a second place that can
|
|
11
11
|
* assemble it differently. The `code` in particular is load-bearing - the scaffold stamps every
|
|
12
12
|
* placeholder it draws with it, so a run keyed by anything else cannot recognise its own
|
|
13
13
|
* reservation.
|
|
14
|
+
*
|
|
15
|
+
* For a context with no card behind it. Where a story card exists, `userStoryOf(card, design)` is
|
|
16
|
+
* the reader: the card wins on the narrative, code, area and actor, which a person may have
|
|
17
|
+
* changed since the design was written.
|
|
14
18
|
*/
|
|
15
|
-
export const
|
|
19
|
+
export const userStoryOfDesign = (design: StoryDesign): UserStory => {
|
|
16
20
|
const componentOf = (name: string): StoryComponent | null => {
|
|
17
21
|
const component = design.components.find(entry => entry.name === name)
|
|
18
22
|
if (component == null) {
|
package/src/design/types.ts
CHANGED
|
@@ -168,24 +168,25 @@ export interface StoryDesign {
|
|
|
168
168
|
provenance: StoryDesignProvenance
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
/**
|
|
172
|
-
export interface
|
|
173
|
-
projectId: string
|
|
174
|
-
storyId?: string
|
|
175
|
-
code: string
|
|
176
|
-
kind: string
|
|
177
|
-
payload: unknown
|
|
171
|
+
/** Who wrote a design revision and why — recorded on the transition, never in the design. */
|
|
172
|
+
export interface StoryDesignPutOptions {
|
|
178
173
|
runId?: string
|
|
174
|
+
cause?: string
|
|
179
175
|
}
|
|
180
176
|
|
|
181
177
|
/**
|
|
182
178
|
* How the implementation stage reaches the design, without knowing where it lives.
|
|
183
179
|
*
|
|
184
180
|
* A port rather than a resource for the usual reason: two questions is the whole of what an
|
|
185
|
-
* implementation step needs, and a port that small is satisfiable by a
|
|
186
|
-
* test
|
|
181
|
+
* implementation step needs, and a port that small is satisfiable by a planning facade, a file,
|
|
182
|
+
* or a test. Both methods are addressed by a CARD id — the story card for a story design, the
|
|
183
|
+
* project card for a scaffold plan — and the port decides which specification slot of that card
|
|
184
|
+
* holds the payload. The code a design carries is the target's vocabulary; it never addresses a
|
|
185
|
+
* record.
|
|
187
186
|
*/
|
|
188
187
|
export interface StoryDesignPort {
|
|
189
|
-
|
|
190
|
-
|
|
188
|
+
/** The card's current design and its revision; `null` when none was written or its version differs. */
|
|
189
|
+
current: (cardId: string) => Promise<{ revision: number, design: StoryDesign } | null>
|
|
190
|
+
/** Write a design as the card's next revision and answer the revision number it received. */
|
|
191
|
+
put: (cardId: string, design: StoryDesign, opts?: StoryDesignPutOptions) => Promise<number>
|
|
191
192
|
}
|
package/src/execution/types.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { PurposeMetadata } from '../agent/types.js'
|
|
|
6
6
|
import type { AgentProject, Entity, UserStory } from '../ba/types.js'
|
|
7
7
|
import type { UXTransition } from '../ux/types.js'
|
|
8
8
|
import type { SeniorityMode } from '../consts.js'
|
|
9
|
+
import type { ViableProjectCard, ViableStoryCard } from '../planning/types.js'
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Model-selection contracts are owned by `@owlmeans/llm-common` — the JSON-safe config
|
|
@@ -26,7 +27,15 @@ export interface ExecutionState extends LlmExecutionState {
|
|
|
26
27
|
slot?: string
|
|
27
28
|
projectId?: string
|
|
28
29
|
entityId?: string
|
|
30
|
+
/** The brief the run reads — assembled from {@link ExecutionState.projectCard} and its specifications. */
|
|
29
31
|
project?: AgentProject
|
|
32
|
+
/**
|
|
33
|
+
* The project card the run acts on, as plain data.
|
|
34
|
+
*
|
|
35
|
+
* Carried beside the brief rather than in place of it: a generator reads the brief, while
|
|
36
|
+
* whatever writes back — a status transition, a specification — needs the card's id and head.
|
|
37
|
+
*/
|
|
38
|
+
projectCard?: ViableProjectCard
|
|
30
39
|
entities?: Entity[]
|
|
31
40
|
/**
|
|
32
41
|
* Which blueprint this run is building against, as an id plus an override patch.
|
|
@@ -51,5 +60,7 @@ export interface TaskExecutionState
|
|
|
51
60
|
extends ExecutionState, Omit<LlmTaskExecutionState, keyof LlmExecutionState> {
|
|
52
61
|
mode?: SeniorityMode
|
|
53
62
|
story?: UserStory
|
|
63
|
+
/** The story card the task develops, as plain data — the aggregate above is derived from it. */
|
|
64
|
+
card?: ViableStoryCard
|
|
54
65
|
transitions?: UXTransition[]
|
|
55
66
|
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { CodeScope, CodeStyle } from '@owlmeans/planning'
|
|
2
|
+
import type { CodePolicy } from '@owlmeans/planning'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The OwlMeans Viable vocabulary over `@owlmeans/planning`.
|
|
6
|
+
*
|
|
7
|
+
* A project, a user story and the documents behind them are planning WORKCARDS of the types
|
|
8
|
+
* declared here. Everything generic — the record, the transition, the fold, the store, the protocol
|
|
9
|
+
* tree — belongs to the planning packages; what a Viable project or story IS, which statuses it
|
|
10
|
+
* moves through and which documents it carries, is declared once in this module and read by every
|
|
11
|
+
* runtime that writes one.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** A Viable project — the card every story, document and platform record of a product hangs under. */
|
|
15
|
+
export const VIABLE_PROJECT_TYPE = 'viable:project'
|
|
16
|
+
/** A user story — the unit of development a person starts. */
|
|
17
|
+
export const VIABLE_STORY_TYPE = 'viable:user-story'
|
|
18
|
+
/** Every document a project or story card carries (specification, vision, design system, plans). */
|
|
19
|
+
export const VIABLE_SPEC_TYPE = 'viable:spec'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Reserved card types. Declared in full so their code prefix and flow are decided once, and
|
|
23
|
+
* deliberately absent from the project type's `cardTypes`: nothing may create one yet.
|
|
24
|
+
*/
|
|
25
|
+
export const VIABLE_BUG_TYPE = 'viable:bug'
|
|
26
|
+
export const VIABLE_IMPROVEMENT_TYPE = 'viable:improvement'
|
|
27
|
+
export const VIABLE_REQUIREMENT_TYPE = 'viable:requirement'
|
|
28
|
+
|
|
29
|
+
export const VIABLE_PROJECT_FLOW = 'viable:project'
|
|
30
|
+
export const VIABLE_STORY_FLOW = 'viable:user-story'
|
|
31
|
+
/** The one-status flow a document runs — a specification has no lifecycle of its own. */
|
|
32
|
+
export const VIABLE_SPEC_FLOW = 'viable:spec'
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The story flow's status keys.
|
|
36
|
+
*
|
|
37
|
+
* Byte-identical to the strings a story has always carried — the frontmatter of
|
|
38
|
+
* `docs/stories/<code>.md`, the connector's job status mapping, the board's columns, their i18n
|
|
39
|
+
* keys and every end-to-end selector read these exact values. A key is a wire contract and is
|
|
40
|
+
* never renamed.
|
|
41
|
+
*/
|
|
42
|
+
export enum ViableStoryStatus {
|
|
43
|
+
Planned = 'planned',
|
|
44
|
+
InProgress = 'in-progress',
|
|
45
|
+
Completed = 'completed',
|
|
46
|
+
/** Intrinsically PLANNED: a failed story is work still to do, and retrying it is `start`. */
|
|
47
|
+
Failed = 'failed',
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export enum ViableStoryTransition {
|
|
51
|
+
/** `planned | failed → in-progress` — the only move that asks for development. */
|
|
52
|
+
Start = 'start',
|
|
53
|
+
Complete = 'complete',
|
|
54
|
+
Fail = 'fail',
|
|
55
|
+
/** `* → planned` — the manual recovery, and the one move a completed story still accepts. */
|
|
56
|
+
Reset = 'reset',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export enum ViableProjectStatus {
|
|
60
|
+
/** Created from a prompt, specification drafted, nothing provisioned. */
|
|
61
|
+
Draft = 'draft',
|
|
62
|
+
/** The owner confirmed the brief; initialization is running or has run. */
|
|
63
|
+
Confirmed = 'confirmed',
|
|
64
|
+
/** Initialization finished at least once. */
|
|
65
|
+
Active = 'active',
|
|
66
|
+
Archived = 'archived',
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export enum ViableProjectTransition {
|
|
70
|
+
Confirm = 'confirm',
|
|
71
|
+
Activate = 'activate',
|
|
72
|
+
Archive = 'archive',
|
|
73
|
+
Reopen = 'reopen',
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The single status a document holds. */
|
|
77
|
+
export enum ViableSpecStatus {
|
|
78
|
+
Current = 'current',
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** The palette key a board renders a status with. Presentation data, carried on the flow. */
|
|
82
|
+
export enum ViableTone {
|
|
83
|
+
Blue = 'blue',
|
|
84
|
+
Yellow = 'yellow',
|
|
85
|
+
Green = 'green',
|
|
86
|
+
Red = 'red',
|
|
87
|
+
Neutral = 'neutral',
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The specification slots Viable cards carry.
|
|
92
|
+
*
|
|
93
|
+
* Project: `specification`, `vision`, `design-system` (the brief) and `scaffold` (the drawn plan).
|
|
94
|
+
* Story: `design`. The co-located `*.spec/.ux/.ui.md` files of a target are FILES, not slots — that
|
|
95
|
+
* prose already lives inside the `design` payload — so `SpecCategory` is not a slot vocabulary.
|
|
96
|
+
*/
|
|
97
|
+
export enum ViableSpecCategory {
|
|
98
|
+
Specification = 'specification',
|
|
99
|
+
Vision = 'vision',
|
|
100
|
+
DesignSystem = 'design-system',
|
|
101
|
+
Scaffold = 'scaffold',
|
|
102
|
+
Design = 'design',
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** How many revisions of a `design` or `scaffold` document the history must be able to answer. */
|
|
106
|
+
export const VIABLE_DESIGN_REVISIONS_KEPT = 3
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Relationship types between story cards.
|
|
110
|
+
*
|
|
111
|
+
* `follows` is WRITTEN: a connective story follows the flow story it was anchored after, created in
|
|
112
|
+
* the same transition as the card. `shares-widget` and `shares-screen` are DECLARED ONLY — the
|
|
113
|
+
* `scaffold` specification is their single authority, and a second copy as links would be a second
|
|
114
|
+
* answer that can disagree with it.
|
|
115
|
+
*/
|
|
116
|
+
export enum ViableRelationship {
|
|
117
|
+
Follows = 'follows',
|
|
118
|
+
SharesWidget = 'shares-widget',
|
|
119
|
+
SharesScreen = 'shares-screen',
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Where a write came from, carried on `PlanningScope.channel` and recorded on the transition's
|
|
124
|
+
* `actor.channel`.
|
|
125
|
+
*
|
|
126
|
+
* It is never read from the wire: the manager API derives `Connect` from an access-token request
|
|
127
|
+
* and `Web` from everything else; the agent writes as `Agent` or `Pipeline`. Three rules key on it
|
|
128
|
+
* — the balance refusal class (`ConnectOutOfCredits` for `Connect`), re-formatting a narrative
|
|
129
|
+
* (`Web`/`Connect` only), and the develop trigger (a committed `start` by `Web`/`Connect` only).
|
|
130
|
+
*/
|
|
131
|
+
export enum ViableChannel {
|
|
132
|
+
Web = 'web',
|
|
133
|
+
Connect = 'connect',
|
|
134
|
+
Agent = 'agent',
|
|
135
|
+
Pipeline = 'pipeline',
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** The channels a PERSON writes through. */
|
|
139
|
+
export const VIABLE_USER_CHANNELS: readonly string[] = Object.freeze([
|
|
140
|
+
ViableChannel.Web, ViableChannel.Connect,
|
|
141
|
+
])
|
|
142
|
+
|
|
143
|
+
export const VIABLE_STORY_CODE_PREFIX = 'US-'
|
|
144
|
+
export const VIABLE_BUG_CODE_PREFIX = 'BUG-'
|
|
145
|
+
export const VIABLE_IMPROVEMENT_CODE_PREFIX = 'IMP-'
|
|
146
|
+
export const VIABLE_REQUIREMENT_CODE_PREFIX = 'REQ-'
|
|
147
|
+
export const VIABLE_CARD_CODE_LENGTH = 5
|
|
148
|
+
|
|
149
|
+
/** `US-` + five uppercase characters, unique within the project. The code a target is keyed by. */
|
|
150
|
+
export const VIABLE_STORY_CODE: CodePolicy = Object.freeze({
|
|
151
|
+
prefix: VIABLE_STORY_CODE_PREFIX,
|
|
152
|
+
style: CodeStyle.Random,
|
|
153
|
+
length: VIABLE_CARD_CODE_LENGTH,
|
|
154
|
+
uppercase: true,
|
|
155
|
+
uniqueWithin: CodeScope.Parent,
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* A project's code is its alias — a slug unique within the organization.
|
|
160
|
+
*
|
|
161
|
+
* Minted by the platform's name ladder, which knows about retired aliases and refused hostnames;
|
|
162
|
+
* a code policy only guards uniqueness, so a create always supplies the code.
|
|
163
|
+
*/
|
|
164
|
+
export const VIABLE_PROJECT_CODE: CodePolicy = Object.freeze({
|
|
165
|
+
style: CodeStyle.Slug,
|
|
166
|
+
uniqueWithin: CodeScope.Entity,
|
|
167
|
+
// The alias moves: a rename changes it, and a refused preview certificate walks it to `alias-2`.
|
|
168
|
+
// A story code never moves — the target's files are named after it.
|
|
169
|
+
mutable: true,
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
export const VIABLE_BUG_CODE: CodePolicy = Object.freeze({
|
|
173
|
+
...VIABLE_STORY_CODE, prefix: VIABLE_BUG_CODE_PREFIX,
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
export const VIABLE_IMPROVEMENT_CODE: CodePolicy = Object.freeze({
|
|
177
|
+
...VIABLE_STORY_CODE, prefix: VIABLE_IMPROVEMENT_CODE_PREFIX,
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
export const VIABLE_REQUIREMENT_CODE: CodePolicy = Object.freeze({
|
|
181
|
+
...VIABLE_STORY_CODE, prefix: VIABLE_REQUIREMENT_CODE_PREFIX,
|
|
182
|
+
})
|