syntaur 0.46.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dashboard/dist/assets/{_basePickBy-RQBuJKcX.js → _basePickBy-Cie7FXcV.js} +1 -1
- package/dashboard/dist/assets/{_baseUniq-_J7s4kD3.js → _baseUniq-C2af7-lW.js} +1 -1
- package/dashboard/dist/assets/{arc-_9SyUgKQ.js → arc-BHKGjEv8.js} +1 -1
- package/dashboard/dist/assets/{architectureDiagram-2XIMDMQ5-C8LeFMgr.js → architectureDiagram-2XIMDMQ5-CWqzcG1t.js} +1 -1
- package/dashboard/dist/assets/{blockDiagram-WCTKOSBZ-gMh0EPEh.js → blockDiagram-WCTKOSBZ-CHLC0M63.js} +1 -1
- package/dashboard/dist/assets/{c4Diagram-IC4MRINW-cHwecwLI.js → c4Diagram-IC4MRINW-Bx6GTZzJ.js} +1 -1
- package/dashboard/dist/assets/channel-CXlttLwe.js +1 -0
- package/dashboard/dist/assets/{chunk-4BX2VUAB-Bb2anYuQ.js → chunk-4BX2VUAB-7cTgwG6c.js} +1 -1
- package/dashboard/dist/assets/{chunk-55IACEB6-DYIRGzA1.js → chunk-55IACEB6-DQmdA20e.js} +1 -1
- package/dashboard/dist/assets/{chunk-FMBD7UC4-sgRWBbaF.js → chunk-FMBD7UC4-knmOnIKI.js} +1 -1
- package/dashboard/dist/assets/{chunk-JSJVCQXG-DlYKMl_j.js → chunk-JSJVCQXG-CaiLHJFn.js} +1 -1
- package/dashboard/dist/assets/{chunk-KX2RTZJC-D0YDLAOF.js → chunk-KX2RTZJC-Crp4zWuY.js} +1 -1
- package/dashboard/dist/assets/{chunk-NQ4KR5QH-D-Y-CUx6.js → chunk-NQ4KR5QH-DDjtdNaK.js} +1 -1
- package/dashboard/dist/assets/{chunk-QZHKN3VN-D7FpSvb5.js → chunk-QZHKN3VN-Cbm1IieP.js} +1 -1
- package/dashboard/dist/assets/{chunk-WL4C6EOR-CtXgQLdS.js → chunk-WL4C6EOR-CdrRh6R4.js} +1 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-BJM0Dprk.js +1 -0
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BJM0Dprk.js +1 -0
- package/dashboard/dist/assets/clone-BTq7ueDt.js +1 -0
- package/dashboard/dist/assets/{cose-bilkent-S5V4N54A-YbTaohoJ.js → cose-bilkent-S5V4N54A-DyNajnMF.js} +1 -1
- package/dashboard/dist/assets/{dagre-KLK3FWXG-CMtwGAnP.js → dagre-KLK3FWXG-CIBjpfqE.js} +1 -1
- package/dashboard/dist/assets/{diagram-E7M64L7V-D8wBMBAX.js → diagram-E7M64L7V-CDENlpZN.js} +1 -1
- package/dashboard/dist/assets/{diagram-IFDJBPK2-DfudLpiJ.js → diagram-IFDJBPK2-CIGMJoFB.js} +1 -1
- package/dashboard/dist/assets/{diagram-P4PSJMXO-CyMy61wE.js → diagram-P4PSJMXO-C27fj5wp.js} +1 -1
- package/dashboard/dist/assets/{erDiagram-INFDFZHY-BlB4ZQl9.js → erDiagram-INFDFZHY-M2CywJym.js} +1 -1
- package/dashboard/dist/assets/{flowDiagram-PKNHOUZH-DbhDQJM3.js → flowDiagram-PKNHOUZH-CTV6ROYf.js} +1 -1
- package/dashboard/dist/assets/{ganttDiagram-A5KZAMGK-DJFqteNi.js → ganttDiagram-A5KZAMGK-CxH3f3e5.js} +1 -1
- package/dashboard/dist/assets/{gitGraphDiagram-K3NZZRJ6-D8etA_mm.js → gitGraphDiagram-K3NZZRJ6-CwhnVvHE.js} +1 -1
- package/dashboard/dist/assets/{graph-Ce86jeZn.js → graph-DGkI_ekZ.js} +1 -1
- package/dashboard/dist/assets/{index-DzHQIE2n.css → index-BxO2I5dN.css} +1 -1
- package/dashboard/dist/assets/index-CTdFARW9.js +567 -0
- package/dashboard/dist/assets/{infoDiagram-LFFYTUFH-Cx35U-h8.js → infoDiagram-LFFYTUFH-CuKReAi2.js} +1 -1
- package/dashboard/dist/assets/{ishikawaDiagram-PHBUUO56-C04Y2nj8.js → ishikawaDiagram-PHBUUO56-DyBMt5Mw.js} +1 -1
- package/dashboard/dist/assets/{journeyDiagram-4ABVD52K-D8-cxbxE.js → journeyDiagram-4ABVD52K-CnwtbTNs.js} +1 -1
- package/dashboard/dist/assets/{kanban-definition-K7BYSVSG-DVKqMylP.js → kanban-definition-K7BYSVSG-5Sh1bC5j.js} +1 -1
- package/dashboard/dist/assets/{layout-98xZDpgu.js → layout-W2Vytcip.js} +1 -1
- package/dashboard/dist/assets/{linear-0jk_IwAc.js → linear-UTm9E6c4.js} +1 -1
- package/dashboard/dist/assets/{mermaid.core-C337VWfr.js → mermaid.core-B0EB-dBk.js} +4 -4
- package/dashboard/dist/assets/{mindmap-definition-YRQLILUH-8sNYGYEP.js → mindmap-definition-YRQLILUH-CH4L08eg.js} +1 -1
- package/dashboard/dist/assets/{pieDiagram-SKSYHLDU-afcmzHxf.js → pieDiagram-SKSYHLDU-CQ3PMl-w.js} +1 -1
- package/dashboard/dist/assets/{quadrantDiagram-337W2JSQ-B4RjcpOq.js → quadrantDiagram-337W2JSQ-DbZgXUm5.js} +1 -1
- package/dashboard/dist/assets/{requirementDiagram-Z7DCOOCP-CRavU6cI.js → requirementDiagram-Z7DCOOCP-CxJWytQa.js} +1 -1
- package/dashboard/dist/assets/{sankeyDiagram-WA2Y5GQK-DFomU3z-.js → sankeyDiagram-WA2Y5GQK-3YeEasvh.js} +1 -1
- package/dashboard/dist/assets/{sequenceDiagram-2WXFIKYE-CGKO7nmK.js → sequenceDiagram-2WXFIKYE-F2EyvYsW.js} +1 -1
- package/dashboard/dist/assets/{stateDiagram-RAJIS63D-BjFI1K8h.js → stateDiagram-RAJIS63D-DrmiemaD.js} +1 -1
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-DfyvP5EF.js +1 -0
- package/dashboard/dist/assets/{timeline-definition-YZTLITO2-BBo8XJFG.js → timeline-definition-YZTLITO2-CBee2YiE.js} +1 -1
- package/dashboard/dist/assets/{treemap-KZPCXAKY-COd6i6TE.js → treemap-KZPCXAKY-BkPRIS3K.js} +1 -1
- package/dashboard/dist/assets/{vennDiagram-LZ73GAT5-CGQweQ36.js → vennDiagram-LZ73GAT5-CTsfwv8G.js} +1 -1
- package/dashboard/dist/assets/{xychartDiagram-JWTSCODW-mfJ5So7N.js → xychartDiagram-JWTSCODW-DUSo-c6w.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dist/dashboard/server.js +188 -73
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +198 -74
- package/dist/index.js.map +1 -1
- package/dist/launch/index.d.ts +25 -12
- package/dist/launch/index.js +62 -58
- package/dist/launch/index.js.map +1 -1
- package/package.json +1 -1
- package/platforms/claude-code/.claude-plugin/plugin.json +1 -1
- package/platforms/claude-code/skills/manage-statuses/SKILL.md +7 -0
- package/platforms/codex/.codex-plugin/plugin.json +1 -1
- package/platforms/codex/skills/manage-statuses/SKILL.md +7 -0
- package/platforms/hermes/plugins/syntaur/__pycache__/__init__.cpython-312.pyc +0 -0
- package/platforms/hermes/plugins/syntaur/__pycache__/boundary.cpython-312.pyc +0 -0
- package/skills/manage-statuses/SKILL.md +7 -0
- package/dashboard/dist/assets/channel-C36dnl_e.js +0 -1
- package/dashboard/dist/assets/classDiagram-VBA2DB6C-BsoGa6_a.js +0 -1
- package/dashboard/dist/assets/classDiagram-v2-RAHNMMFH-BsoGa6_a.js +0 -1
- package/dashboard/dist/assets/clone-Bz6jW3OY.js +0 -1
- package/dashboard/dist/assets/index-DRng26Jg.js +0 -567
- package/dashboard/dist/assets/stateDiagram-v2-FVOUBMTO-BtxefYKD.js +0 -1
package/dist/dashboard/server.js
CHANGED
|
@@ -3046,6 +3046,53 @@ function factFieldNames(decl) {
|
|
|
3046
3046
|
].map((k) => k.toLowerCase()) : [exportNames.fact.toLowerCase()];
|
|
3047
3047
|
return { storageKey: name, exports: exportNames, registryKeys };
|
|
3048
3048
|
}
|
|
3049
|
+
function validateFactDeclarations(raw2) {
|
|
3050
|
+
const problems = [];
|
|
3051
|
+
const owners = /* @__PURE__ */ new Map();
|
|
3052
|
+
for (const key of Object.keys(DERIVE_FIELDS)) owners.set(key, "built-in");
|
|
3053
|
+
for (const key of Object.keys(ASSIGNMENT_FIELDS)) owners.set(key, "built-in");
|
|
3054
|
+
for (const row of raw2 ?? []) {
|
|
3055
|
+
const name = (row?.name ?? "").trim();
|
|
3056
|
+
if (!/^[a-z][a-zA-Z0-9]*$/.test(name)) {
|
|
3057
|
+
problems.push(
|
|
3058
|
+
`fact "${row?.name ?? ""}": invalid name \u2014 must match /^[a-z][a-zA-Z0-9]*$/`
|
|
3059
|
+
);
|
|
3060
|
+
continue;
|
|
3061
|
+
}
|
|
3062
|
+
const type = (row.type ?? "").trim();
|
|
3063
|
+
if (type !== "bool" && type !== "number" && type !== "attestation") {
|
|
3064
|
+
problems.push(
|
|
3065
|
+
`fact "${name}": invalid type "${row.type ?? ""}" \u2014 expected bool, number, or attestation`
|
|
3066
|
+
);
|
|
3067
|
+
continue;
|
|
3068
|
+
}
|
|
3069
|
+
if (type === "attestation") {
|
|
3070
|
+
const binds = (row.binds ?? "none").toString().trim() || "none";
|
|
3071
|
+
if (binds !== "plan" && binds !== "commit" && binds !== "none") {
|
|
3072
|
+
problems.push(
|
|
3073
|
+
`fact "${name}": invalid binds "${row.binds}" \u2014 expected plan, commit, or none`
|
|
3074
|
+
);
|
|
3075
|
+
continue;
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
const decl = type === "attestation" ? { name, type, binds: "none" } : { name, type };
|
|
3079
|
+
const keys = factFieldNames(decl).registryKeys;
|
|
3080
|
+
const collidingKey = keys.find((k) => owners.has(k));
|
|
3081
|
+
if (collidingKey !== void 0) {
|
|
3082
|
+
const owner = owners.get(collidingKey);
|
|
3083
|
+
if (owner === "built-in") {
|
|
3084
|
+
problems.push(`fact "${name}": exported field "${collidingKey}" collides with a built-in field`);
|
|
3085
|
+
} else if (owner === name) {
|
|
3086
|
+
problems.push(`fact "${name}": duplicate declaration (a fact named "${name}" is already declared)`);
|
|
3087
|
+
} else {
|
|
3088
|
+
problems.push(`fact "${name}": exported field "${collidingKey}" collides with fact "${owner}"`);
|
|
3089
|
+
}
|
|
3090
|
+
continue;
|
|
3091
|
+
}
|
|
3092
|
+
for (const key of keys) owners.set(key, name);
|
|
3093
|
+
}
|
|
3094
|
+
return problems;
|
|
3095
|
+
}
|
|
3049
3096
|
function acceptFactDeclarations(declarations) {
|
|
3050
3097
|
const taken = /* @__PURE__ */ new Set([
|
|
3051
3098
|
...Object.keys(DERIVE_FIELDS),
|
|
@@ -3571,7 +3618,6 @@ function parseStatusConfig(content) {
|
|
|
3571
3618
|
continue;
|
|
3572
3619
|
}
|
|
3573
3620
|
}
|
|
3574
|
-
if (statuses.length === 0) return null;
|
|
3575
3621
|
const derive = phaseLadder.length > 0 || disposition.length > 0 || Object.keys(headline).length > 0 ? {
|
|
3576
3622
|
phaseLadder: phaseLadder.length > 0 ? phaseLadder : DEFAULT_DERIVE_CONFIG.phaseLadder,
|
|
3577
3623
|
disposition: disposition.length > 0 ? disposition : DEFAULT_DERIVE_CONFIG.disposition,
|
|
@@ -3582,6 +3628,7 @@ function parseStatusConfig(content) {
|
|
|
3582
3628
|
active: "phase"
|
|
3583
3629
|
}
|
|
3584
3630
|
} : null;
|
|
3631
|
+
if (statuses.length === 0 && facts.length === 0 && derive === null) return null;
|
|
3585
3632
|
return {
|
|
3586
3633
|
statuses,
|
|
3587
3634
|
order: order.length > 0 ? order : statuses.map((s) => s.id),
|
|
@@ -3707,53 +3754,6 @@ function validateDeriveConfig(derive, statusConfig, validateWhen = () => null) {
|
|
|
3707
3754
|
}
|
|
3708
3755
|
return problems;
|
|
3709
3756
|
}
|
|
3710
|
-
function validateFactDeclarations(raw2) {
|
|
3711
|
-
const problems = [];
|
|
3712
|
-
const owners = /* @__PURE__ */ new Map();
|
|
3713
|
-
for (const key of Object.keys(DERIVE_FIELDS)) owners.set(key, "built-in");
|
|
3714
|
-
for (const key of Object.keys(ASSIGNMENT_FIELDS)) owners.set(key, "built-in");
|
|
3715
|
-
for (const row of raw2 ?? []) {
|
|
3716
|
-
const name = (row?.name ?? "").trim();
|
|
3717
|
-
if (!/^[a-z][a-zA-Z0-9]*$/.test(name)) {
|
|
3718
|
-
problems.push(
|
|
3719
|
-
`fact "${row?.name ?? ""}": invalid name \u2014 must match /^[a-z][a-zA-Z0-9]*$/`
|
|
3720
|
-
);
|
|
3721
|
-
continue;
|
|
3722
|
-
}
|
|
3723
|
-
const type = (row.type ?? "").trim();
|
|
3724
|
-
if (type !== "bool" && type !== "number" && type !== "attestation") {
|
|
3725
|
-
problems.push(
|
|
3726
|
-
`fact "${name}": invalid type "${row.type ?? ""}" \u2014 expected bool, number, or attestation`
|
|
3727
|
-
);
|
|
3728
|
-
continue;
|
|
3729
|
-
}
|
|
3730
|
-
if (type === "attestation") {
|
|
3731
|
-
const binds = (row.binds ?? "none").toString().trim() || "none";
|
|
3732
|
-
if (binds !== "plan" && binds !== "commit" && binds !== "none") {
|
|
3733
|
-
problems.push(
|
|
3734
|
-
`fact "${name}": invalid binds "${row.binds}" \u2014 expected plan, commit, or none`
|
|
3735
|
-
);
|
|
3736
|
-
continue;
|
|
3737
|
-
}
|
|
3738
|
-
}
|
|
3739
|
-
const decl = type === "attestation" ? { name, type, binds: "none" } : { name, type };
|
|
3740
|
-
const keys = factFieldNames(decl).registryKeys;
|
|
3741
|
-
const collidingKey = keys.find((k) => owners.has(k));
|
|
3742
|
-
if (collidingKey !== void 0) {
|
|
3743
|
-
const owner = owners.get(collidingKey);
|
|
3744
|
-
if (owner === "built-in") {
|
|
3745
|
-
problems.push(`fact "${name}": exported field "${collidingKey}" collides with a built-in field`);
|
|
3746
|
-
} else if (owner === name) {
|
|
3747
|
-
problems.push(`fact "${name}": duplicate declaration (a fact named "${name}" is already declared)`);
|
|
3748
|
-
} else {
|
|
3749
|
-
problems.push(`fact "${name}": exported field "${collidingKey}" collides with fact "${owner}"`);
|
|
3750
|
-
}
|
|
3751
|
-
continue;
|
|
3752
|
-
}
|
|
3753
|
-
for (const key of keys) owners.set(key, name);
|
|
3754
|
-
}
|
|
3755
|
-
return problems;
|
|
3756
|
-
}
|
|
3757
3757
|
function serializeIntegrationConfig(integrations) {
|
|
3758
3758
|
const lines = [];
|
|
3759
3759
|
if (integrations.claudePluginDir) {
|
|
@@ -4833,7 +4833,6 @@ var init_config2 = __esm({
|
|
|
4833
4833
|
init_agents_schema();
|
|
4834
4834
|
init_slug();
|
|
4835
4835
|
init_fact_registry();
|
|
4836
|
-
init_query();
|
|
4837
4836
|
init_terminal_schema();
|
|
4838
4837
|
init_workspace_visibility_schema();
|
|
4839
4838
|
DEFAULT_DERIVE_CONFIG = {
|
|
@@ -6061,7 +6060,8 @@ function rowToSession(row) {
|
|
|
6061
6060
|
transcriptPath: row.transcript_path ?? null,
|
|
6062
6061
|
pid: row.pid ?? null,
|
|
6063
6062
|
pidStartedAt: row.pid_started_at ?? null,
|
|
6064
|
-
originalHeadSha: row.original_head_sha ?? null
|
|
6063
|
+
originalHeadSha: row.original_head_sha ?? null,
|
|
6064
|
+
updatedAt: row.updated_at ?? null
|
|
6065
6065
|
};
|
|
6066
6066
|
}
|
|
6067
6067
|
async function appendSession(_projectDir, session, opts) {
|
|
@@ -7452,24 +7452,28 @@ async function getStatusConfig() {
|
|
|
7452
7452
|
if (_cachedConfig) return _cachedConfig;
|
|
7453
7453
|
const config = await readConfig();
|
|
7454
7454
|
if (config.statuses) {
|
|
7455
|
+
const sc = config.statuses;
|
|
7456
|
+
const defaults = sc.statuses.length === 0 ? buildDefaultStatusConfig() : null;
|
|
7457
|
+
const effectiveStatuses = defaults ? defaults.statuses : sc.statuses;
|
|
7458
|
+
const effectiveOrder = defaults ? defaults.order : sc.order;
|
|
7455
7459
|
const terminalSet = new Set(
|
|
7456
|
-
|
|
7460
|
+
effectiveStatuses.filter((s) => s.terminal).map((s) => s.id)
|
|
7457
7461
|
);
|
|
7458
|
-
const hasCustomTransitions =
|
|
7459
|
-
const effectiveTransitions = hasCustomTransitions ?
|
|
7462
|
+
const hasCustomTransitions = sc.transitions.length > 0;
|
|
7463
|
+
const effectiveTransitions = hasCustomTransitions ? sc.transitions : Array.from(DEFAULT_TRANSITION_TABLE.entries()).map(([key, to]) => {
|
|
7460
7464
|
const [from, command] = key.split(":");
|
|
7461
7465
|
return { from, command, to };
|
|
7462
7466
|
});
|
|
7463
|
-
const accepted = acceptFactDeclarations(normalizeFactDeclarations(
|
|
7467
|
+
const accepted = acceptFactDeclarations(normalizeFactDeclarations(sc.facts ?? null));
|
|
7464
7468
|
_cachedConfig = {
|
|
7465
7469
|
custom: true,
|
|
7466
|
-
statuses:
|
|
7467
|
-
order:
|
|
7470
|
+
statuses: effectiveStatuses,
|
|
7471
|
+
order: effectiveOrder,
|
|
7468
7472
|
transitions: effectiveTransitions,
|
|
7469
7473
|
transitionTable: buildTransitionTable(effectiveTransitions),
|
|
7470
7474
|
terminalStatuses: terminalSet.size > 0 ? terminalSet : /* @__PURE__ */ new Set(["completed", "failed"]),
|
|
7471
|
-
derive:
|
|
7472
|
-
facts:
|
|
7475
|
+
derive: sc.derive ?? null,
|
|
7476
|
+
facts: sc.facts ?? null,
|
|
7473
7477
|
factDeclarations: accepted,
|
|
7474
7478
|
deriveRegistry: buildDeriveRegistry(accepted),
|
|
7475
7479
|
queryRegistry: buildQueryRegistry(accepted)
|
|
@@ -8633,7 +8637,7 @@ async function buildDerivedDetail(assignment, assignmentDir, projectDir) {
|
|
|
8633
8637
|
try {
|
|
8634
8638
|
const { computeFactsDetailed: computeFactsDetailed2 } = await Promise.resolve().then(() => (init_facts(), facts_exports));
|
|
8635
8639
|
const { deriveDimensions: deriveDimensions2 } = await Promise.resolve().then(() => (init_derive(), derive_exports));
|
|
8636
|
-
const { DEFAULT_DERIVE_CONFIG:
|
|
8640
|
+
const { DEFAULT_DERIVE_CONFIG: DEFAULT_DERIVE_CONFIG3 } = await Promise.resolve().then(() => (init_config2(), config_exports));
|
|
8637
8641
|
const { facts, attestations } = await computeFactsDetailed2({
|
|
8638
8642
|
assignmentDir,
|
|
8639
8643
|
frontmatter: {
|
|
@@ -8648,7 +8652,7 @@ async function buildDerivedDetail(assignment, assignmentDir, projectDir) {
|
|
|
8648
8652
|
});
|
|
8649
8653
|
const dims = deriveDimensions2({
|
|
8650
8654
|
facts,
|
|
8651
|
-
derive: config.derive ??
|
|
8655
|
+
derive: config.derive ?? DEFAULT_DERIVE_CONFIG3,
|
|
8652
8656
|
currentStatus: assignment.status,
|
|
8653
8657
|
terminalStatuses: config.terminalStatuses,
|
|
8654
8658
|
knownStatusIds: new Set(config.statuses.map((s) => s.id)),
|
|
@@ -11221,7 +11225,11 @@ var SORT_FIELDS = [
|
|
|
11221
11225
|
"assignee",
|
|
11222
11226
|
"dependencies",
|
|
11223
11227
|
"created",
|
|
11224
|
-
"updated"
|
|
11228
|
+
"updated",
|
|
11229
|
+
"started",
|
|
11230
|
+
"lastActivity",
|
|
11231
|
+
"projectName",
|
|
11232
|
+
"agentName"
|
|
11225
11233
|
];
|
|
11226
11234
|
var SORT_DIRECTIONS = ["asc", "desc"];
|
|
11227
11235
|
var DENSITIES = ["comfortable", "compact"];
|
|
@@ -11234,7 +11242,7 @@ var GROUPINGS = [
|
|
|
11234
11242
|
"project"
|
|
11235
11243
|
];
|
|
11236
11244
|
var ACTIVITIES = ["all", "stale", "fresh"];
|
|
11237
|
-
var DATE_RANGE_FIELDS = ["created", "updated"];
|
|
11245
|
+
var DATE_RANGE_FIELDS = ["created", "updated", "started"];
|
|
11238
11246
|
var DATE_RANGE_PRESETS = [
|
|
11239
11247
|
"last_24h",
|
|
11240
11248
|
"last_7d",
|
|
@@ -11483,6 +11491,7 @@ function makeSeededView(id, name, filterOverrides) {
|
|
|
11483
11491
|
id,
|
|
11484
11492
|
name,
|
|
11485
11493
|
workspace: null,
|
|
11494
|
+
entityType: "assignment",
|
|
11486
11495
|
config: {
|
|
11487
11496
|
viewMode: "list",
|
|
11488
11497
|
filters: { ...DEFAULT_FILTERS, ...filterOverrides },
|
|
@@ -11520,7 +11529,13 @@ function isWidgetConfig(value) {
|
|
|
11520
11529
|
if (obj.kind === "saved-view") {
|
|
11521
11530
|
return typeof obj.viewId === "string" && obj.viewId.length > 0;
|
|
11522
11531
|
}
|
|
11523
|
-
|
|
11532
|
+
if (obj.kind === "agent-sessions") {
|
|
11533
|
+
if (obj.viewId !== void 0) {
|
|
11534
|
+
return typeof obj.viewId === "string" && obj.viewId.length > 0;
|
|
11535
|
+
}
|
|
11536
|
+
return true;
|
|
11537
|
+
}
|
|
11538
|
+
return obj.kind === "inventories";
|
|
11524
11539
|
}
|
|
11525
11540
|
function isListSectionVisibility(value) {
|
|
11526
11541
|
if (!value || typeof value !== "object") return false;
|
|
@@ -11557,6 +11572,9 @@ function isSavedViewConfig(value) {
|
|
|
11557
11572
|
function isSavedView(value) {
|
|
11558
11573
|
if (!value || typeof value !== "object") return false;
|
|
11559
11574
|
const obj = value;
|
|
11575
|
+
if (obj.entityType !== void 0 && obj.entityType !== "assignment" && obj.entityType !== "session") {
|
|
11576
|
+
return false;
|
|
11577
|
+
}
|
|
11560
11578
|
return typeof obj.id === "string" && obj.id.length > 0 && typeof obj.name === "string" && (obj.workspace === null || typeof obj.workspace === "string") && isSavedViewConfig(obj.config) && typeof obj.createdAt === "string" && typeof obj.updatedAt === "string";
|
|
11561
11579
|
}
|
|
11562
11580
|
function isDashboardSlot(value) {
|
|
@@ -11651,6 +11669,8 @@ function createSavedView(file, input, now = () => (/* @__PURE__ */ new Date()).t
|
|
|
11651
11669
|
id: randomUUID(),
|
|
11652
11670
|
name: input.name,
|
|
11653
11671
|
workspace: input.workspace,
|
|
11672
|
+
// Only persist entityType when explicitly a session view; absent === assignment.
|
|
11673
|
+
...input.entityType === "session" ? { entityType: "session" } : {},
|
|
11654
11674
|
config: input.config,
|
|
11655
11675
|
createdAt: ts,
|
|
11656
11676
|
updatedAt: ts
|
|
@@ -11749,12 +11769,16 @@ function validateCreateBody(body) {
|
|
|
11749
11769
|
if (!isSavedViewConfig(obj.config)) {
|
|
11750
11770
|
return { ok: false, error: "config must be a valid SavedViewConfig" };
|
|
11751
11771
|
}
|
|
11772
|
+
if (obj.entityType !== void 0 && obj.entityType !== "assignment" && obj.entityType !== "session") {
|
|
11773
|
+
return { ok: false, error: "entityType must be 'assignment' or 'session'" };
|
|
11774
|
+
}
|
|
11752
11775
|
return {
|
|
11753
11776
|
ok: true,
|
|
11754
11777
|
value: {
|
|
11755
11778
|
name: obj.name.trim(),
|
|
11756
11779
|
workspace: obj.workspace,
|
|
11757
|
-
config: obj.config
|
|
11780
|
+
config: obj.config,
|
|
11781
|
+
...obj.entityType !== void 0 ? { entityType: obj.entityType } : {}
|
|
11758
11782
|
}
|
|
11759
11783
|
};
|
|
11760
11784
|
}
|
|
@@ -16692,7 +16716,9 @@ function createWorkspaceVisibilityConfigRouter() {
|
|
|
16692
16716
|
|
|
16693
16717
|
// src/dashboard/api-status-config.ts
|
|
16694
16718
|
init_config2();
|
|
16719
|
+
init_fact_registry();
|
|
16695
16720
|
init_api();
|
|
16721
|
+
init_derive();
|
|
16696
16722
|
import { Router as Router9 } from "express";
|
|
16697
16723
|
|
|
16698
16724
|
// src/utils/status-config-resolution.ts
|
|
@@ -17069,7 +17095,8 @@ function createStatusConfigRouter(projectsDir, assignmentsDir2) {
|
|
|
17069
17095
|
order: config.order,
|
|
17070
17096
|
transitions: config.transitions,
|
|
17071
17097
|
custom: config.custom,
|
|
17072
|
-
factDeclarations: config.factDeclarations
|
|
17098
|
+
factDeclarations: config.factDeclarations,
|
|
17099
|
+
rawFacts: config.facts ?? []
|
|
17073
17100
|
});
|
|
17074
17101
|
} catch (error) {
|
|
17075
17102
|
console.error("Error getting status config:", error);
|
|
@@ -17093,8 +17120,27 @@ function createStatusConfigRouter(projectsDir, assignmentsDir2) {
|
|
|
17093
17120
|
});
|
|
17094
17121
|
router.post("/", async (req, res) => {
|
|
17095
17122
|
try {
|
|
17096
|
-
const {
|
|
17097
|
-
|
|
17123
|
+
const {
|
|
17124
|
+
statuses,
|
|
17125
|
+
order,
|
|
17126
|
+
transitions,
|
|
17127
|
+
facts: bodyFacts,
|
|
17128
|
+
factRemovalAcks,
|
|
17129
|
+
resolutions: rawResolutions
|
|
17130
|
+
} = req.body ?? {};
|
|
17131
|
+
const currentConfig = await getStatusConfig();
|
|
17132
|
+
const hasFacts = bodyFacts !== void 0;
|
|
17133
|
+
const hasStatuses = statuses !== void 0;
|
|
17134
|
+
const hasOrder = order !== void 0;
|
|
17135
|
+
const hasTransitions = transitions !== void 0;
|
|
17136
|
+
let effectiveStatuses = statuses;
|
|
17137
|
+
let effectiveOrder = order;
|
|
17138
|
+
let effectiveTransitions = transitions;
|
|
17139
|
+
if (hasFacts && !hasStatuses && !hasOrder && !hasTransitions) {
|
|
17140
|
+
effectiveStatuses = currentConfig.statuses;
|
|
17141
|
+
effectiveOrder = currentConfig.order;
|
|
17142
|
+
effectiveTransitions = currentConfig.transitions;
|
|
17143
|
+
} else if (!Array.isArray(effectiveStatuses) || !Array.isArray(effectiveOrder) || !Array.isArray(effectiveTransitions)) {
|
|
17098
17144
|
res.status(400).json({ error: "malformed-statuses", message: "Request body must include statuses, order, and transitions arrays" });
|
|
17099
17145
|
return;
|
|
17100
17146
|
}
|
|
@@ -17108,10 +17154,9 @@ function createStatusConfigRouter(projectsDir, assignmentsDir2) {
|
|
|
17108
17154
|
return;
|
|
17109
17155
|
}
|
|
17110
17156
|
const resolutions = parsed.resolutions;
|
|
17111
|
-
const currentConfig = await getStatusConfig();
|
|
17112
17157
|
const oldIds = new Set(currentConfig.statuses.map((s) => s.id));
|
|
17113
17158
|
const newIds = /* @__PURE__ */ new Set();
|
|
17114
|
-
for (const s of
|
|
17159
|
+
for (const s of effectiveStatuses) {
|
|
17115
17160
|
if (s && typeof s === "object" && isString(s.id)) {
|
|
17116
17161
|
newIds.add(s.id);
|
|
17117
17162
|
}
|
|
@@ -17192,13 +17237,83 @@ function createStatusConfigRouter(projectsDir, assignmentsDir2) {
|
|
|
17192
17237
|
}
|
|
17193
17238
|
throw err;
|
|
17194
17239
|
}
|
|
17240
|
+
let factsToWrite = currentConfig.facts ?? null;
|
|
17241
|
+
if (hasFacts) {
|
|
17242
|
+
const shapedFacts = [];
|
|
17243
|
+
if (!Array.isArray(bodyFacts)) {
|
|
17244
|
+
res.status(400).json({ error: "malformed-facts", message: "facts must be an array" });
|
|
17245
|
+
return;
|
|
17246
|
+
}
|
|
17247
|
+
for (let i = 0; i < bodyFacts.length; i++) {
|
|
17248
|
+
const row = bodyFacts[i];
|
|
17249
|
+
if (!row || typeof row !== "object") {
|
|
17250
|
+
res.status(400).json({ error: "malformed-facts", message: `facts[${i}] must be an object` });
|
|
17251
|
+
return;
|
|
17252
|
+
}
|
|
17253
|
+
const name = row.name;
|
|
17254
|
+
const type = row.type;
|
|
17255
|
+
if (typeof name !== "string" || typeof type !== "string") {
|
|
17256
|
+
res.status(400).json({ error: "malformed-facts", message: `facts[${i}] must have name and type strings` });
|
|
17257
|
+
return;
|
|
17258
|
+
}
|
|
17259
|
+
const binds = row.binds;
|
|
17260
|
+
const normalizedBinds = binds === void 0 ? null : binds === null ? null : typeof binds === "string" ? binds : null;
|
|
17261
|
+
shapedFacts.push({ name, type, binds: normalizedBinds });
|
|
17262
|
+
}
|
|
17263
|
+
const problems = validateFactDeclarations(shapedFacts);
|
|
17264
|
+
if (problems.length > 0) {
|
|
17265
|
+
res.status(400).json({ error: "invalid-facts", problems });
|
|
17266
|
+
return;
|
|
17267
|
+
}
|
|
17268
|
+
const currentNames = new Set((currentConfig.facts ?? []).map((f) => f.name));
|
|
17269
|
+
const incomingNames = new Set(shapedFacts.map((f) => f.name));
|
|
17270
|
+
const removedNames = [];
|
|
17271
|
+
for (const name of currentNames) {
|
|
17272
|
+
if (!incomingNames.has(name)) removedNames.push(name);
|
|
17273
|
+
}
|
|
17274
|
+
const acks = new Set(Array.isArray(factRemovalAcks) ? factRemovalAcks.map((x) => String(x)) : []);
|
|
17275
|
+
const unresolvedRefs = [];
|
|
17276
|
+
const deriveConfig = currentConfig.derive ?? null;
|
|
17277
|
+
if (deriveConfig !== null && removedNames.length > 0) {
|
|
17278
|
+
const acceptedAll = acceptFactDeclarations(normalizeFactDeclarations(currentConfig.facts));
|
|
17279
|
+
const fullRegistry = buildDeriveRegistry(acceptedAll);
|
|
17280
|
+
for (const removedName of removedNames) {
|
|
17281
|
+
if (acks.has(removedName)) continue;
|
|
17282
|
+
const acceptedWithout = acceptedAll.filter((d) => d.name !== removedName);
|
|
17283
|
+
const withoutRegistry = buildDeriveRegistry(acceptedWithout);
|
|
17284
|
+
for (let i = 0; i < deriveConfig.phaseLadder.length; i++) {
|
|
17285
|
+
const rung = deriveConfig.phaseLadder[i];
|
|
17286
|
+
if (rung.when === "*") continue;
|
|
17287
|
+
const before = validateDeriveCondition(rung.when, fullRegistry);
|
|
17288
|
+
const after = validateDeriveCondition(rung.when, withoutRegistry);
|
|
17289
|
+
if (before === null && after !== null) {
|
|
17290
|
+
unresolvedRefs.push({ factName: removedName, location: `phaseLadder[${i}]`, when: rung.when });
|
|
17291
|
+
}
|
|
17292
|
+
}
|
|
17293
|
+
for (let i = 0; i < deriveConfig.disposition.length; i++) {
|
|
17294
|
+
const rule = deriveConfig.disposition[i];
|
|
17295
|
+
if (rule.when === null) continue;
|
|
17296
|
+
const before = validateDeriveCondition(rule.when, fullRegistry);
|
|
17297
|
+
const after = validateDeriveCondition(rule.when, withoutRegistry);
|
|
17298
|
+
if (before === null && after !== null) {
|
|
17299
|
+
unresolvedRefs.push({ factName: removedName, location: `disposition[${i}]`, when: rule.when });
|
|
17300
|
+
}
|
|
17301
|
+
}
|
|
17302
|
+
}
|
|
17303
|
+
}
|
|
17304
|
+
if (unresolvedRefs.length > 0) {
|
|
17305
|
+
res.status(409).json({ error: "unresolved-fact-references", references: unresolvedRefs });
|
|
17306
|
+
return;
|
|
17307
|
+
}
|
|
17308
|
+
factsToWrite = shapedFacts;
|
|
17309
|
+
}
|
|
17195
17310
|
try {
|
|
17196
17311
|
await writeStatusConfig({
|
|
17197
|
-
statuses,
|
|
17198
|
-
order,
|
|
17199
|
-
transitions,
|
|
17312
|
+
statuses: effectiveStatuses,
|
|
17313
|
+
order: effectiveOrder,
|
|
17314
|
+
transitions: effectiveTransitions,
|
|
17200
17315
|
derive: currentConfig.derive ?? null,
|
|
17201
|
-
facts:
|
|
17316
|
+
facts: factsToWrite
|
|
17202
17317
|
});
|
|
17203
17318
|
} catch (err) {
|
|
17204
17319
|
console.error("Error saving status config after applying resolutions:", err);
|