@valescoagency/runway 0.8.0 → 0.8.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/README.md +1 -1
- package/dist/linear.js +39 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -392,7 +392,7 @@ These are tractable, just not v1.
|
|
|
392
392
|
|
|
393
393
|
## Status
|
|
394
394
|
|
|
395
|
-
0.8.
|
|
395
|
+
0.8.1 — production-shaped and dogfooded against live Linear queues.
|
|
396
396
|
The end-to-end pipeline (init → run → review → PR) is stable; surface
|
|
397
397
|
may still shift as the orchestrator's policy and iteration mechanics
|
|
398
398
|
mature. See [CHANGELOG.md](./CHANGELOG.md) for per-release detail.
|
package/dist/linear.js
CHANGED
|
@@ -42,14 +42,20 @@ const WorkflowStateTypeNodeSchema = Schema.Struct({
|
|
|
42
42
|
// integration comments can lack an author); we map a missing user to
|
|
43
43
|
// the empty string so downstream filters can match by name without a
|
|
44
44
|
// null-guard at every call site.
|
|
45
|
+
//
|
|
46
|
+
// VA-415: `user` can also be *absent from the payload entirely* (vs.
|
|
47
|
+
// present-and-null) on some system / deleted-user comments. The
|
|
48
|
+
// optional + nullable shape below accepts all three forms: missing,
|
|
49
|
+
// null, and full struct. Downstream code already null-coalesces via
|
|
50
|
+
// `comment.user?.name ?? ""`.
|
|
45
51
|
const CommentNodeSchema = Schema.Struct({
|
|
46
52
|
id: Schema.String,
|
|
47
53
|
body: Schema.String,
|
|
48
54
|
createdAt: Schema.Union(Schema.String, Schema.DateFromSelf),
|
|
49
|
-
user: Schema.NullOr(Schema.Struct({
|
|
55
|
+
user: Schema.optional(Schema.NullOr(Schema.Struct({
|
|
50
56
|
id: Schema.String,
|
|
51
57
|
name: Schema.String,
|
|
52
|
-
})),
|
|
58
|
+
}))),
|
|
53
59
|
});
|
|
54
60
|
const ViewerSchema = Schema.Struct({
|
|
55
61
|
id: Schema.String,
|
|
@@ -358,21 +364,44 @@ export function createLinearGateway(config, limiter = null) {
|
|
|
358
364
|
message: `Issue ${issueId} has no team`,
|
|
359
365
|
});
|
|
360
366
|
}
|
|
367
|
+
// VA-416: Linear labels can be team-scoped OR
|
|
368
|
+
// workspace-scoped (no team association). Earlier code
|
|
369
|
+
// filtered by team only, which silently excluded
|
|
370
|
+
// workspace-scoped labels like the default
|
|
371
|
+
// `ready-for-human`. Query by name alone, then prefer a
|
|
372
|
+
// team-scoped match when one exists so the team-vs-
|
|
373
|
+
// workspace name-collision edge resolves the obvious way.
|
|
361
374
|
const labels = await client.issueLabels({
|
|
362
|
-
filter: {
|
|
363
|
-
team: { id: { eq: team.id } },
|
|
364
|
-
name: { eq: labelName },
|
|
365
|
-
},
|
|
375
|
+
filter: { name: { eq: labelName } },
|
|
366
376
|
});
|
|
367
|
-
const
|
|
368
|
-
|
|
377
|
+
const decoded = labels.nodes.map((l) => ({
|
|
378
|
+
raw: l,
|
|
379
|
+
decoded: decodeIssueLabelNode(l),
|
|
380
|
+
}));
|
|
381
|
+
const teamScoped = await (async () => {
|
|
382
|
+
for (const { raw, decoded: d } of decoded) {
|
|
383
|
+
const labelTeam = await raw.team;
|
|
384
|
+
if (labelTeam?.id === team.id)
|
|
385
|
+
return d;
|
|
386
|
+
}
|
|
387
|
+
return undefined;
|
|
388
|
+
})();
|
|
389
|
+
const workspaceScoped = await (async () => {
|
|
390
|
+
for (const { raw, decoded: d } of decoded) {
|
|
391
|
+
const labelTeam = await raw.team;
|
|
392
|
+
if (!labelTeam)
|
|
393
|
+
return d;
|
|
394
|
+
}
|
|
395
|
+
return undefined;
|
|
396
|
+
})();
|
|
397
|
+
const label = teamScoped ?? workspaceScoped;
|
|
398
|
+
if (!label) {
|
|
369
399
|
throw new LinearNotFound({
|
|
370
400
|
resource: "label",
|
|
371
401
|
identifier: labelName,
|
|
372
|
-
message: `Linear label "${labelName}" not found on team ${team.id}`,
|
|
402
|
+
message: `Linear label "${labelName}" not found at workspace scope or on team ${team.id}`,
|
|
373
403
|
});
|
|
374
404
|
}
|
|
375
|
-
const label = decodeIssueLabelNode(rawLabel);
|
|
376
405
|
const existing = await issue.labels();
|
|
377
406
|
const existingIds = existing.nodes.map((l) => decodeIssueLabelNode(l).id);
|
|
378
407
|
const labelIds = [...existingIds, label.id];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valescoagency/runway",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Linear-driven orchestrator + scaffolder for coding agents on Sandcastle. `runway init` scaffolds a target repo (sandcastle + varlock + 1Password); `runway run` drains a Linear queue against it; `runway doctor`, `runway upgrade`, `runway upgrade-repo` round out the lifecycle.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|