next-ai-editor 0.1.3 → 0.2.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/dist/AIEditorProvider-CKA2K_g2.js +1428 -0
- package/dist/AIEditorProvider-CKA2K_g2.js.map +1 -0
- package/dist/AIEditorProvider-C_zRSAuV.cjs +1427 -0
- package/dist/AIEditorProvider-C_zRSAuV.cjs.map +1 -0
- package/dist/client/AIEditorProvider.d.ts +1 -33
- package/dist/client/AIEditorProvider.d.ts.map +1 -1
- package/dist/client/components/ChatPanel.d.ts +18 -0
- package/dist/client/components/ChatPanel.d.ts.map +1 -0
- package/dist/client/components/ControlPill.d.ts +8 -0
- package/dist/client/components/ControlPill.d.ts.map +1 -0
- package/dist/client/components/MessageItem.d.ts +7 -0
- package/dist/client/components/MessageItem.d.ts.map +1 -0
- package/dist/client/components/MessageList.d.ts +7 -0
- package/dist/client/components/MessageList.d.ts.map +1 -0
- package/dist/client/components/TaskHistoryPanel.d.ts +10 -0
- package/dist/client/components/TaskHistoryPanel.d.ts.map +1 -0
- package/dist/client/components/index.d.ts +11 -0
- package/dist/client/components/index.d.ts.map +1 -0
- package/dist/client/hooks/index.d.ts +3 -0
- package/dist/client/hooks/index.d.ts.map +1 -0
- package/dist/client/hooks/useChatStream.d.ts +66 -0
- package/dist/client/hooks/useChatStream.d.ts.map +1 -0
- package/dist/client/hooks/useHotReload.d.ts +10 -0
- package/dist/client/hooks/useHotReload.d.ts.map +1 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client.cjs +7 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +8 -2
- package/dist/client.js.map +1 -1
- package/dist/{index-DrmEf13c.js → comments-D3m0RsOO.js} +440 -15
- package/dist/comments-D3m0RsOO.js.map +1 -0
- package/dist/{index-CNJqd4EQ.cjs → comments-Daur80r4.cjs} +426 -1
- package/dist/comments-Daur80r4.cjs.map +1 -0
- package/dist/index.cjs +34 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -15
- package/dist/index.js.map +1 -1
- package/dist/next-ai-editor.css +880 -0
- package/dist/server/agent/sdk-client.d.ts +54 -0
- package/dist/server/agent/sdk-client.d.ts.map +1 -0
- package/dist/server/agent/session-store.d.ts +101 -0
- package/dist/server/agent/session-store.d.ts.map +1 -0
- package/dist/server/handlers/chat.d.ts +6 -0
- package/dist/server/handlers/chat.d.ts.map +1 -0
- package/dist/server/handlers/comments.d.ts +10 -0
- package/dist/server/handlers/comments.d.ts.map +1 -0
- package/dist/server/handlers/index.d.ts +2 -1
- package/dist/server/handlers/index.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server.cjs +27 -26
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +14 -13
- package/dist/shared/comment-types.d.ts +140 -0
- package/dist/shared/comment-types.d.ts.map +1 -0
- package/package.json +13 -4
- package/dist/AIEditorProvider-BGHm2xyU.cjs +0 -2167
- package/dist/AIEditorProvider-BGHm2xyU.cjs.map +0 -1
- package/dist/AIEditorProvider-CxdGjdLL.js +0 -2168
- package/dist/AIEditorProvider-CxdGjdLL.js.map +0 -1
- package/dist/index-CNJqd4EQ.cjs.map +0 -1
- package/dist/index-DrmEf13c.js.map +0 -1
|
@@ -10,6 +10,8 @@ const t = require("@babel/types");
|
|
|
10
10
|
const sourceMap = require("@jridgewell/source-map");
|
|
11
11
|
const pathUtils = require("./path-utils-DYzEWUGy.cjs");
|
|
12
12
|
const crypto = require("crypto");
|
|
13
|
+
const claudeAgentSdk = require("@anthropic-ai/claude-agent-sdk");
|
|
14
|
+
const fs$1 = require("fs");
|
|
13
15
|
function _interopNamespaceDefault(e) {
|
|
14
16
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
15
17
|
if (e) {
|
|
@@ -1533,6 +1535,361 @@ Generate 6-8 initial suggestions:`;
|
|
|
1533
1535
|
return null;
|
|
1534
1536
|
}
|
|
1535
1537
|
}
|
|
1538
|
+
class AIEditorAgent {
|
|
1539
|
+
constructor(session, projectRoot) {
|
|
1540
|
+
this.session = session;
|
|
1541
|
+
this.projectRoot = projectRoot;
|
|
1542
|
+
}
|
|
1543
|
+
/**
|
|
1544
|
+
* Create a new agent instance
|
|
1545
|
+
*/
|
|
1546
|
+
static async create(config) {
|
|
1547
|
+
const sessionOptions = {
|
|
1548
|
+
model: "claude-sonnet-4-5-20250929",
|
|
1549
|
+
// Enable auto-apply for edits without permission prompts
|
|
1550
|
+
permissionMode: "acceptEdits",
|
|
1551
|
+
env: {
|
|
1552
|
+
...process.env,
|
|
1553
|
+
ANTHROPIC_API_KEY: config.apiKey,
|
|
1554
|
+
// Set working directory
|
|
1555
|
+
PWD: config.projectRoot
|
|
1556
|
+
},
|
|
1557
|
+
// Explicitly allow core development tools
|
|
1558
|
+
allowedTools: config.allowedTools || ["Read", "Edit", "Glob", "Grep"],
|
|
1559
|
+
disallowedTools: config.disallowedTools || []
|
|
1560
|
+
};
|
|
1561
|
+
let session;
|
|
1562
|
+
if (config.sessionId) {
|
|
1563
|
+
session = claudeAgentSdk.unstable_v2_resumeSession(config.sessionId, sessionOptions);
|
|
1564
|
+
} else {
|
|
1565
|
+
session = claudeAgentSdk.unstable_v2_createSession(sessionOptions);
|
|
1566
|
+
}
|
|
1567
|
+
return new AIEditorAgent(session, config.projectRoot);
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
* Send a message to the agent and stream responses
|
|
1571
|
+
*/
|
|
1572
|
+
async *sendMessage(message, componentContext) {
|
|
1573
|
+
let fullMessage = `<response_style>
|
|
1574
|
+
KEEP RESPONSES EXTREMELY BRIEF AND STATUS-LIKE.
|
|
1575
|
+
- Use terse status messages: "Reading file.tsx", "Changing color", "Done"
|
|
1576
|
+
- NO conversational language (avoid: "I'll", "Let me", "Sure", "Great", "I can see")
|
|
1577
|
+
- NO explanations unless explicitly asked
|
|
1578
|
+
- State ONLY what you're doing, nothing more
|
|
1579
|
+
- Format: Action + target (e.g., "Updating StatsCard.tsx:24")
|
|
1580
|
+
</response_style>
|
|
1581
|
+
|
|
1582
|
+
`;
|
|
1583
|
+
if (componentContext) {
|
|
1584
|
+
fullMessage += `[Component: ${componentContext.componentName} at ${componentContext.filePath}:${componentContext.lineNumber}]
|
|
1585
|
+
|
|
1586
|
+
`;
|
|
1587
|
+
}
|
|
1588
|
+
fullMessage += message;
|
|
1589
|
+
await this.session.send(fullMessage);
|
|
1590
|
+
for await (const event of this.session.stream()) {
|
|
1591
|
+
yield event;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
/**
|
|
1595
|
+
* Get the session ID
|
|
1596
|
+
*/
|
|
1597
|
+
getSessionId() {
|
|
1598
|
+
return this.session.sessionId;
|
|
1599
|
+
}
|
|
1600
|
+
/**
|
|
1601
|
+
* Close the session
|
|
1602
|
+
*/
|
|
1603
|
+
close() {
|
|
1604
|
+
this.session.close();
|
|
1605
|
+
}
|
|
1606
|
+
/**
|
|
1607
|
+
* Async disposal support
|
|
1608
|
+
*/
|
|
1609
|
+
async [Symbol.asyncDispose]() {
|
|
1610
|
+
await this.session[Symbol.asyncDispose]();
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
class AgentSessionStore {
|
|
1614
|
+
// 5 minutes
|
|
1615
|
+
constructor() {
|
|
1616
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
1617
|
+
this.SESSION_TIMEOUT = 1e3 * 60 * 30;
|
|
1618
|
+
this.CLEANUP_INTERVAL = 1e3 * 60 * 5;
|
|
1619
|
+
this.startCleanupTimer();
|
|
1620
|
+
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Create or resume a session
|
|
1623
|
+
*/
|
|
1624
|
+
async createSession(config) {
|
|
1625
|
+
const sessionId = config.sessionId || this.generateSessionId();
|
|
1626
|
+
const existing = this.sessions.get(sessionId);
|
|
1627
|
+
if (existing) {
|
|
1628
|
+
existing.lastActive = Date.now();
|
|
1629
|
+
existing.threadId = config.threadId;
|
|
1630
|
+
return existing;
|
|
1631
|
+
}
|
|
1632
|
+
const agent = await AIEditorAgent.create({
|
|
1633
|
+
apiKey: config.apiKey,
|
|
1634
|
+
projectRoot: config.projectRoot,
|
|
1635
|
+
sessionId: config.sessionId,
|
|
1636
|
+
allowedTools: config.allowedTools,
|
|
1637
|
+
disallowedTools: config.disallowedTools
|
|
1638
|
+
});
|
|
1639
|
+
const session = {
|
|
1640
|
+
sessionId,
|
|
1641
|
+
threadId: config.threadId,
|
|
1642
|
+
agent,
|
|
1643
|
+
createdAt: Date.now(),
|
|
1644
|
+
lastActive: Date.now(),
|
|
1645
|
+
isLocked: false
|
|
1646
|
+
};
|
|
1647
|
+
this.sessions.set(sessionId, session);
|
|
1648
|
+
return session;
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Get a session by ID
|
|
1652
|
+
*/
|
|
1653
|
+
getSession(sessionId) {
|
|
1654
|
+
const session = this.sessions.get(sessionId);
|
|
1655
|
+
if (session) {
|
|
1656
|
+
session.lastActive = Date.now();
|
|
1657
|
+
}
|
|
1658
|
+
return session;
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Acquire a lock on a session to prevent concurrent edits
|
|
1662
|
+
* Returns true if lock was acquired, false if already locked
|
|
1663
|
+
*/
|
|
1664
|
+
acquireLock(sessionId) {
|
|
1665
|
+
const session = this.sessions.get(sessionId);
|
|
1666
|
+
if (!session) {
|
|
1667
|
+
throw new Error(`Session ${sessionId} not found`);
|
|
1668
|
+
}
|
|
1669
|
+
if (session.isLocked) {
|
|
1670
|
+
return false;
|
|
1671
|
+
}
|
|
1672
|
+
session.isLocked = true;
|
|
1673
|
+
session.lastActive = Date.now();
|
|
1674
|
+
return true;
|
|
1675
|
+
}
|
|
1676
|
+
/**
|
|
1677
|
+
* Release a lock on a session
|
|
1678
|
+
*/
|
|
1679
|
+
releaseLock(sessionId) {
|
|
1680
|
+
const session = this.sessions.get(sessionId);
|
|
1681
|
+
if (session) {
|
|
1682
|
+
session.isLocked = false;
|
|
1683
|
+
session.lastActive = Date.now();
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
/**
|
|
1687
|
+
* Check if any session is currently locked (to prevent concurrent edits)
|
|
1688
|
+
*/
|
|
1689
|
+
hasActiveLock() {
|
|
1690
|
+
for (const session of this.sessions.values()) {
|
|
1691
|
+
if (session.isLocked) {
|
|
1692
|
+
return true;
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
return false;
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* Get all active sessions for a thread
|
|
1699
|
+
*/
|
|
1700
|
+
getSessionsByThread(threadId) {
|
|
1701
|
+
const sessions = [];
|
|
1702
|
+
for (const session of this.sessions.values()) {
|
|
1703
|
+
if (session.threadId === threadId) {
|
|
1704
|
+
sessions.push(session);
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
return sessions;
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* Delete a session
|
|
1711
|
+
*/
|
|
1712
|
+
deleteSession(sessionId) {
|
|
1713
|
+
const session = this.sessions.get(sessionId);
|
|
1714
|
+
if (session) {
|
|
1715
|
+
session.agent.close();
|
|
1716
|
+
this.sessions.delete(sessionId);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
/**
|
|
1720
|
+
* Delete all sessions for a thread
|
|
1721
|
+
*/
|
|
1722
|
+
deleteSessionsByThread(threadId) {
|
|
1723
|
+
for (const [sessionId, session] of this.sessions.entries()) {
|
|
1724
|
+
if (session.threadId === threadId) {
|
|
1725
|
+
session.agent.close();
|
|
1726
|
+
this.sessions.delete(sessionId);
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Get all active sessions
|
|
1732
|
+
*/
|
|
1733
|
+
getAllSessions() {
|
|
1734
|
+
return Array.from(this.sessions.values());
|
|
1735
|
+
}
|
|
1736
|
+
/**
|
|
1737
|
+
* Clean up expired sessions
|
|
1738
|
+
*/
|
|
1739
|
+
cleanupExpiredSessions() {
|
|
1740
|
+
const now = Date.now();
|
|
1741
|
+
const expiredSessions = [];
|
|
1742
|
+
for (const [sessionId, session] of this.sessions.entries()) {
|
|
1743
|
+
const inactiveTime = now - session.lastActive;
|
|
1744
|
+
if (inactiveTime > this.SESSION_TIMEOUT && !session.isLocked) {
|
|
1745
|
+
expiredSessions.push(sessionId);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
for (const sessionId of expiredSessions) {
|
|
1749
|
+
console.log(
|
|
1750
|
+
`[AgentSessionStore] Cleaning up expired session: ${sessionId}`
|
|
1751
|
+
);
|
|
1752
|
+
this.deleteSession(sessionId);
|
|
1753
|
+
}
|
|
1754
|
+
if (expiredSessions.length > 0) {
|
|
1755
|
+
console.log(
|
|
1756
|
+
`[AgentSessionStore] Cleaned up ${expiredSessions.length} expired sessions`
|
|
1757
|
+
);
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
/**
|
|
1761
|
+
* Start periodic cleanup timer
|
|
1762
|
+
*/
|
|
1763
|
+
startCleanupTimer() {
|
|
1764
|
+
setInterval(() => {
|
|
1765
|
+
this.cleanupExpiredSessions();
|
|
1766
|
+
}, this.CLEANUP_INTERVAL);
|
|
1767
|
+
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Generate a unique session ID
|
|
1770
|
+
*/
|
|
1771
|
+
generateSessionId() {
|
|
1772
|
+
return `session-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
1773
|
+
}
|
|
1774
|
+
/**
|
|
1775
|
+
* Get statistics about the session store
|
|
1776
|
+
*/
|
|
1777
|
+
getStats() {
|
|
1778
|
+
return {
|
|
1779
|
+
totalSessions: this.sessions.size,
|
|
1780
|
+
lockedSessions: Array.from(this.sessions.values()).filter(
|
|
1781
|
+
(s) => s.isLocked
|
|
1782
|
+
).length,
|
|
1783
|
+
sessions: Array.from(this.sessions.values()).map((s) => ({
|
|
1784
|
+
sessionId: s.sessionId,
|
|
1785
|
+
threadId: s.threadId,
|
|
1786
|
+
isLocked: s.isLocked,
|
|
1787
|
+
ageMinutes: Math.floor((Date.now() - s.createdAt) / 1e3 / 60),
|
|
1788
|
+
inactiveMinutes: Math.floor((Date.now() - s.lastActive) / 1e3 / 60)
|
|
1789
|
+
}))
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
let sessionStore = null;
|
|
1794
|
+
function getSessionStore() {
|
|
1795
|
+
if (!sessionStore) {
|
|
1796
|
+
sessionStore = new AgentSessionStore();
|
|
1797
|
+
}
|
|
1798
|
+
return sessionStore;
|
|
1799
|
+
}
|
|
1800
|
+
async function handleChat(req) {
|
|
1801
|
+
const devModeError = validateDevMode();
|
|
1802
|
+
if (devModeError) return devModeError;
|
|
1803
|
+
try {
|
|
1804
|
+
const body = await req.json();
|
|
1805
|
+
const { sessionId, threadId, message, componentContext } = body;
|
|
1806
|
+
if (!threadId || !message) {
|
|
1807
|
+
return server.NextResponse.json(
|
|
1808
|
+
{ error: "threadId and message are required" },
|
|
1809
|
+
{ status: 400 }
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
1813
|
+
if (!apiKey) {
|
|
1814
|
+
return server.NextResponse.json(
|
|
1815
|
+
{ error: "ANTHROPIC_API_KEY not configured" },
|
|
1816
|
+
{ status: 500 }
|
|
1817
|
+
);
|
|
1818
|
+
}
|
|
1819
|
+
const sessionStore2 = getSessionStore();
|
|
1820
|
+
const projectRoot = process.cwd();
|
|
1821
|
+
const session = await sessionStore2.createSession({
|
|
1822
|
+
sessionId,
|
|
1823
|
+
threadId,
|
|
1824
|
+
apiKey,
|
|
1825
|
+
projectRoot
|
|
1826
|
+
});
|
|
1827
|
+
if (!sessionStore2.acquireLock(session.sessionId)) {
|
|
1828
|
+
return server.NextResponse.json(
|
|
1829
|
+
{
|
|
1830
|
+
error: "Another operation is in progress. Please wait for it to complete."
|
|
1831
|
+
},
|
|
1832
|
+
{ status: 409 }
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1835
|
+
const encoder = new TextEncoder();
|
|
1836
|
+
const stream = new ReadableStream({
|
|
1837
|
+
async start(controller) {
|
|
1838
|
+
try {
|
|
1839
|
+
controller.enqueue(
|
|
1840
|
+
encoder.encode(
|
|
1841
|
+
`data: ${JSON.stringify({ type: "connected", sessionId: session.sessionId })}
|
|
1842
|
+
|
|
1843
|
+
`
|
|
1844
|
+
)
|
|
1845
|
+
);
|
|
1846
|
+
for await (const event of session.agent.sendMessage(
|
|
1847
|
+
message,
|
|
1848
|
+
componentContext
|
|
1849
|
+
)) {
|
|
1850
|
+
console.log("[AGENT EVENT]", event.type, JSON.stringify(event, null, 2));
|
|
1851
|
+
controller.enqueue(
|
|
1852
|
+
encoder.encode(`data: ${JSON.stringify(event)}
|
|
1853
|
+
|
|
1854
|
+
`)
|
|
1855
|
+
);
|
|
1856
|
+
}
|
|
1857
|
+
controller.enqueue(
|
|
1858
|
+
encoder.encode(`data: ${JSON.stringify({ type: "done" })}
|
|
1859
|
+
|
|
1860
|
+
`)
|
|
1861
|
+
);
|
|
1862
|
+
controller.close();
|
|
1863
|
+
} catch (error) {
|
|
1864
|
+
console.error("[handleChat] Error:", error);
|
|
1865
|
+
controller.enqueue(
|
|
1866
|
+
encoder.encode(
|
|
1867
|
+
`data: ${JSON.stringify({ type: "error", error: error.message || String(error) })}
|
|
1868
|
+
|
|
1869
|
+
`
|
|
1870
|
+
)
|
|
1871
|
+
);
|
|
1872
|
+
controller.close();
|
|
1873
|
+
} finally {
|
|
1874
|
+
sessionStore2.releaseLock(session.sessionId);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
});
|
|
1878
|
+
return new Response(stream, {
|
|
1879
|
+
headers: {
|
|
1880
|
+
"Content-Type": "text/event-stream",
|
|
1881
|
+
"Cache-Control": "no-cache",
|
|
1882
|
+
Connection: "keep-alive"
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
} catch (error) {
|
|
1886
|
+
console.error("[handleChat] Request error:", error);
|
|
1887
|
+
return server.NextResponse.json(
|
|
1888
|
+
{ error: String(error) },
|
|
1889
|
+
{ status: 500 }
|
|
1890
|
+
);
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1536
1893
|
async function handleAIEditorRequest(req, context) {
|
|
1537
1894
|
const { path: path2 } = await context.params;
|
|
1538
1895
|
const endpoint = path2[0];
|
|
@@ -1559,12 +1916,79 @@ async function handleAIEditorRequest(req, context) {
|
|
|
1559
1916
|
case "suggestions":
|
|
1560
1917
|
if (method === "GET") return handleSuggestions(req);
|
|
1561
1918
|
break;
|
|
1919
|
+
case "chat":
|
|
1920
|
+
if (method === "POST") return handleChat(req);
|
|
1921
|
+
break;
|
|
1562
1922
|
}
|
|
1563
1923
|
return server.NextResponse.json(
|
|
1564
1924
|
{ error: `Unknown endpoint: ${endpoint}` },
|
|
1565
1925
|
{ status: 404 }
|
|
1566
1926
|
);
|
|
1567
1927
|
}
|
|
1928
|
+
const STORAGE_DIR = ".ai-editor";
|
|
1929
|
+
const STORAGE_FILE = "comments.json";
|
|
1930
|
+
function getProjectRoot() {
|
|
1931
|
+
return process.cwd();
|
|
1932
|
+
}
|
|
1933
|
+
function getStoragePath() {
|
|
1934
|
+
return path.join(getProjectRoot(), STORAGE_DIR, STORAGE_FILE);
|
|
1935
|
+
}
|
|
1936
|
+
async function ensureStorageDir() {
|
|
1937
|
+
const dir = path.join(getProjectRoot(), STORAGE_DIR);
|
|
1938
|
+
if (!fs$1.existsSync(dir)) {
|
|
1939
|
+
await fs.mkdir(dir, { recursive: true });
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
async function handleCommentsRequest(request) {
|
|
1943
|
+
if (process.env.NODE_ENV !== "development") {
|
|
1944
|
+
return server.NextResponse.json(
|
|
1945
|
+
{ error: "Comments API only available in development" },
|
|
1946
|
+
{ status: 403 }
|
|
1947
|
+
);
|
|
1948
|
+
}
|
|
1949
|
+
try {
|
|
1950
|
+
if (request.method === "GET") {
|
|
1951
|
+
const storagePath = getStoragePath();
|
|
1952
|
+
if (!fs$1.existsSync(storagePath)) {
|
|
1953
|
+
return server.NextResponse.json({ comments: [] });
|
|
1954
|
+
}
|
|
1955
|
+
const data = await fs.readFile(storagePath, "utf-8");
|
|
1956
|
+
const comments = JSON.parse(data);
|
|
1957
|
+
return server.NextResponse.json({ comments });
|
|
1958
|
+
}
|
|
1959
|
+
if (request.method === "POST") {
|
|
1960
|
+
const body = await request.json();
|
|
1961
|
+
const { action } = body;
|
|
1962
|
+
if (action === "save") {
|
|
1963
|
+
const { comments } = body;
|
|
1964
|
+
await ensureStorageDir();
|
|
1965
|
+
const storagePath = getStoragePath();
|
|
1966
|
+
await fs.writeFile(storagePath, JSON.stringify(comments, null, 2), "utf-8");
|
|
1967
|
+
return server.NextResponse.json({ success: true });
|
|
1968
|
+
}
|
|
1969
|
+
if (action === "clear") {
|
|
1970
|
+
await ensureStorageDir();
|
|
1971
|
+
const storagePath = getStoragePath();
|
|
1972
|
+
await fs.writeFile(storagePath, JSON.stringify([]), "utf-8");
|
|
1973
|
+
return server.NextResponse.json({ success: true });
|
|
1974
|
+
}
|
|
1975
|
+
return server.NextResponse.json(
|
|
1976
|
+
{ error: "Invalid action" },
|
|
1977
|
+
{ status: 400 }
|
|
1978
|
+
);
|
|
1979
|
+
}
|
|
1980
|
+
return server.NextResponse.json(
|
|
1981
|
+
{ error: "Method not allowed" },
|
|
1982
|
+
{ status: 405 }
|
|
1983
|
+
);
|
|
1984
|
+
} catch (error) {
|
|
1985
|
+
console.error("Comment storage error:", error);
|
|
1986
|
+
return server.NextResponse.json(
|
|
1987
|
+
{ error: "Internal server error" },
|
|
1988
|
+
{ status: 500 }
|
|
1989
|
+
);
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1568
1992
|
exports.extractComponentName = extractComponentName;
|
|
1569
1993
|
exports.extractComponentNameFromStack = extractComponentNameFromStack;
|
|
1570
1994
|
exports.fileExists = fileExists$1;
|
|
@@ -1574,6 +1998,7 @@ exports.getJSXMemberName = getJSXMemberName;
|
|
|
1574
1998
|
exports.getOriginalPositionFromDebugStack = getOriginalPositionFromDebugStack;
|
|
1575
1999
|
exports.handleAIEditorRequest = handleAIEditorRequest;
|
|
1576
2000
|
exports.handleAbsolutePath = handleAbsolutePath;
|
|
2001
|
+
exports.handleCommentsRequest = handleCommentsRequest;
|
|
1577
2002
|
exports.handleEdit = handleEdit;
|
|
1578
2003
|
exports.handleRead = handleRead;
|
|
1579
2004
|
exports.handleResolve = handleResolve;
|
|
@@ -1590,4 +2015,4 @@ exports.resolveOriginalPosition = resolveOriginalPosition;
|
|
|
1590
2015
|
exports.scoreElementMatch = scoreElementMatch;
|
|
1591
2016
|
exports.validateDevMode = validateDevMode;
|
|
1592
2017
|
exports.validateGeneratedCode = validateGeneratedCode;
|
|
1593
|
-
//# sourceMappingURL=
|
|
2018
|
+
//# sourceMappingURL=comments-Daur80r4.cjs.map
|