@norman-else/dsh-claude 0.1.11 → 0.1.12
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/lib/client.js +83 -3
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +13 -8
- package/lib/index.mjs +17 -21
- package/lib/index.mjs.map +1 -1
- package/lib/{presenters-BE6LPw2m.mjs → presenters-CtgkpzZo.mjs} +10 -57
- package/lib/presenters-CtgkpzZo.mjs.map +1 -0
- package/lib/preset-route.mjs +2 -5
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +4 -1
- package/lib/presenters-BE6LPw2m.mjs.map +0 -1
package/lib/client.js
CHANGED
|
@@ -1547,10 +1547,12 @@ window.__ModuleLoader__.load({
|
|
|
1547
1547
|
schemaVersion: 1,
|
|
1548
1548
|
revision: 0,
|
|
1549
1549
|
owned: false,
|
|
1550
|
+
commands: [],
|
|
1550
1551
|
activities: []
|
|
1551
1552
|
};
|
|
1552
1553
|
const POLL_INTERVAL_MS = 2e3;
|
|
1553
1554
|
const MAX_ACTIVITIES = 1e4;
|
|
1555
|
+
const MAX_COMMANDS = 2e3;
|
|
1554
1556
|
function record(value) {
|
|
1555
1557
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
1556
1558
|
}
|
|
@@ -1560,7 +1562,11 @@ window.__ModuleLoader__.load({
|
|
|
1560
1562
|
/** Validate the public route envelope before publishing it to UI components. */
|
|
1561
1563
|
function parseClaudeClientProjection(value) {
|
|
1562
1564
|
const input = record(value);
|
|
1563
|
-
if (input === void 0 || input.schemaVersion !== 1 || !nonNegativeInteger(input.revision) || typeof input.owned !== "boolean" || !Array.isArray(input.activities) || input.activities.length > MAX_ACTIVITIES) throw new Error("invalid Claude sidecar projection");
|
|
1565
|
+
if (input === void 0 || input.schemaVersion !== 1 || !nonNegativeInteger(input.revision) || typeof input.owned !== "boolean" || !Array.isArray(input.commands) || input.commands.length > MAX_COMMANDS || !Array.isArray(input.activities) || input.activities.length > MAX_ACTIVITIES) throw new Error("invalid Claude sidecar projection");
|
|
1566
|
+
for (const item of input.commands) {
|
|
1567
|
+
const command = record(item);
|
|
1568
|
+
if (command === void 0 || typeof command.publicName !== "string" || typeof command.claudeName !== "string" || typeof command.description !== "string" || command.hint !== void 0 && typeof command.hint !== "string" || typeof command.prefixed !== "boolean") throw new Error("invalid Claude command projection");
|
|
1569
|
+
}
|
|
1564
1570
|
for (const item of input.activities) {
|
|
1565
1571
|
const activity = record(item);
|
|
1566
1572
|
if (activity === void 0 || !nonNegativeInteger(activity.turn) || !nonNegativeInteger(activity.step) || !nonNegativeInteger(activity.ordinal) || typeof activity.kind !== "string") throw new Error("invalid Claude sidecar activity");
|
|
@@ -1594,7 +1600,8 @@ window.__ModuleLoader__.load({
|
|
|
1594
1600
|
});
|
|
1595
1601
|
if (!response.ok) throw new Error(`Claude projection request failed (${response.status})`);
|
|
1596
1602
|
const next = parseClaudeClientProjection(await response.json());
|
|
1597
|
-
|
|
1603
|
+
const commandCatalogChanged = JSON.stringify(next.commands) !== JSON.stringify(snapshot.commands);
|
|
1604
|
+
if (next.revision !== snapshot.revision || next.owned !== snapshot.owned || commandCatalogChanged) {
|
|
1598
1605
|
snapshot = next;
|
|
1599
1606
|
for (const listener of [...listeners]) listener();
|
|
1600
1607
|
}
|
|
@@ -1650,6 +1657,76 @@ window.__ModuleLoader__.load({
|
|
|
1650
1657
|
}
|
|
1651
1658
|
};
|
|
1652
1659
|
//#endregion
|
|
1660
|
+
//#region src/client/claude-command-source.ts
|
|
1661
|
+
const SOURCE_NAME = "Claude Code";
|
|
1662
|
+
function commandsFor(store, session) {
|
|
1663
|
+
const projection = store.source(session.sessionId).getSnapshot();
|
|
1664
|
+
return projection.owned ? projection.commands : [];
|
|
1665
|
+
}
|
|
1666
|
+
function findCommand(store, session, publicName) {
|
|
1667
|
+
return commandsFor(store, session).find((command) => command.publicName === publicName);
|
|
1668
|
+
}
|
|
1669
|
+
function claimFor(command) {
|
|
1670
|
+
return {
|
|
1671
|
+
token: `/${command.publicName} `,
|
|
1672
|
+
...command.hint === void 0 ? {} : { hint: command.hint },
|
|
1673
|
+
async submit(args, actx) {
|
|
1674
|
+
const line = `/${command.claudeName}${args.length === 0 ? "" : ` ${args}`}`;
|
|
1675
|
+
try {
|
|
1676
|
+
await actx.conversation.send(line);
|
|
1677
|
+
return { kind: "success" };
|
|
1678
|
+
} catch (error) {
|
|
1679
|
+
return {
|
|
1680
|
+
kind: "error",
|
|
1681
|
+
text: error instanceof Error ? error.message : String(error)
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
function pickCommand(store, pick) {
|
|
1688
|
+
const command = findCommand(store, pick.session, pick.candidate.name);
|
|
1689
|
+
if (command === void 0) return void 0;
|
|
1690
|
+
return { claim: claimFor(command) };
|
|
1691
|
+
}
|
|
1692
|
+
/** Build a client-owned slash source. It never calls command.execute, so
|
|
1693
|
+
* Claude Skill submission creates only the ordinary user-message turn. */
|
|
1694
|
+
function createClaudeCommandSource(store) {
|
|
1695
|
+
return {
|
|
1696
|
+
trigger: "/",
|
|
1697
|
+
name: SOURCE_NAME,
|
|
1698
|
+
order: 10,
|
|
1699
|
+
async candidates(session, request) {
|
|
1700
|
+
if (request.position !== "leading") return [];
|
|
1701
|
+
return commandsFor(store, session).map((command) => ({
|
|
1702
|
+
name: command.publicName,
|
|
1703
|
+
description: command.description,
|
|
1704
|
+
...command.hint === void 0 ? {} : { hint: command.hint }
|
|
1705
|
+
}));
|
|
1706
|
+
},
|
|
1707
|
+
onPick(pick) {
|
|
1708
|
+
return pickCommand(store, pick);
|
|
1709
|
+
},
|
|
1710
|
+
matchSpace(session, token) {
|
|
1711
|
+
if (!token.startsWith("/")) return void 0;
|
|
1712
|
+
const command = findCommand(store, session, token.slice(1));
|
|
1713
|
+
return command === void 0 ? void 0 : { claim: claimFor(command) };
|
|
1714
|
+
},
|
|
1715
|
+
async matchEnter(session, line) {
|
|
1716
|
+
if (!line.startsWith("/")) return void 0;
|
|
1717
|
+
const separator = line.indexOf(" ");
|
|
1718
|
+
const command = findCommand(store, session, line.slice(1, separator === -1 ? void 0 : separator));
|
|
1719
|
+
return command === void 0 ? void 0 : { claim: claimFor(command) };
|
|
1720
|
+
},
|
|
1721
|
+
lexicon(session) {
|
|
1722
|
+
return commandsFor(store, session).map((command) => command.publicName);
|
|
1723
|
+
},
|
|
1724
|
+
subscribeLexicon(session, listener) {
|
|
1725
|
+
return store.source(session.sessionId).subscribe(listener);
|
|
1726
|
+
}
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
//#endregion
|
|
1653
1730
|
//#region src/client/locales.ts
|
|
1654
1731
|
const zh = {
|
|
1655
1732
|
nav: "Claude Code",
|
|
@@ -1826,7 +1903,9 @@ window.__ModuleLoader__.load({
|
|
|
1826
1903
|
"slots",
|
|
1827
1904
|
"locale",
|
|
1828
1905
|
"conversationEvents",
|
|
1829
|
-
"sessions"
|
|
1906
|
+
"sessions",
|
|
1907
|
+
"inputTriggers",
|
|
1908
|
+
"conversation"
|
|
1830
1909
|
];
|
|
1831
1910
|
function apply(ctx) {
|
|
1832
1911
|
const namespace = "settings.claude-code";
|
|
@@ -1836,6 +1915,7 @@ window.__ModuleLoader__.load({
|
|
|
1836
1915
|
}), "dsh-claude: client copy");
|
|
1837
1916
|
const t = ctx.locale.bind(namespace);
|
|
1838
1917
|
const projections = new ClaudeProjectionStore();
|
|
1918
|
+
ctx.effect(() => ctx.inputTriggers.registerSource(createClaudeCommandSource(projections)), "dsh-claude: Claude slash source");
|
|
1839
1919
|
const sessions = ctx.get("sessions");
|
|
1840
1920
|
if (sessions !== void 0) ctx.effect(() => sessions.provide({
|
|
1841
1921
|
hooks: ["claudeProjection"],
|