@owlmeans/viable-common 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +4 -4
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/agent-presentation/SKILL.md +1 -1
  4. package/agent-meta/skills/viable-common/SKILL.md +10 -9
  5. package/build/blueprint/case.js +3 -3
  6. package/build/connect/consts.d.ts +10 -43
  7. package/build/connect/consts.d.ts.map +1 -1
  8. package/build/connect/consts.js +13 -48
  9. package/build/connect/consts.js.map +1 -1
  10. package/build/connect/entrypoints.d.ts +22 -19
  11. package/build/connect/entrypoints.d.ts.map +1 -1
  12. package/build/connect/entrypoints.js +8 -4
  13. package/build/connect/entrypoints.js.map +1 -1
  14. package/build/connect/index.d.ts +0 -1
  15. package/build/connect/index.d.ts.map +1 -1
  16. package/build/connect/index.js +0 -1
  17. package/build/connect/index.js.map +1 -1
  18. package/build/connect/ops.d.ts +1 -4
  19. package/build/connect/ops.d.ts.map +1 -1
  20. package/build/connect/references.d.ts +20 -16
  21. package/build/connect/references.d.ts.map +1 -1
  22. package/build/connect/references.js +3 -1
  23. package/build/connect/references.js.map +1 -1
  24. package/build/connect/schemas.d.ts +6 -3
  25. package/build/connect/schemas.d.ts.map +1 -1
  26. package/build/connect/schemas.js +4 -4
  27. package/build/connect/schemas.js.map +1 -1
  28. package/build/connect/types.d.ts +36 -66
  29. package/build/connect/types.d.ts.map +1 -1
  30. package/build/design/runtime.d.ts +1 -1
  31. package/build/design/runtime.d.ts.map +1 -1
  32. package/build/planning/consts.d.ts +1 -1
  33. package/build/planning/consts.js +1 -1
  34. package/build/skills/catalogue.d.ts.map +1 -1
  35. package/build/skills/catalogue.js +22 -15
  36. package/build/skills/catalogue.js.map +1 -1
  37. package/package.json +8 -8
  38. package/src/blueprint/case.ts +3 -3
  39. package/src/connect/consts.ts +10 -45
  40. package/src/connect/entrypoints.ts +26 -20
  41. package/src/connect/index.ts +0 -1
  42. package/src/connect/ops.ts +1 -4
  43. package/src/connect/references.ts +34 -28
  44. package/src/connect/schemas.ts +8 -8
  45. package/src/connect/types.ts +38 -69
  46. package/src/design/runtime.ts +1 -1
  47. package/src/planning/consts.ts +1 -1
  48. package/src/skills/catalogue.ts +22 -15
  49. package/tests/connect-convert.spec.ts +2 -8
  50. package/tests/connect-entrypoints.spec.ts +11 -29
  51. package/build/connect/jobs.d.ts +0 -25
  52. package/build/connect/jobs.d.ts.map +0 -1
  53. package/build/connect/jobs.js +0 -29
  54. package/build/connect/jobs.js.map +0 -1
  55. package/src/connect/jobs.ts +0 -40
@@ -4,8 +4,8 @@ import type {
4
4
  OriginState, StoryEstimateBand
5
5
  } from '../convert/index.js'
6
6
  import type {
7
- ConnectExecutor, ConnectHarness, ConnectJobBlock, ConnectJobKind, ConnectJobStatus, ConnectLlm,
8
- ConnectSessionStatus, ConnectTarget, ConnectTransport, ModelTier
7
+ ConnectExecutor, ConnectHarness, ConnectLlm, ConnectSessionStatus, ConnectTarget,
8
+ ConnectTransport, ConnectWaitReason, ModelTier
9
9
  } from './consts.js'
10
10
  import type { InquiryAnswerPayload, InquiryPayload } from './ops.js'
11
11
 
@@ -82,68 +82,22 @@ export interface ConnectSessionView {
82
82
  expiresAt: string
83
83
  }
84
84
 
