wicked-crew 0.7.29 → 0.7.30
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 +4 -1
- package/dist/api/chat-scope.d.ts.map +1 -1
- package/dist/api/chat-scope.js +5 -1
- package/dist/api/chat-scope.js.map +1 -1
- package/dist/api/governance-health.d.ts +25 -17
- package/dist/api/governance-health.d.ts.map +1 -1
- package/dist/api/governance-health.js +40 -9
- package/dist/api/governance-health.js.map +1 -1
- package/dist/api/routes.d.ts +22 -0
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +88 -34
- package/dist/api/routes.js.map +1 -1
- package/dist/api/seat-health.d.ts +38 -0
- package/dist/api/seat-health.d.ts.map +1 -1
- package/dist/api/seat-health.js +63 -0
- package/dist/api/seat-health.js.map +1 -1
- package/dist/api/seat-standing.d.ts +101 -0
- package/dist/api/seat-standing.d.ts.map +1 -0
- package/dist/api/seat-standing.js +138 -0
- package/dist/api/seat-standing.js.map +1 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +17 -0
- package/dist/api/server.js.map +1 -1
- package/dist/cli/index.js +37 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adapter.d.ts +10 -0
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +26 -1
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/bridge-path.d.ts +21 -0
- package/dist/core/bridge-path.d.ts.map +1 -1
- package/dist/core/bridge-path.js +37 -0
- package/dist/core/bridge-path.js.map +1 -1
- package/dist/core/bridge-reaper.d.ts.map +1 -1
- package/dist/core/bridge-reaper.js +7 -3
- package/dist/core/bridge-reaper.js.map +1 -1
- package/dist/core/governance-store.d.ts +22 -0
- package/dist/core/governance-store.d.ts.map +1 -1
- package/dist/core/governance-store.js +7 -0
- package/dist/core/governance-store.js.map +1 -1
- package/dist/interactive/bridge-pool.d.ts +29 -24
- package/dist/interactive/bridge-pool.d.ts.map +1 -1
- package/dist/interactive/bridge-pool.js +65 -3
- package/dist/interactive/bridge-pool.js.map +1 -1
- package/dist/interactive/chat-events.d.ts.map +1 -1
- package/dist/interactive/chat-events.js +5 -2
- package/dist/interactive/chat-events.js.map +1 -1
- package/dist/interactive/council-outcome.d.ts +28 -0
- package/dist/interactive/council-outcome.d.ts.map +1 -0
- package/dist/interactive/council-outcome.js +57 -0
- package/dist/interactive/council-outcome.js.map +1 -0
- package/dist/interactive/demo-events.d.ts.map +1 -1
- package/dist/interactive/demo-events.js +5 -2
- package/dist/interactive/demo-events.js.map +1 -1
- package/dist/interactive/doc-delete-routes.d.ts.map +1 -1
- package/dist/interactive/doc-delete-routes.js +3 -2
- package/dist/interactive/doc-delete-routes.js.map +1 -1
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +5 -2
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +5 -2
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/projects/auto-refresh.d.ts +54 -0
- package/dist/projects/auto-refresh.d.ts.map +1 -0
- package/dist/projects/auto-refresh.js +76 -0
- package/dist/projects/auto-refresh.js.map +1 -0
- package/dist/projects/graph.d.ts +15 -2
- package/dist/projects/graph.d.ts.map +1 -1
- package/dist/projects/graph.js +18 -8
- package/dist/projects/graph.js.map +1 -1
- package/dist/projects/routes.d.ts.map +1 -1
- package/dist/projects/routes.js +12 -2
- package/dist/projects/routes.js.map +1 -1
- package/dist/projects/state-home.d.ts +6 -0
- package/dist/projects/state-home.d.ts.map +1 -1
- package/dist/projects/state-home.js +9 -1
- package/dist/projects/state-home.js.map +1 -1
- package/dist/skills/guards.d.ts +17 -6
- package/dist/skills/guards.d.ts.map +1 -1
- package/dist/skills/guards.js +42 -15
- package/dist/skills/guards.js.map +1 -1
- package/dist/skills/refs.d.ts +181 -17
- package/dist/skills/refs.d.ts.map +1 -1
- package/dist/skills/refs.js +345 -26
- package/dist/skills/refs.js.map +1 -1
- package/dist/skills/store.d.ts +22 -1
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/skills/store.js +161 -23
- package/dist/skills/store.js.map +1 -1
- package/dist/studio/assets/index-CWUS9Ump.js +542 -0
- package/dist/studio/assets/{index-CK1uJWs2.css → index-_ydd-jKd.css} +1 -1
- package/dist/studio/index.html +2 -2
- package/dist/studio/testid-inventory.json +359 -4
- package/endpoint-manifest.json +8 -3
- package/package.json +4 -4
- package/dist/studio/assets/index-CeJTutxP.js +0 -540
package/dist/api/routes.js
CHANGED
|
@@ -17,6 +17,7 @@ import { execCapped, ExecOutputTooLarge } from '../core/exec.js';
|
|
|
17
17
|
import { callEstateTool, EstateMcpError } from '../core/estate-mcp-client.js';
|
|
18
18
|
import { SeatHealthTracker } from './seat-health.js';
|
|
19
19
|
import { applyWorkerConfigRoot, signedInHeuristic } from './seat-signin.js';
|
|
20
|
+
import { chatSeatAdmission, seatStanding } from './seat-standing.js';
|
|
20
21
|
import { ChatScopeIndex, chatScopeDeps, prepareChatScratch, removeChatScratch, resolveChatScope, } from './chat-scope.js';
|
|
21
22
|
import { allowedRootsFor, isInsideRoot, openWithSystemDefault } from './open-path.js';
|
|
22
23
|
import { InvalidDiffBaseError, NotARegularFileError, UnresolvableDiffBaseError, readFileCapped, worktreeDiff, } from './run-files.js';
|
|
@@ -73,13 +74,6 @@ const STATUS_ORDER = {
|
|
|
73
74
|
function sortActionableFirst(views) {
|
|
74
75
|
return [...views].sort((a, b) => (STATUS_ORDER[a.session.status] ?? 9) - (STATUS_ORDER[b.session.status] ?? 9));
|
|
75
76
|
}
|
|
76
|
-
/**
|
|
77
|
-
* `codeGraphDb(repo)` for a repo surface, or `null` after answering **503** — a CURRENT engine that
|
|
78
|
-
* resolved no repo-graph root (`code_graph_root_unresolvable`, wicked-core#406) is a daemon-
|
|
79
|
-
* environment fault, not a bad request and not Fastify's generic 500. The mapping is the shared
|
|
80
|
-
* `codeGraphErrorStatus`; anything it does not classify rethrows unchanged (the stale-addon error
|
|
81
|
-
* keeps its pre-existing shape here).
|
|
82
|
-
*/
|
|
83
77
|
function codeGraphDbOr503(repo, reply) {
|
|
84
78
|
try {
|
|
85
79
|
return codeGraphDb(repo);
|
|
@@ -707,16 +701,29 @@ runtime = {}) {
|
|
|
707
701
|
// gains `signed_in`: the cheap file/env presence heuristic, computed against the LIVE
|
|
708
702
|
// `WICKED_WORKER_HOME` env — the same value the engine reads at the next worker spawn, kept
|
|
709
703
|
// current by `applyWorkerConfigRoot` at boot and on every settings change.
|
|
710
|
-
|
|
704
|
+
//
|
|
705
|
+
// Each seat ALSO carries its STANDING (F-2R2-009): `auth` re-reads `signed_in` for what it means
|
|
706
|
+
// (a `signed_out` codex is benched on its first ballot; a `not_required` opencode answers on its
|
|
707
|
+
// free tier), and `council_eligible` says what a council would do with the seat as far as the
|
|
708
|
+
// daemon can tell. `POST /chats` seats its defaults through the SAME standing, so the roster and
|
|
709
|
+
// the chat never disagree about a seat.
|
|
710
|
+
const rosterWithStanding = () => {
|
|
711
711
|
const workerRoot = process.env['WICKED_WORKER_HOME'];
|
|
712
|
-
return {
|
|
713
|
-
|
|
712
|
+
return CoreAdapter.roster().map((seat) => {
|
|
713
|
+
const key = String(seat.key);
|
|
714
|
+
const health = seatHealth.healthFor(key);
|
|
715
|
+
const signed = signedIn(key, workerRoot === '' ? undefined : workerRoot);
|
|
716
|
+
return {
|
|
714
717
|
...seat,
|
|
715
|
-
health
|
|
716
|
-
signed_in:
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
718
|
+
health,
|
|
719
|
+
signed_in: signed,
|
|
720
|
+
// The bench is THIS daemon's council evidence (councilSeatFailed, bounded window) — the
|
|
721
|
+
// prediction learns from what the engine actually did with the seat (#533 review, F-1).
|
|
722
|
+
...seatStanding(seat, signed, health, seatHealth.councilBenchFor(key)),
|
|
723
|
+
};
|
|
724
|
+
});
|
|
725
|
+
};
|
|
726
|
+
app.get(`${V}/roster`, async () => ({ roster: rosterWithStanding() }));
|
|
720
727
|
// Open a file/folder with the OS default application (crew#273) — the studio Files tab's
|
|
721
728
|
// click-to-open. The open MUST happen daemon-side (the SPA cannot spawn a process), which is
|
|
722
729
|
// why the path is validated first: absolute, and inside one of the caller-visible roots — the
|
|
@@ -1559,26 +1566,43 @@ runtime = {}) {
|
|
|
1559
1566
|
.code(500)
|
|
1560
1567
|
.send({ error: `cannot prepare the chat's scratch root ${scope.cwd}: ${message(err)}` });
|
|
1561
1568
|
}
|
|
1562
|
-
// The
|
|
1563
|
-
//
|
|
1564
|
-
//
|
|
1565
|
-
//
|
|
1566
|
-
//
|
|
1567
|
-
// with the
|
|
1569
|
+
// The DEFAULT seats are the roster seats the daemon's own admission admits (F-2R2-007,
|
|
1570
|
+
// F-2R2-009): the seat's auth standing (a signed-out seat is refused up front, with the
|
|
1571
|
+
// reason, instead of failing its first turn — the same predicate `GET /roster` reports as
|
|
1572
|
+
// `council_eligible`) and, for a SCOPED chat, the engine's rule restated (only a seat whose
|
|
1573
|
+
// ACP adapter asks permissions or whose record arms the kernel write floor can be held to
|
|
1574
|
+
// read-only roots — with the default roster that is claude and opencode). Every seat dropped
|
|
1575
|
+
// here is NAMED on the response (`refused`) and in the thread (`chatSeatRefused`), so a
|
|
1576
|
+
// person can see why pi is missing. Explicit `clis` are passed through as asked; the engine
|
|
1577
|
+
// refuses per seat with its reason, which is copied into `refused` too.
|
|
1568
1578
|
const scoped = scope.kind !== 'none';
|
|
1569
|
-
const
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1579
|
+
const refused = [];
|
|
1580
|
+
let clis;
|
|
1581
|
+
if (b.clis !== undefined) {
|
|
1582
|
+
clis = b.clis;
|
|
1583
|
+
}
|
|
1584
|
+
else {
|
|
1585
|
+
clis = [];
|
|
1586
|
+
for (const seat of rosterWithStanding()) {
|
|
1587
|
+
const key = String(seat.key);
|
|
1588
|
+
const admission = chatSeatAdmission(seat, seat.auth ?? 'unknown', scoped);
|
|
1589
|
+
if (admission.ok)
|
|
1590
|
+
clis.push(key);
|
|
1591
|
+
else
|
|
1592
|
+
refused.push({ cliKey: key, reason: admission.reason });
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1575
1595
|
if (clis.length === 0) {
|
|
1576
1596
|
chatScopes.release(chatId, token);
|
|
1577
1597
|
removeChatScratch(scope.cwd, chatScopes.base);
|
|
1578
1598
|
return reply.code(409).send({
|
|
1579
|
-
error:
|
|
1580
|
-
'
|
|
1581
|
-
|
|
1599
|
+
error: (scoped
|
|
1600
|
+
? 'no seat in the roster can be held to a scoped chat (an ACP adapter admitted to input ' +
|
|
1601
|
+
'governance, or `os_sandbox = true` on its [cli.acp] record) and take a turn; open the ' +
|
|
1602
|
+
'chat unscoped, sign a seat in, or name seats with `clis`'
|
|
1603
|
+
: 'no seat in the roster can take a turn (every seat is signed out); sign a seat in from ' +
|
|
1604
|
+
'the System page, or name seats with `clis`') + ' — see refused',
|
|
1605
|
+
refused,
|
|
1582
1606
|
});
|
|
1583
1607
|
}
|
|
1584
1608
|
try {
|
|
@@ -1586,6 +1610,11 @@ runtime = {}) {
|
|
|
1586
1610
|
codeGraphDb: engine.codeGraphDb,
|
|
1587
1611
|
readRoots: engine.readRoots,
|
|
1588
1612
|
});
|
|
1613
|
+
// A REQUESTED seat the engine refused joins the same list, with the engine's reason.
|
|
1614
|
+
for (const s of seats) {
|
|
1615
|
+
if (!s.ok)
|
|
1616
|
+
refused.push({ cliKey: s.cliKey, reason: s.error ?? 'the engine refused the seat' });
|
|
1617
|
+
}
|
|
1589
1618
|
// Nothing warmed (independent review, W1): the engine holds no pool row and has dropped the
|
|
1590
1619
|
// scope itself (no `chatClosed` will come) — report the PER-SEAT reasons, never an
|
|
1591
1620
|
// engine-version guess; the root goes, the id is free again.
|
|
@@ -1595,6 +1624,7 @@ runtime = {}) {
|
|
|
1595
1624
|
return reply.code(409).send({
|
|
1596
1625
|
error: `chat ${chatId}: no seat warmed (${seats.length} failed) — see seats`,
|
|
1597
1626
|
seats,
|
|
1627
|
+
refused,
|
|
1598
1628
|
});
|
|
1599
1629
|
}
|
|
1600
1630
|
// Honest scope (Copilot, #518): a SCOPED chat is a promise — the roots are read-only, the
|
|
@@ -1663,10 +1693,23 @@ runtime = {}) {
|
|
|
1663
1693
|
error: `chat ${chatId} was closed while it was being opened; open it again`,
|
|
1664
1694
|
});
|
|
1665
1695
|
}
|
|
1696
|
+
// The thread learns of every refused seat the way it learns of everything else — a frame
|
|
1697
|
+
// on /ws — AFTER the scope is published, so a reader never sees a refusal for a chat it
|
|
1698
|
+
// cannot yet look up.
|
|
1699
|
+
for (const r of refused) {
|
|
1700
|
+
runtime.broadcast?.({
|
|
1701
|
+
type: 'chatSeatRefused',
|
|
1702
|
+
chat: chatId,
|
|
1703
|
+
cliKey: r.cliKey,
|
|
1704
|
+
reason: r.reason,
|
|
1705
|
+
...(b.projectId !== undefined ? { project_id: b.projectId } : {}),
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1666
1708
|
return reply.code(201).send({
|
|
1667
1709
|
chatId,
|
|
1668
1710
|
seats,
|
|
1669
1711
|
scope,
|
|
1712
|
+
refused,
|
|
1670
1713
|
...(projectAttachError !== undefined ? { projectAttachError } : {}),
|
|
1671
1714
|
});
|
|
1672
1715
|
}
|
|
@@ -2791,7 +2834,7 @@ runtime = {}) {
|
|
|
2791
2834
|
return reply.code(404).send({ error: 'Requirement not found' });
|
|
2792
2835
|
return { requirement: detail };
|
|
2793
2836
|
});
|
|
2794
|
-
app.get(`${V}/repos/:id/graph`, async (req, reply) => {
|
|
2837
|
+
app.get(`${V}/repos/:id/graph`, { config: { manifest: { responseType: 'RepoGraphResponse', statusCodes: [200, 404, 500, 503] } } }, async (req, reply) => {
|
|
2795
2838
|
const { id } = req.params;
|
|
2796
2839
|
const repos = await adapter.listRepos();
|
|
2797
2840
|
const repo = repos.find((r) => r.id === id);
|
|
@@ -2801,7 +2844,17 @@ runtime = {}) {
|
|
|
2801
2844
|
if (dbPath === null)
|
|
2802
2845
|
return reply;
|
|
2803
2846
|
if (!existsSync(dbPath)) {
|
|
2804
|
-
|
|
2847
|
+
// `graph: null` alone cannot tell "not indexed" from "empty" (F-2R2-005): say WHY, with the
|
|
2848
|
+
// same finding text the repos wire carries when the engine has one.
|
|
2849
|
+
const finding = (repo.findings ?? []).find((f) => f.code === 'in_tree_code_graph_ignored' || f.code === 'code_graph_root_unresolvable');
|
|
2850
|
+
const unbuilt = {
|
|
2851
|
+
graph: null,
|
|
2852
|
+
reason: finding?.message ??
|
|
2853
|
+
`no code graph has been built for '${repo.name}' yet (nothing at ${dbPath}) — run onboarding ` +
|
|
2854
|
+
`(POST /api/v1/repos/${repo.id}/onboard) to index it`,
|
|
2855
|
+
...(finding !== undefined ? { finding } : {}),
|
|
2856
|
+
};
|
|
2857
|
+
return reply.send(unbuilt);
|
|
2805
2858
|
}
|
|
2806
2859
|
try {
|
|
2807
2860
|
const settings = await adapter.getSettings();
|
|
@@ -2822,13 +2875,14 @@ runtime = {}) {
|
|
|
2822
2875
|
});
|
|
2823
2876
|
const raw = JSON.parse(stdout);
|
|
2824
2877
|
const fileCount = new Set(raw.nodes.map((n) => n.file)).size;
|
|
2825
|
-
|
|
2878
|
+
const built = {
|
|
2826
2879
|
graph: {
|
|
2827
2880
|
nodes: raw.nodes,
|
|
2828
2881
|
edges: raw.edges,
|
|
2829
2882
|
stats: { nodeCount: raw.nodes.length, edgeCount: raw.edges.length, fileCount },
|
|
2830
2883
|
},
|
|
2831
|
-
}
|
|
2884
|
+
};
|
|
2885
|
+
return reply.send(built);
|
|
2832
2886
|
}
|
|
2833
2887
|
catch (err) {
|
|
2834
2888
|
return reply.code(500).send({ error: message(err) });
|