85
- /**
86
- * A derived view of "what the platform is doing for this project right now".
87
- *
88
- * Never stored. It is composed per request from the project lock, the slot record, the story
89
- * card, the latest pipeline run row and the operations queued for the project — the same facts
90
- * the manager UI reads, arranged for a caller that has one question ("may I stop waiting?") and
91
- * one follow-up ("what do I call next?").
92
- *
93
- * Its `id` is composed and parsed only through `jobIdOf` / `parseJobId`.
94
- */
95
- export interface ConnectJob {
96
- id: string
97
- kind: ConnectJobKind
98
- status: ConnectJobStatus
99
- /** The project CARD id. */
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
- */
107
- storyId?: string
108
- runId?: string
109
- /** The pipeline step in flight, when a run row says. */
110
- phase?: string
111
- progress?: ConnectJobProgress
112
- blockedOn?: ConnectJobBlock
113
- /**
114
- * The question a parked run is waiting on — present exactly when it is blocked on one.
115
- *
116
- * Carried on the job rather than left to a second lookup because a parent reads a job and
117
- * nothing else while it polls: a run that stopped for a person, described only as "blocked",
118
- * is a run whose parent waits out the timeout for a question it was never shown. It is also
119
- * the ONLY way back to a question whose operation timed out while nobody was attached — the
120
- * connector's own queue holds nothing at that point.
121
- */
122
- inquiry?: InquiryPayload
123
- /** One sentence a parent agent can show a human. */
124
- message?: string
125
- /** Present on `Failed`, and on `Done` where the run recorded a warning. */
126
- error?: string
127
- /** Kind-specific payload once `Done`. */
128
- result?: Record<string, unknown>
129
- startedAt?: string
130
- updatedAt: string
85
+ export interface ConnectPullQuery {
86
+ /** Seconds to wait before answering; clamped to the pull ceiling. */
87
+ wait?: number
131
88
  }
132
89
 
133
- export interface ConnectJobProgress {
90
+ export interface ConnectRunStatus {
91
+ runId: string
92
+ pipeline: string
93
+ status: string
134
94
  step?: string
135
95
  completed: string[]
136
96
  pending: string[]
137
- }
138
-
139
- export interface ConnectJobParams {
140
- id: string
141
- jobId: string
142
- }
143
-
144
- export interface ConnectWaitQuery {
145
- /** Seconds to wait before answering; clamped to the pull ceiling. */
146
- wait?: number
97
+ warnings?: string[]
98
+ error?: string
99
+ startedAt?: string
100
+ updatedAt?: string
147
101
  }
148
102
 
149
103
  /** What a connector needs to know about a project in one call. */
@@ -181,18 +135,30 @@ export interface ConnectProjectStatus {
181
135
  }
182
136
  production?: { id: string, status: string, host?: string }
183
137
  agent: { locked: boolean, task?: string, lockedAt?: string }
184
- run?: {
185
- runId: string
186
- pipeline: string
187
- status: string
188
- step?: string
189
- completed: string[]
190
- pending: string[]
191
- error?: string
192
- }
138
+ run?: ConnectRunStatus
139
+ waitingFor?: ConnectWaitReason
140
+ pendingInquiry?: InquiryPayload
193
141
  session?: ConnectSessionView
194
142
  /** Set for a local target: the connector should not offer cloud-only operations. */
195
143
  local: boolean
144
+ updatedAt: string
145
+ }
146
+
147
+ /** A story card composed with its deterministic development run. */
148
+ export interface ConnectStoryStatus {
149
+ projectId: string
150
+ story: {
151
+ id: string
152
+ code: string
153
+ title: string
154
+ status: string
155
+ intrinsic: string
156
+ warning?: string
157
+ }
158
+ run?: ConnectRunStatus
159
+ waitingFor?: ConnectWaitReason
160
+ pendingInquiry?: InquiryPayload
161
+ updatedAt: string
196
162
  }
197
163
 
198
164
  /** The record a local project keeps so a later session knows what it is. */
@@ -217,7 +183,7 @@ export interface ConnectProfileSettingsView extends ConnectProfileSettings {
217
183
  * The profile's preference for who performs a CONVERSION's model calls.
218
184
  *
219
185
  * Its own setting rather than a reading of `llmMode`, because the two answer for different
220
- * work: a conversion reads somebody else's whole repository, which is the one job where handing
186
+ * work: a conversion reads somebody else's whole repository, which is the one case where handing
221
187
  * the inference to the parent agent is the cheap default rather than the experimental option.
222
188
  *
223
189
  * OPTIONAL for the same reason {@link ConnectCapabilitiesView.defaults} carries `converterLlm`
@@ -397,6 +363,7 @@ export interface ConversionStatusView {
397
363
  runId?: string
398
364
  /** Set exactly when `status` is `Waiting`: the question the run stopped on. */
399
365
  pendingInquiry?: InquiryPayload
366
+ waitingFor?: ConnectWaitReason
400
367
  lastError?: string
401
368
  updatedAt: string
402
369
  }
@@ -428,6 +395,8 @@ export interface ConnectPipelineState {
428
395
  failedAt?: string
429
396
  error?: string
430
397
  note?: string
398
+ waitingFor?: ConnectWaitReason
399
+ pendingInquiry?: InquiryPayload
431
400
  attempts: number
432
401
  startedAt: string
433
402
  heartbeatAt: string
@@ -40,7 +40,7 @@ export const isEphemeralActor = (actor?: StoryActor): boolean =>
40
40
  export interface StoryDesignJob {
41
41
  /** The queue it is enqueued onto. */
42
42
  queue: string
43
- /** The job name, which IS its entrypoint alias — `app.job.<name>`. */
43
+ /** The job name, which becomes the backend-only `job:<name>` protocol alias. */
44
44
  name: string
45
45
  /** The processor module, relative to the worker package's `src`. */
46
46
  path: string
@@ -35,7 +35,7 @@ export const VIABLE_SPEC_FLOW = 'viable:spec'
35
35
  * The story flow's status keys.
36
36
  *
37
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
38
+ * `docs/stories/<code>.md`, connector status rendering, the board's columns, their i18n
39
39
  * keys and every end-to-end selector read these exact values. A key is a wire contract and is
40
40
  * never renamed.
41
41
  */
@@ -82,9 +82,6 @@ export const ALIAS_CONVENTION = `
82
82
  \`web:layout:\` alias and no \`app.web.layout\` — writing either addresses nothing.
83
83
  - An endpoint alias is \`api:<entity>:<action>\` — \`api:task:list\`, \`api:task:create\`. The
84
84
  group alias that carries the shared path and guard is \`api:<entity>\` — \`api:task\`.
85
- - A queued job alias is \`job:<entity>:<action>\` — \`job:report:build\`, \`job:contract:analyze\`.
86
- A job is never given a \`web:\` or \`api:\` alias, and an endpoint is never given a \`job:\` one:
87
- the prefix is what says which side serves it.
88
85
  - Lowercase kebab-case in every segment. The prefix is NOT optional and NOT decorative: access
89
86
  rules are applied per side by it.
90
87
  `.trim()
@@ -103,11 +100,12 @@ The generated project is a \`@owlmeans/create-app\` monorepo with five workspace
103
100
  - \`sources/web\` — the react application.
104
101
  - \`sources/worker\` — the queue consumer. Same context, no HTTP routes, one processor per job.
105
102
 
106
- These files are the CONTRACT between the packages. Every screen, endpoint and job passes through
107
- them, and each has a sentinel comment marking where a new line goes:
103
+ These files are the CONTRACT between the public packages. Every screen and endpoint passes through
104
+ them; technical worker protocols live in the backend package instead:
108
105
 
109
106
  - \`sources/common/src/consts.ts\` — the \`app\` alias tree.
110
107
  - \`sources/common/src/entrypoints.ts\` — the shared immutable protocol tree (\`appEntrypoints\`).
108
+ - \`sources/backend/src/jobs/index.ts\` — backend-only queue protocols and declarations.
111
109
  - \`sources/api/src/entrypoints.ts\` — server bindings: \`bind\` + one \`handlers<Context>()\` wrap
112
110
  per handler.
113
111
  - \`sources/web/src/entrypoints.ts\` — client bindings (\`bindAll\` + \`bindScreen\`).
@@ -1390,25 +1388,34 @@ the work is invisible and the user is left pressing a button that appears to do
1390
1388
  `),
1391
1389
 
1392
1390
  skill(ViableSkill.WorkerJobs, 'Queues, jobs and processors', `
1393
- Three files have to agree, and a job that exists in two of the three is worse than one that
1391
+ Three server-side bindings have to agree, and a job that exists in two of the three is worse than one that
1394
1392
  exists in none — a declared name nothing processes is a message that piles up, and a processor
1395
1393
  with no declaration is dead code the barrel still imports.
1396
1394
 
1397
- ## 1. The queue — \`sources/backend/src/jobs/index.ts\`
1395
+ ## 1. The protocol and queue — \`sources/backend/src/jobs/index.ts\`
1398
1396
  A queue is an ADDRESS: it says what exists and which job names it accepts. Both the api (which
1399
1397
  enqueues) and the worker (which consumes) read this one list, and a job name the queue does not
1400
- declare is refused at enqueue time.
1398
+ declare is refused at enqueue time. The technical protocol belongs here too; common and web must
1399
+ not import it.
1401
1400
 
1402
1401
  \`\`\`ts
1402
+ export const jobProtocols = {
1403
+ reportBuild: protocol(route(
1404
+ 'job:report:build', '/report-build',
1405
+ queueRoute({ service: APP_WORKER, queue: APP_QUEUE, timeout: 30_000 }),
1406
+ ), contract(typed())),
1407
+ }
1403
1408
  export const queues: QueueDeclaration[] = [
1404
- { name: APP_QUEUE, jobs: [app.job.test, app.job.<name>],
1409
+ { name: APP_QUEUE, jobs: [jobProtocols.reportBuild.alias],
1405
1410
  worker: { concurrency: 4, lockDuration: 60_000 } },
1406
1411
  ]
1407
1412
  \`\`\`
1408
1413
 
1409
- ## 2. The alias and the entrypoint — \`sources/common/src\`
1410
- The job's name IS its entrypoint alias. Declare \`app.job.<name>\` in \`consts.ts\` above the
1411
- sentinel, and the protocol in \`entrypoints.ts\` with \`job()\` from \`@owlmeans/route\`.
1414
+ Use \`job()\` from \`@owlmeans/queue\`, never from the generic route package.
1415
+
1416
+ ## 2. The producer — \`sources/api/src/entrypoints.ts\`
1417
+ Bind \`bindClient(jobProtocols.reportBuild)\`. Public API contracts in common describe the domain
1418
+ operation and do not disclose that the handler delegates to a queue.
1412
1419
 
1413
1420
  ## 3. The processor — \`sources/worker/src/jobs/<name>.ts\`
1414
1421
  A PLAIN exported async function — named exports only, exactly like an endpoint handler. It never
@@ -1421,7 +1428,7 @@ imports \`handlers\` and never calls \`handlers<Context>()\`; that belongs only
1421
1428
  // sources/worker/src/entrypoints.ts — the ONLY wrap
1422
1429
  import * as jobs from '@/jobs/index.js'
1423
1430
  const worker = handlers<Context>()
1424
- bind(protocols.job.reportBuild, worker.request(protocols.job.reportBuild, jobs.handleReportBuildJob))
1431
+ bind(jobProtocols.reportBuild, worker.request(jobProtocols.reportBuild, jobs.handleReportBuildJob))
1425
1432
 
1426
1433
  WRONG — the processor module ALSO calls \`handlers()\` and wraps itself, so the export bound above
1427
1434
  is wrapped a SECOND time. \`tsc\` catches it (\`TS2345 "BoundEntrypointHandler<…> is not
@@ -1430,7 +1437,7 @@ function\`:
1430
1437
 
1431
1438
  // WRONG — sources/worker/src/jobs/report-build.ts
1432
1439
  const worker = handlers<Context>()
1433
- export const handleReportBuildJob = worker.request(protocols.job.reportBuild, async (req, ctx) => { ... })
1440
+ export const handleReportBuildJob = worker.request(jobProtocols.reportBuild, async (req, ctx) => { ... })
1434
1441
 
1435
1442
  It RETURNS its result; throwing a \`ResilientError\` subclass is how a refusal is reported, and the
1436
1443
  class survives the broker.
@@ -1443,7 +1450,7 @@ Two rules with no equivalent on the HTTP side:
1443
1450
  what it created, and say in a comment which of the two this one does.
1444
1451
 
1445
1452
  Enqueue from an endpoint with the same typed call used for HTTP:
1446
- \`context.entrypoint(appEntrypoints.job.<name>).call({ body: data })\`.
1453
+ \`context.entrypoint(jobProtocols.<name>).call({ body: data })\`.
1447
1454
  `),
1448
1455
 
1449
1456
  skill(ViableSkill.TargetAgents, 'LLM agents inside the application', `
@@ -3,7 +3,7 @@ import Ajv from 'ajv'
3
3
  import addFormats from 'ajv-formats'
4
4
  import { RouteMethod, route } from '@owlmeans/route'
5
5
  import { aliasOf, openProtocol, protocols } from '@owlmeans/entrypoint'
6
- import { connect, ConnectInquiryKind, ConnectJobKind, ConnectOpKind } from '../src/connect/consts.js'
6
+ import { connect, ConnectInquiryKind, ConnectOpKind } from '../src/connect/consts.js'
7
7
  import { connectProtocols } from '../src/connect/entrypoints.js'
8
8
  import { connectRef } from '../src/connect/references.js'
9
9
  import {
@@ -151,12 +151,6 @@ describe('viable-common - the conversion additions to the connector contract', (
151
151
  // while the two enums stay byte-identical — `manager-api` does not depend on the model
152
152
  // runtime, so nothing else in the stack would notice one of them gaining a fourth shape.
153
153
  expect(Object.values(ConnectInquiryKind)).toEqual(Object.values(InquiryKind))
154
- // One job kind per stage: each stage is its own pipeline run, looked up by the alias its kind
155
- // names, so a single `convert` kind would match whichever run row happened to be newest.
156
- expect(ConnectJobKind.ConvertIntake).toBe('convert-intake')
157
- expect(ConnectJobKind.ConvertAnalysis).toBe('convert-analysis')
158
- expect(ConnectJobKind.ConvertExtraction).toBe('convert-extraction')
159
- expect(ConnectJobKind.ConvertImplementation).toBe('convert-implementation')
160
- expect(ConnectJobKind.ConvertPurge).toBe('convert-purge')
154
+ expect(connect.convert.status).toBe('viable:manager-api:connect:convert:status')
161
155
  })
162
156
  })
@@ -2,9 +2,8 @@ import { describe, expect, test } from 'bun:test'
2
2
  import { openProtocol, protocols } from '@owlmeans/entrypoint'
3
3
  import { DEFAULT_GUARD } from '@owlmeans/auth-common'
4
4
  import { route } from '@owlmeans/route'
5
- import { connect, ConnectJobKind } from '../src/connect/consts.js'
5
+ import { connect } from '../src/connect/consts.js'
6
6
  import { connectProtocols } from '../src/connect/entrypoints.js'
7
- import { JOB_SEPARATOR, jobIdOf, parseJobId } from '../src/connect/jobs.js'
8
7
  import { connectRef } from '../src/connect/references.js'
9
8
 
10
9
  describe('@owlmeans/viable-common — connector protocol tree', () => {
@@ -18,6 +17,7 @@ describe('@owlmeans/viable-common — connector protocol tree', () => {
18
17
  expect(tree.session.open.alias).toBe(connect.session.open)
19
18
  expect(tree.project.llm.alias).toBe(connect.project.llm)
20
19
  expect(tree.project.converterLlm.alias).toBe(connect.project.converterLlm)
20
+ expect(tree.story.status.alias).toBe(connect.story.status)
21
21
  expect(tree.convert.proceed.alias).toBe(connect.convert.proceed)
22
22
  expect(tree.inquiry.answer.alias).toBe(connect.inquiry.answer)
23
23
  expect(tree.files.list.alias).toBe(connect.files.list)
@@ -25,33 +25,15 @@ describe('@owlmeans/viable-common — connector protocol tree', () => {
25
25
  expect(new Set(protocols(tree).map(protocol => protocol.alias)).size).toBe(32)
26
26
  })
27
27
 
28
- test('carries no story routes: stories are planning cards served by the planning tree', () => {
29
- expect((tree as Record<string, unknown>).story).toBeUndefined()
30
- expect((connect as Record<string, unknown>).story).toBeUndefined()
31
- expect((connectRef as unknown as Record<string, unknown>).story).toBeUndefined()
32
- expect(protocols(tree).some(protocol => protocol.alias.includes(':story:'))).toBe(false)
28
+ test('keeps story mutations in planning and exposes only the composed story status', () => {
29
+ expect(Object.keys(tree.story)).toEqual(['status'])
30
+ expect(Object.keys(connect.story)).toEqual(['status'])
31
+ expect(Object.keys(connectRef.story)).toEqual(['status'])
32
+ expect(tree.story.status.route.route.path).toBe('/project/:id/story/:storyId/status')
33
33
  })
34
- })
35
-
36
- describe('@owlmeans/viable-common — connector job ids', () => {
37
- test('a story job id names the card and splits back into its parts', () => {
38
- const id = jobIdOf(ConnectJobKind.StoryDevelop, 'project-card', 'story-card')
39
-
40
- expect(id).toBe(['story-develop', 'project-card', 'story-card'].join(JOB_SEPARATOR))
41
- expect(parseJobId(id)).toEqual({
42
- kind: ConnectJobKind.StoryDevelop, projectId: 'project-card', suffix: 'story-card',
43
- })
44
- })
45
-
46
- test('a job with no subject carries no suffix', () => {
47
- expect(parseJobId(jobIdOf(ConnectJobKind.ProjectInit, 'p1'))).toEqual({
48
- kind: ConnectJobKind.ProjectInit, projectId: 'p1',
49
- })
50
- })
51
-
52
- test('a suffix that contains the separator is rejoined, never truncated', () => {
53
- const suffix = `run${JOB_SEPARATOR}tail`
54
-
55
- expect(parseJobId(jobIdOf(ConnectJobKind.PipelineResume, 'p1', suffix)).suffix).toBe(suffix)
34
+ test('has no generic connector job endpoint', () => {
35
+ expect((tree.project as Record<string, unknown>).job).toBeUndefined()
36
+ expect((connect.project as Record<string, unknown>).job).toBeUndefined()
37
+ expect((connectRef.project as Record<string, unknown>).job).toBeUndefined()
56
38
  })
57
39
  })
@@ -1,25 +0,0 @@
1
- import type { ConnectJobKind } from './consts.js';
2
- /**
3
- * The separator a job id is joined with.
4
- *
5
- * `~`, because every other separator in play is already spoken for: a route alias is
6
- * colon-delimited and so is every run id (`init:<projectId>`, `story:<storyId>`), so a job id
7
- * built with one could not be split back apart.
8
- */
9
- export declare const JOB_SEPARATOR = "~";
10
- /**
11
- * A job's id: its kind, the project card it belongs to, and the subject it is about.
12
- *
13
- * The suffix is a CARD id for a story job and a run id for a pipeline job — never a story code.
14
- * Declared here rather than by whoever answers the job, because the SDK composes the id it then
15
- * polls for: two spellings of one id is a job nobody can find.
16
- */
17
- export declare const jobIdOf: (kind: ConnectJobKind, projectId: string, suffix?: string) => string;
18
- export interface ParsedJobId {
19
- kind: ConnectJobKind;
20
- projectId: string;
21
- suffix?: string;
22
- }
23
- /** Split a job id back into what {@link jobIdOf} composed it from. */
24
- export declare const parseJobId: (jobId: string) => ParsedJobId;
25
- //# sourceMappingURL=jobs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../../src/connect/jobs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,MAAM,CAAA;AAEhC;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,SAAU,cAAc,aAAa,MAAM,WAAW,MAAM,KAAG,MACP,CAAA;AAE5E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,sEAAsE;AACtE,eAAO,MAAM,UAAU,UAAW,MAAM,KAAG,WAW1C,CAAA"}
@@ -1,29 +0,0 @@
1
- /**
2
- * The separator a job id is joined with.
3
- *
4
- * `~`, because every other separator in play is already spoken for: a route alias is
5
- * colon-delimited and so is every run id (`init:<projectId>`, `story:<storyId>`), so a job id
6
- * built with one could not be split back apart.
7
- */
8
- export const JOB_SEPARATOR = '~';
9
- /**
10
- * A job's id: its kind, the project card it belongs to, and the subject it is about.
11
- *
12
- * The suffix is a CARD id for a story job and a run id for a pipeline job — never a story code.
13
- * Declared here rather than by whoever answers the job, because the SDK composes the id it then
14
- * polls for: two spellings of one id is a job nobody can find.
15
- */
16
- export const jobIdOf = (kind, projectId, suffix) => [kind, projectId, ...(suffix != null ? [suffix] : [])].join(JOB_SEPARATOR);
17
- /** Split a job id back into what {@link jobIdOf} composed it from. */
18
- export const parseJobId = (jobId) => {
19
- const [kind, projectId, ...rest] = jobId.split(JOB_SEPARATOR);
20
- // A suffix may carry the separator back if one ever ends up in a card or run id, so the tail is
21
- // rejoined rather than taken as its first segment.
22
- const suffix = rest.length > 0 ? rest.join(JOB_SEPARATOR) : undefined;
23
- return {
24
- kind: kind,
25
- projectId: projectId ?? '',
26
- ...(suffix != null ? { suffix } : {}),
27
- };
28
- };
29
- //# sourceMappingURL=jobs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/connect/jobs.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;AAEhC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAoB,EAAE,SAAiB,EAAE,MAAe,EAAU,EAAE,CAC1F,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;AAQ5E,sEAAsE;AACtE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAe,EAAE;IACvD,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;IAC7D,gGAAgG;IAChG,mDAAmD;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAErE,OAAO;QACL,IAAI,EAAE,IAAsB;QAC5B,SAAS,EAAE,SAAS,IAAI,EAAE;QAC1B,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAA;AACH,CAAC,CAAA"}
@@ -1,40 +0,0 @@
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
- }