@brianli/kimaki 0.4.72-brianli.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/bin.js +2 -0
- package/dist/ai-tool-to-genai.js +233 -0
- package/dist/ai-tool-to-genai.test.js +267 -0
- package/dist/ai-tool.js +6 -0
- package/dist/bin.js +87 -0
- package/dist/bot-token.js +121 -0
- package/dist/bot-token.test.js +134 -0
- package/dist/channel-management.js +101 -0
- package/dist/cli-parsing.test.js +89 -0
- package/dist/cli.js +2529 -0
- package/dist/commands/abort.js +82 -0
- package/dist/commands/action-buttons.js +257 -0
- package/dist/commands/add-project.js +114 -0
- package/dist/commands/agent.js +291 -0
- package/dist/commands/ask-question.js +223 -0
- package/dist/commands/compact.js +120 -0
- package/dist/commands/context-usage.js +140 -0
- package/dist/commands/create-new-project.js +118 -0
- package/dist/commands/diff.js +128 -0
- package/dist/commands/file-upload.js +275 -0
- package/dist/commands/fork.js +217 -0
- package/dist/commands/gemini-apikey.js +70 -0
- package/dist/commands/login.js +490 -0
- package/dist/commands/mention-mode.js +51 -0
- package/dist/commands/merge-worktree.js +124 -0
- package/dist/commands/model.js +694 -0
- package/dist/commands/permissions.js +163 -0
- package/dist/commands/queue.js +217 -0
- package/dist/commands/remove-project.js +115 -0
- package/dist/commands/restart-opencode-server.js +116 -0
- package/dist/commands/resume.js +159 -0
- package/dist/commands/run-command.js +79 -0
- package/dist/commands/session-id.js +78 -0
- package/dist/commands/session.js +192 -0
- package/dist/commands/share.js +80 -0
- package/dist/commands/types.js +2 -0
- package/dist/commands/undo-redo.js +159 -0
- package/dist/commands/unset-model.js +152 -0
- package/dist/commands/upgrade.js +42 -0
- package/dist/commands/user-command.js +148 -0
- package/dist/commands/verbosity.js +60 -0
- package/dist/commands/worktree-settings.js +50 -0
- package/dist/commands/worktree.js +299 -0
- package/dist/condense-memory.js +33 -0
- package/dist/config.js +110 -0
- package/dist/database.js +1050 -0
- package/dist/db.js +159 -0
- package/dist/db.test.js +49 -0
- package/dist/discord-api.js +28 -0
- package/dist/discord-auth.js +231 -0
- package/dist/discord-auth.test.js +80 -0
- package/dist/discord-bot.js +997 -0
- package/dist/discord-utils.js +560 -0
- package/dist/discord-utils.test.js +115 -0
- package/dist/errors.js +167 -0
- package/dist/escape-backticks.test.js +429 -0
- package/dist/format-tables.js +122 -0
- package/dist/format-tables.test.js +199 -0
- package/dist/forum-sync/config.js +79 -0
- package/dist/forum-sync/discord-operations.js +154 -0
- package/dist/forum-sync/index.js +5 -0
- package/dist/forum-sync/markdown.js +117 -0
- package/dist/forum-sync/sync-to-discord.js +417 -0
- package/dist/forum-sync/sync-to-files.js +190 -0
- package/dist/forum-sync/types.js +53 -0
- package/dist/forum-sync/watchers.js +307 -0
- package/dist/gateway-consumer.js +232 -0
- package/dist/gateway-consumer.test.js +18 -0
- package/dist/genai-worker-wrapper.js +111 -0
- package/dist/genai-worker.js +311 -0
- package/dist/genai.js +232 -0
- package/dist/generated/browser.js +17 -0
- package/dist/generated/client.js +35 -0
- package/dist/generated/commonInputTypes.js +10 -0
- package/dist/generated/enums.js +30 -0
- package/dist/generated/internal/class.js +41 -0
- package/dist/generated/internal/prismaNamespace.js +239 -0
- package/dist/generated/internal/prismaNamespaceBrowser.js +209 -0
- package/dist/generated/models/bot_api_keys.js +1 -0
- package/dist/generated/models/bot_tokens.js +1 -0
- package/dist/generated/models/channel_agents.js +1 -0
- package/dist/generated/models/channel_directories.js +1 -0
- package/dist/generated/models/channel_mention_mode.js +1 -0
- package/dist/generated/models/channel_models.js +1 -0
- package/dist/generated/models/channel_verbosity.js +1 -0
- package/dist/generated/models/channel_worktrees.js +1 -0
- package/dist/generated/models/forum_sync_configs.js +1 -0
- package/dist/generated/models/global_models.js +1 -0
- package/dist/generated/models/ipc_requests.js +1 -0
- package/dist/generated/models/part_messages.js +1 -0
- package/dist/generated/models/scheduled_tasks.js +1 -0
- package/dist/generated/models/session_agents.js +1 -0
- package/dist/generated/models/session_models.js +1 -0
- package/dist/generated/models/session_start_sources.js +1 -0
- package/dist/generated/models/thread_sessions.js +1 -0
- package/dist/generated/models/thread_worktrees.js +1 -0
- package/dist/generated/models.js +1 -0
- package/dist/heap-monitor.js +95 -0
- package/dist/hrana-server.js +416 -0
- package/dist/hrana-server.test.js +368 -0
- package/dist/image-utils.js +112 -0
- package/dist/interaction-handler.js +327 -0
- package/dist/ipc-polling.js +251 -0
- package/dist/kimaki-digital-twin.e2e.test.js +165 -0
- package/dist/limit-heading-depth.js +25 -0
- package/dist/limit-heading-depth.test.js +105 -0
- package/dist/logger.js +160 -0
- package/dist/markdown.js +342 -0
- package/dist/markdown.test.js +253 -0
- package/dist/message-formatting.js +433 -0
- package/dist/message-formatting.test.js +73 -0
- package/dist/openai-realtime.js +228 -0
- package/dist/opencode-plugin-loading.e2e.test.js +91 -0
- package/dist/opencode-plugin.js +536 -0
- package/dist/opencode-plugin.test.js +98 -0
- package/dist/opencode.js +409 -0
- package/dist/privacy-sanitizer.js +105 -0
- package/dist/runtime-mode.js +51 -0
- package/dist/runtime-mode.test.js +115 -0
- package/dist/sentry.js +127 -0
- package/dist/session-handler/state.js +151 -0
- package/dist/session-handler.js +1874 -0
- package/dist/session-search.js +100 -0
- package/dist/session-search.test.js +40 -0
- package/dist/startup-service.js +153 -0
- package/dist/system-message.js +499 -0
- package/dist/task-runner.js +282 -0
- package/dist/task-schedule.js +191 -0
- package/dist/task-schedule.test.js +71 -0
- package/dist/thinking-utils.js +35 -0
- package/dist/thread-message-queue.e2e.test.js +781 -0
- package/dist/tools.js +359 -0
- package/dist/unnest-code-blocks.js +136 -0
- package/dist/unnest-code-blocks.test.js +641 -0
- package/dist/upgrade.js +114 -0
- package/dist/utils.js +109 -0
- package/dist/voice-handler.js +606 -0
- package/dist/voice.js +304 -0
- package/dist/voice.test.js +187 -0
- package/dist/wait-session.js +94 -0
- package/dist/worker-types.js +4 -0
- package/dist/worktree-utils.js +727 -0
- package/dist/xml.js +92 -0
- package/dist/xml.test.js +32 -0
- package/package.json +82 -0
- package/schema.prisma +246 -0
- package/skills/batch/SKILL.md +87 -0
- package/skills/critique/SKILL.md +129 -0
- package/skills/errore/SKILL.md +589 -0
- package/skills/goke/.prettierrc +5 -0
- package/skills/goke/CHANGELOG.md +40 -0
- package/skills/goke/LICENSE +21 -0
- package/skills/goke/README.md +666 -0
- package/skills/goke/SKILL.md +458 -0
- package/skills/goke/package.json +43 -0
- package/skills/goke/src/__test__/coerce.test.ts +411 -0
- package/skills/goke/src/__test__/index.test.ts +1798 -0
- package/skills/goke/src/__test__/types.test-d.ts +111 -0
- package/skills/goke/src/coerce.ts +547 -0
- package/skills/goke/src/goke.ts +1362 -0
- package/skills/goke/src/index.ts +16 -0
- package/skills/goke/src/mri.ts +164 -0
- package/skills/goke/tsconfig.json +15 -0
- package/skills/jitter/EDITOR.md +219 -0
- package/skills/jitter/EXPORT-INTERNALS.md +309 -0
- package/skills/jitter/SKILL.md +158 -0
- package/skills/jitter/jitter-clipboard.json +1042 -0
- package/skills/jitter/package.json +14 -0
- package/skills/jitter/tsconfig.json +15 -0
- package/skills/jitter/utils/actions.ts +212 -0
- package/skills/jitter/utils/export.ts +114 -0
- package/skills/jitter/utils/index.ts +141 -0
- package/skills/jitter/utils/snapshot.ts +154 -0
- package/skills/jitter/utils/traverse.ts +246 -0
- package/skills/jitter/utils/types.ts +279 -0
- package/skills/jitter/utils/wait.ts +133 -0
- package/skills/playwriter/SKILL.md +31 -0
- package/skills/security-review/SKILL.md +208 -0
- package/skills/simplify/SKILL.md +58 -0
- package/skills/termcast/SKILL.md +945 -0
- package/skills/tuistory/SKILL.md +250 -0
- package/skills/zustand-centralized-state/SKILL.md +582 -0
- package/src/__snapshots__/compact-session-context-no-system.md +35 -0
- package/src/__snapshots__/compact-session-context.md +41 -0
- package/src/__snapshots__/first-session-no-info.md +17 -0
- package/src/__snapshots__/first-session-with-info.md +23 -0
- package/src/__snapshots__/session-1.md +17 -0
- package/src/__snapshots__/session-2.md +5871 -0
- package/src/__snapshots__/session-3.md +17 -0
- package/src/__snapshots__/session-with-tools.md +5871 -0
- package/src/ai-tool-to-genai.test.ts +296 -0
- package/src/ai-tool-to-genai.ts +282 -0
- package/src/ai-tool.ts +39 -0
- package/src/bin.ts +108 -0
- package/src/bot-token.test.ts +171 -0
- package/src/bot-token.ts +159 -0
- package/src/channel-management.ts +172 -0
- package/src/cli-parsing.test.ts +132 -0
- package/src/cli.ts +3605 -0
- package/src/commands/abort.ts +112 -0
- package/src/commands/action-buttons.ts +376 -0
- package/src/commands/add-project.ts +152 -0
- package/src/commands/agent.ts +404 -0
- package/src/commands/ask-question.ts +330 -0
- package/src/commands/compact.ts +157 -0
- package/src/commands/context-usage.ts +199 -0
- package/src/commands/create-new-project.ts +179 -0
- package/src/commands/diff.ts +165 -0
- package/src/commands/file-upload.ts +389 -0
- package/src/commands/fork.ts +320 -0
- package/src/commands/gemini-apikey.ts +104 -0
- package/src/commands/login.ts +634 -0
- package/src/commands/mention-mode.ts +77 -0
- package/src/commands/merge-worktree.ts +177 -0
- package/src/commands/model.ts +961 -0
- package/src/commands/permissions.ts +261 -0
- package/src/commands/queue.ts +296 -0
- package/src/commands/remove-project.ts +155 -0
- package/src/commands/restart-opencode-server.ts +162 -0
- package/src/commands/resume.ts +242 -0
- package/src/commands/run-command.ts +123 -0
- package/src/commands/session-id.ts +109 -0
- package/src/commands/session.ts +250 -0
- package/src/commands/share.ts +106 -0
- package/src/commands/types.ts +25 -0
- package/src/commands/undo-redo.ts +221 -0
- package/src/commands/unset-model.ts +189 -0
- package/src/commands/upgrade.ts +52 -0
- package/src/commands/user-command.ts +193 -0
- package/src/commands/verbosity.ts +88 -0
- package/src/commands/worktree-settings.ts +79 -0
- package/src/commands/worktree.ts +431 -0
- package/src/condense-memory.ts +36 -0
- package/src/config.ts +148 -0
- package/src/database.ts +1530 -0
- package/src/db.test.ts +60 -0
- package/src/db.ts +190 -0
- package/src/discord-api.ts +35 -0
- package/src/discord-bot.ts +1316 -0
- package/src/discord-utils.test.ts +132 -0
- package/src/discord-utils.ts +767 -0
- package/src/errors.ts +213 -0
- package/src/escape-backticks.test.ts +469 -0
- package/src/format-tables.test.ts +223 -0
- package/src/format-tables.ts +145 -0
- package/src/forum-sync/config.ts +92 -0
- package/src/forum-sync/discord-operations.ts +241 -0
- package/src/forum-sync/index.ts +9 -0
- package/src/forum-sync/markdown.ts +176 -0
- package/src/forum-sync/sync-to-discord.ts +595 -0
- package/src/forum-sync/sync-to-files.ts +294 -0
- package/src/forum-sync/types.ts +175 -0
- package/src/forum-sync/watchers.ts +454 -0
- package/src/genai-worker-wrapper.ts +164 -0
- package/src/genai-worker.ts +386 -0
- package/src/genai.ts +321 -0
- package/src/generated/browser.ts +109 -0
- package/src/generated/client.ts +131 -0
- package/src/generated/commonInputTypes.ts +512 -0
- package/src/generated/enums.ts +46 -0
- package/src/generated/internal/class.ts +362 -0
- package/src/generated/internal/prismaNamespace.ts +2251 -0
- package/src/generated/internal/prismaNamespaceBrowser.ts +308 -0
- package/src/generated/models/bot_api_keys.ts +1288 -0
- package/src/generated/models/bot_tokens.ts +1577 -0
- package/src/generated/models/channel_agents.ts +1256 -0
- package/src/generated/models/channel_directories.ts +2104 -0
- package/src/generated/models/channel_mention_mode.ts +1300 -0
- package/src/generated/models/channel_models.ts +1288 -0
- package/src/generated/models/channel_verbosity.ts +1224 -0
- package/src/generated/models/channel_worktrees.ts +1308 -0
- package/src/generated/models/forum_sync_configs.ts +1452 -0
- package/src/generated/models/global_models.ts +1288 -0
- package/src/generated/models/ipc_requests.ts +1485 -0
- package/src/generated/models/part_messages.ts +1302 -0
- package/src/generated/models/scheduled_tasks.ts +2320 -0
- package/src/generated/models/session_agents.ts +1086 -0
- package/src/generated/models/session_models.ts +1114 -0
- package/src/generated/models/session_start_sources.ts +1408 -0
- package/src/generated/models/thread_sessions.ts +1599 -0
- package/src/generated/models/thread_worktrees.ts +1352 -0
- package/src/generated/models.ts +29 -0
- package/src/heap-monitor.ts +121 -0
- package/src/hrana-server.test.ts +428 -0
- package/src/hrana-server.ts +547 -0
- package/src/image-utils.ts +149 -0
- package/src/interaction-handler.ts +461 -0
- package/src/ipc-polling.ts +325 -0
- package/src/kimaki-digital-twin.e2e.test.ts +201 -0
- package/src/limit-heading-depth.test.ts +116 -0
- package/src/limit-heading-depth.ts +26 -0
- package/src/logger.ts +203 -0
- package/src/markdown.test.ts +360 -0
- package/src/markdown.ts +410 -0
- package/src/message-formatting.test.ts +81 -0
- package/src/message-formatting.ts +549 -0
- package/src/openai-realtime.ts +362 -0
- package/src/opencode-plugin-loading.e2e.test.ts +112 -0
- package/src/opencode-plugin.test.ts +108 -0
- package/src/opencode-plugin.ts +652 -0
- package/src/opencode.ts +554 -0
- package/src/privacy-sanitizer.ts +142 -0
- package/src/schema.sql +158 -0
- package/src/sentry.ts +137 -0
- package/src/session-handler/state.ts +232 -0
- package/src/session-handler.ts +2668 -0
- package/src/session-search.test.ts +50 -0
- package/src/session-search.ts +148 -0
- package/src/startup-service.ts +200 -0
- package/src/system-message.ts +568 -0
- package/src/task-runner.ts +425 -0
- package/src/task-schedule.test.ts +84 -0
- package/src/task-schedule.ts +287 -0
- package/src/thinking-utils.ts +61 -0
- package/src/thread-message-queue.e2e.test.ts +997 -0
- package/src/tools.ts +432 -0
- package/src/unnest-code-blocks.test.ts +679 -0
- package/src/unnest-code-blocks.ts +168 -0
- package/src/upgrade.ts +127 -0
- package/src/utils.ts +145 -0
- package/src/voice-handler.ts +852 -0
- package/src/voice.test.ts +219 -0
- package/src/voice.ts +444 -0
- package/src/wait-session.ts +147 -0
- package/src/worker-types.ts +64 -0
- package/src/worktree-utils.ts +988 -0
- package/src/xml.test.ts +38 -0
- package/src/xml.ts +121 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jitter-utils",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "esbuild utils/index.ts --bundle --format=iife --global-name=jitterUtils --outfile=dist/jitter-utils.js",
|
|
8
|
+
"typecheck": "tsc --noEmit"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"esbuild": "^0.24.2",
|
|
12
|
+
"typescript": "^5.9.2"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"lib": ["ES2022", "DOM"],
|
|
12
|
+
"types": []
|
|
13
|
+
},
|
|
14
|
+
"include": ["utils/**/*.ts"]
|
|
15
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Action helpers for modifying Jitter projects
|
|
2
|
+
|
|
3
|
+
import type { LayerProperties } from './types'
|
|
4
|
+
|
|
5
|
+
function dispatch(action: Record<string, unknown>): void {
|
|
6
|
+
window.app.dispatchAction(action)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Replace the URL of an asset node (image, SVG, video)
|
|
11
|
+
*/
|
|
12
|
+
export function replaceAssetUrl(nodeId: string, newUrl: string): void {
|
|
13
|
+
dispatch({
|
|
14
|
+
type: 'updateObjWithUndo',
|
|
15
|
+
objId: nodeId,
|
|
16
|
+
data: { url: newUrl },
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Replace text content of a text node
|
|
22
|
+
*/
|
|
23
|
+
export function replaceText(nodeId: string, newText: string): void {
|
|
24
|
+
dispatch({
|
|
25
|
+
type: 'updateObjWithUndo',
|
|
26
|
+
objId: nodeId,
|
|
27
|
+
data: { text: newText },
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Update multiple properties on a node
|
|
33
|
+
*/
|
|
34
|
+
export function updateNode(
|
|
35
|
+
nodeId: string,
|
|
36
|
+
properties: Partial<LayerProperties> & { url?: string; text?: string },
|
|
37
|
+
): void {
|
|
38
|
+
dispatch({
|
|
39
|
+
type: 'updateObjWithUndo',
|
|
40
|
+
objId: nodeId,
|
|
41
|
+
data: properties,
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface ReplacementItem {
|
|
46
|
+
nodeId: string
|
|
47
|
+
data: Partial<LayerProperties> & { url?: string; text?: string }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Batch update multiple nodes at once
|
|
52
|
+
*/
|
|
53
|
+
export function batchReplace(replacements: ReplacementItem[]): void {
|
|
54
|
+
for (const { nodeId, data } of replacements) {
|
|
55
|
+
dispatch({
|
|
56
|
+
type: 'updateObjWithUndo',
|
|
57
|
+
objId: nodeId,
|
|
58
|
+
data: data,
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Select specific nodes by their IDs
|
|
65
|
+
*/
|
|
66
|
+
export function selectNodes(nodeIds: string[]): void {
|
|
67
|
+
dispatch({
|
|
68
|
+
type: 'setSelection',
|
|
69
|
+
selection: { nodesIds: nodeIds },
|
|
70
|
+
saveInCmdHistory: true,
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Clear the current selection
|
|
76
|
+
*/
|
|
77
|
+
export function clearSelection(): void {
|
|
78
|
+
dispatch({ type: 'emptySelection' })
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Delete the currently selected nodes
|
|
83
|
+
*/
|
|
84
|
+
export function deleteSelection(): void {
|
|
85
|
+
dispatch({ type: 'deleteCurrentSelection' })
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Remove specific nodes by their IDs
|
|
90
|
+
*/
|
|
91
|
+
export function removeNodes(nodeIds: string[]): void {
|
|
92
|
+
dispatch({
|
|
93
|
+
type: 'removeObjWithUndo',
|
|
94
|
+
objIds: nodeIds,
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Undo the last action
|
|
100
|
+
*/
|
|
101
|
+
export function undo(): void {
|
|
102
|
+
dispatch({ type: 'undo' })
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Redo the last undone action
|
|
107
|
+
*/
|
|
108
|
+
export function redo(): void {
|
|
109
|
+
dispatch({ type: 'redo' })
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Rename a node
|
|
114
|
+
*/
|
|
115
|
+
export function renameNode(nodeId: string, newName: string): void {
|
|
116
|
+
selectNodes([nodeId])
|
|
117
|
+
dispatch({
|
|
118
|
+
type: 'renameSelection',
|
|
119
|
+
name: newName,
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Update node position
|
|
125
|
+
*/
|
|
126
|
+
export function moveNode(nodeId: string, x: number, y: number): void {
|
|
127
|
+
dispatch({
|
|
128
|
+
type: 'updateObjWithUndo',
|
|
129
|
+
objId: nodeId,
|
|
130
|
+
data: { x, y },
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Update node size
|
|
136
|
+
*/
|
|
137
|
+
export function resizeNode(
|
|
138
|
+
nodeId: string,
|
|
139
|
+
width: number,
|
|
140
|
+
height: number,
|
|
141
|
+
): void {
|
|
142
|
+
dispatch({
|
|
143
|
+
type: 'updateObjWithUndo',
|
|
144
|
+
objId: nodeId,
|
|
145
|
+
data: { width, height },
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Update node opacity (0-100)
|
|
151
|
+
*/
|
|
152
|
+
export function setOpacity(nodeId: string, opacity: number): void {
|
|
153
|
+
dispatch({
|
|
154
|
+
type: 'updateObjWithUndo',
|
|
155
|
+
objId: nodeId,
|
|
156
|
+
data: { opacity },
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Update node rotation angle in degrees
|
|
162
|
+
*/
|
|
163
|
+
export function setRotation(nodeId: string, angle: number): void {
|
|
164
|
+
dispatch({
|
|
165
|
+
type: 'updateObjWithUndo',
|
|
166
|
+
objId: nodeId,
|
|
167
|
+
data: { angle },
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Set the current playhead time for an artboard
|
|
173
|
+
*/
|
|
174
|
+
export function setCurrentTime(artboardId: string, timeMs: number): void {
|
|
175
|
+
dispatch({
|
|
176
|
+
type: 'setArtboardsTime',
|
|
177
|
+
times: { [artboardId]: timeMs },
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Jump playhead to start
|
|
183
|
+
*/
|
|
184
|
+
export function jumpToStart(): void {
|
|
185
|
+
dispatch({ type: 'jumpToStartTime' })
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Jump playhead to end
|
|
190
|
+
*/
|
|
191
|
+
export function jumpToEnd(): void {
|
|
192
|
+
dispatch({ type: 'jumpToEndTime' })
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Add a new object to the project
|
|
197
|
+
*/
|
|
198
|
+
export function addObject(
|
|
199
|
+
parentId: string,
|
|
200
|
+
id: string,
|
|
201
|
+
item: LayerProperties,
|
|
202
|
+
index?: string,
|
|
203
|
+
): void {
|
|
204
|
+
dispatch({ type: 'saveSelectionForUndo' })
|
|
205
|
+
dispatch({
|
|
206
|
+
type: 'addObjWithUndo',
|
|
207
|
+
parentId,
|
|
208
|
+
objData: { id, item },
|
|
209
|
+
index,
|
|
210
|
+
})
|
|
211
|
+
selectNodes([id])
|
|
212
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Export URL generation utilities
|
|
2
|
+
|
|
3
|
+
import type { ExportProfile } from './types'
|
|
4
|
+
import { getArtboards } from './traverse'
|
|
5
|
+
|
|
6
|
+
export interface ExportUrlOptions {
|
|
7
|
+
fileId: string
|
|
8
|
+
artboardId: string
|
|
9
|
+
width: number
|
|
10
|
+
height: number
|
|
11
|
+
profile?: ExportProfile
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generate a Jitter export URL for downloading Lottie/video/etc
|
|
16
|
+
*/
|
|
17
|
+
export function generateExportUrl(options: ExportUrlOptions): string {
|
|
18
|
+
const { fileId, artboardId, width, height, profile = 'lottie' } = options
|
|
19
|
+
const params = new URLSearchParams({
|
|
20
|
+
file: fileId,
|
|
21
|
+
artboardId: artboardId,
|
|
22
|
+
profile: profile,
|
|
23
|
+
width: width.toString(),
|
|
24
|
+
height: height.toString(),
|
|
25
|
+
})
|
|
26
|
+
return `https://jitter.video/export/?${params.toString()}`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CurrentProjectExportOptions {
|
|
30
|
+
artboardName?: string
|
|
31
|
+
profile?: ExportProfile
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generate export URL from the currently open project
|
|
36
|
+
*/
|
|
37
|
+
export function generateExportUrlFromCurrentProject(
|
|
38
|
+
options: CurrentProjectExportOptions = {},
|
|
39
|
+
): string {
|
|
40
|
+
const { artboardName, profile = 'lottie' } = options
|
|
41
|
+
const fileId = window.app.props.fileMeta.id
|
|
42
|
+
const artboards = getArtboards()
|
|
43
|
+
|
|
44
|
+
const artboard = artboardName
|
|
45
|
+
? artboards.find((a) => a.name === artboardName)
|
|
46
|
+
: artboards[0]
|
|
47
|
+
|
|
48
|
+
if (!artboard) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
artboardName
|
|
51
|
+
? `Artboard "${artboardName}" not found`
|
|
52
|
+
: 'No artboard found in project',
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return generateExportUrl({
|
|
57
|
+
fileId,
|
|
58
|
+
artboardId: artboard.id,
|
|
59
|
+
width: artboard.width,
|
|
60
|
+
height: artboard.height,
|
|
61
|
+
profile,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface ParsedJitterUrl {
|
|
66
|
+
fileId: string | null
|
|
67
|
+
nodeId: string | null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Parse a Jitter project URL to extract file and node IDs
|
|
72
|
+
*/
|
|
73
|
+
export function parseJitterUrl(url: string): ParsedJitterUrl {
|
|
74
|
+
const parsed = new URL(url)
|
|
75
|
+
return {
|
|
76
|
+
fileId: parsed.searchParams.get('id'),
|
|
77
|
+
nodeId: parsed.searchParams.get('nodeId'),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get the current project's file metadata
|
|
83
|
+
*/
|
|
84
|
+
export function getFileMeta(): {
|
|
85
|
+
id: string
|
|
86
|
+
name: string
|
|
87
|
+
bucket: string
|
|
88
|
+
teamId?: string
|
|
89
|
+
} {
|
|
90
|
+
return window.app.props.fileMeta
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Generate a URL to open a specific node in the editor
|
|
95
|
+
*/
|
|
96
|
+
export function generateNodeUrl(fileId: string, nodeId: string): string {
|
|
97
|
+
const params = new URLSearchParams({
|
|
98
|
+
id: fileId,
|
|
99
|
+
nodeId: nodeId,
|
|
100
|
+
})
|
|
101
|
+
return `https://jitter.video/file/?${params.toString()}`
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get URL for the currently open project
|
|
106
|
+
*/
|
|
107
|
+
export function getCurrentProjectUrl(nodeId?: string): string {
|
|
108
|
+
const fileId = window.app.props.fileMeta.id
|
|
109
|
+
const params = new URLSearchParams({ id: fileId })
|
|
110
|
+
if (nodeId) {
|
|
111
|
+
params.set('nodeId', nodeId)
|
|
112
|
+
}
|
|
113
|
+
return `https://jitter.video/file/?${params.toString()}`
|
|
114
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// Jitter Utils - Bundle entry point
|
|
2
|
+
// Exports all utilities and attaches to globalThis.jitterUtils
|
|
3
|
+
|
|
4
|
+
export * from './types'
|
|
5
|
+
export * from './traverse'
|
|
6
|
+
export * from './actions'
|
|
7
|
+
export * from './export'
|
|
8
|
+
export * from './snapshot'
|
|
9
|
+
export * from './wait'
|
|
10
|
+
|
|
11
|
+
// Re-export specific functions for easier access
|
|
12
|
+
import {
|
|
13
|
+
findNodeById,
|
|
14
|
+
findAllMediaNodes,
|
|
15
|
+
findAllTextNodes,
|
|
16
|
+
getArtboards,
|
|
17
|
+
findNodesByType,
|
|
18
|
+
findNodesByName,
|
|
19
|
+
getParentNode,
|
|
20
|
+
getAncestors,
|
|
21
|
+
flattenTree,
|
|
22
|
+
} from './traverse'
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
replaceAssetUrl,
|
|
26
|
+
replaceText,
|
|
27
|
+
updateNode,
|
|
28
|
+
batchReplace,
|
|
29
|
+
selectNodes,
|
|
30
|
+
clearSelection,
|
|
31
|
+
deleteSelection,
|
|
32
|
+
removeNodes,
|
|
33
|
+
undo,
|
|
34
|
+
redo,
|
|
35
|
+
renameNode,
|
|
36
|
+
moveNode,
|
|
37
|
+
resizeNode,
|
|
38
|
+
setOpacity,
|
|
39
|
+
setRotation,
|
|
40
|
+
setCurrentTime,
|
|
41
|
+
jumpToStart,
|
|
42
|
+
jumpToEnd,
|
|
43
|
+
addObject,
|
|
44
|
+
} from './actions'
|
|
45
|
+
|
|
46
|
+
import {
|
|
47
|
+
generateExportUrl,
|
|
48
|
+
generateExportUrlFromCurrentProject,
|
|
49
|
+
parseJitterUrl,
|
|
50
|
+
getFileMeta,
|
|
51
|
+
generateNodeUrl,
|
|
52
|
+
getCurrentProjectUrl,
|
|
53
|
+
} from './export'
|
|
54
|
+
|
|
55
|
+
import {
|
|
56
|
+
createSnapshot,
|
|
57
|
+
restoreFromSnapshot,
|
|
58
|
+
duplicateProject,
|
|
59
|
+
deleteProject,
|
|
60
|
+
createMediaSnapshot,
|
|
61
|
+
createTextSnapshot,
|
|
62
|
+
withTemporaryChanges,
|
|
63
|
+
} from './snapshot'
|
|
64
|
+
|
|
65
|
+
import {
|
|
66
|
+
waitForApp,
|
|
67
|
+
waitForSync,
|
|
68
|
+
waitFor,
|
|
69
|
+
waitForNode,
|
|
70
|
+
waitForConfigChange,
|
|
71
|
+
isReadOnly,
|
|
72
|
+
isAppReady,
|
|
73
|
+
} from './wait'
|
|
74
|
+
|
|
75
|
+
const jitterUtils = {
|
|
76
|
+
// Traverse
|
|
77
|
+
findNodeById,
|
|
78
|
+
findAllMediaNodes,
|
|
79
|
+
findAllTextNodes,
|
|
80
|
+
getArtboards,
|
|
81
|
+
findNodesByType,
|
|
82
|
+
findNodesByName,
|
|
83
|
+
getParentNode,
|
|
84
|
+
getAncestors,
|
|
85
|
+
flattenTree,
|
|
86
|
+
|
|
87
|
+
// Actions
|
|
88
|
+
replaceAssetUrl,
|
|
89
|
+
replaceText,
|
|
90
|
+
updateNode,
|
|
91
|
+
batchReplace,
|
|
92
|
+
selectNodes,
|
|
93
|
+
clearSelection,
|
|
94
|
+
deleteSelection,
|
|
95
|
+
removeNodes,
|
|
96
|
+
undo,
|
|
97
|
+
redo,
|
|
98
|
+
renameNode,
|
|
99
|
+
moveNode,
|
|
100
|
+
resizeNode,
|
|
101
|
+
setOpacity,
|
|
102
|
+
setRotation,
|
|
103
|
+
setCurrentTime,
|
|
104
|
+
jumpToStart,
|
|
105
|
+
jumpToEnd,
|
|
106
|
+
addObject,
|
|
107
|
+
|
|
108
|
+
// Export
|
|
109
|
+
generateExportUrl,
|
|
110
|
+
generateExportUrlFromCurrentProject,
|
|
111
|
+
parseJitterUrl,
|
|
112
|
+
getFileMeta,
|
|
113
|
+
generateNodeUrl,
|
|
114
|
+
getCurrentProjectUrl,
|
|
115
|
+
|
|
116
|
+
// Snapshot
|
|
117
|
+
createSnapshot,
|
|
118
|
+
restoreFromSnapshot,
|
|
119
|
+
duplicateProject,
|
|
120
|
+
deleteProject,
|
|
121
|
+
createMediaSnapshot,
|
|
122
|
+
createTextSnapshot,
|
|
123
|
+
withTemporaryChanges,
|
|
124
|
+
|
|
125
|
+
// Wait
|
|
126
|
+
waitForApp,
|
|
127
|
+
waitForSync,
|
|
128
|
+
waitFor,
|
|
129
|
+
waitForNode,
|
|
130
|
+
waitForConfigChange,
|
|
131
|
+
isReadOnly,
|
|
132
|
+
isAppReady,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Attach to globalThis for browser access
|
|
136
|
+
if (typeof globalThis !== 'undefined') {
|
|
137
|
+
;(globalThis as unknown as { jitterUtils: typeof jitterUtils }).jitterUtils =
|
|
138
|
+
jitterUtils
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export default jitterUtils
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Snapshot and restore utilities for temporary project modifications
|
|
2
|
+
|
|
3
|
+
import type { LayerProperties } from './types'
|
|
4
|
+
import { findNodeById } from './traverse'
|
|
5
|
+
|
|
6
|
+
export type Snapshot = Record<string, LayerProperties>
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create a snapshot of specific nodes' current state
|
|
10
|
+
* Use this before making temporary changes that you want to restore later
|
|
11
|
+
*/
|
|
12
|
+
export function createSnapshot(nodeIds: string[]): Snapshot {
|
|
13
|
+
const snapshot: Snapshot = {}
|
|
14
|
+
|
|
15
|
+
for (const nodeId of nodeIds) {
|
|
16
|
+
const node = findNodeById(nodeId)
|
|
17
|
+
if (node?.item) {
|
|
18
|
+
// Deep clone the item to avoid reference issues
|
|
19
|
+
snapshot[nodeId] = JSON.parse(JSON.stringify(node.item))
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return snapshot
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Restore nodes to their previously saved state
|
|
28
|
+
*/
|
|
29
|
+
export function restoreFromSnapshot(snapshot: Snapshot): void {
|
|
30
|
+
for (const [nodeId, data] of Object.entries(snapshot)) {
|
|
31
|
+
window.app.dispatchAction({
|
|
32
|
+
type: 'updateObjWithUndo',
|
|
33
|
+
objId: nodeId,
|
|
34
|
+
data: data,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Duplicate the current project file
|
|
41
|
+
* Returns the new file's ID
|
|
42
|
+
*/
|
|
43
|
+
export async function duplicateProject(): Promise<string> {
|
|
44
|
+
const currentFileId = window.app.props.fileMeta.id
|
|
45
|
+
return await window.app.props.fileActions.duplicateFile(currentFileId)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Delete a project file by ID
|
|
50
|
+
*/
|
|
51
|
+
export async function deleteProject(fileId: string): Promise<void> {
|
|
52
|
+
await window.app.props.fileActions.deleteFile(fileId)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a snapshot of all media nodes for easy restoration
|
|
57
|
+
*/
|
|
58
|
+
export function createMediaSnapshot(): {
|
|
59
|
+
snapshot: Snapshot
|
|
60
|
+
nodeIds: string[]
|
|
61
|
+
} {
|
|
62
|
+
const conf = window.app.props.observableImmutableConf.lastImmutableConf
|
|
63
|
+
const nodeIds: string[] = []
|
|
64
|
+
const mediaTypes = new Set(['svg', 'image', 'video', 'gif'])
|
|
65
|
+
|
|
66
|
+
const collectIds = (node: {
|
|
67
|
+
id: string
|
|
68
|
+
item?: { type: string }
|
|
69
|
+
children?: unknown[]
|
|
70
|
+
}): void => {
|
|
71
|
+
if (node.item && mediaTypes.has(node.item.type)) {
|
|
72
|
+
nodeIds.push(node.id)
|
|
73
|
+
}
|
|
74
|
+
if (node.children) {
|
|
75
|
+
;(node.children as (typeof node)[]).forEach(collectIds)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
;(conf.roots || []).forEach(collectIds)
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
snapshot: createSnapshot(nodeIds),
|
|
83
|
+
nodeIds,
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create a snapshot of all text nodes for easy restoration
|
|
89
|
+
*/
|
|
90
|
+
export function createTextSnapshot(): {
|
|
91
|
+
snapshot: Snapshot
|
|
92
|
+
nodeIds: string[]
|
|
93
|
+
} {
|
|
94
|
+
const conf = window.app.props.observableImmutableConf.lastImmutableConf
|
|
95
|
+
const nodeIds: string[] = []
|
|
96
|
+
|
|
97
|
+
const collectIds = (node: {
|
|
98
|
+
id: string
|
|
99
|
+
item?: { type: string }
|
|
100
|
+
children?: unknown[]
|
|
101
|
+
}): void => {
|
|
102
|
+
if (node.item?.type === 'text') {
|
|
103
|
+
nodeIds.push(node.id)
|
|
104
|
+
}
|
|
105
|
+
if (node.children) {
|
|
106
|
+
;(node.children as (typeof node)[]).forEach(collectIds)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
;(conf.roots || []).forEach(collectIds)
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
snapshot: createSnapshot(nodeIds),
|
|
114
|
+
nodeIds,
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface ExportWithRestoreOptions {
|
|
119
|
+
replacements: Array<{ nodeId: string; data: Record<string, unknown> }>
|
|
120
|
+
onBeforeExport?: () => void | Promise<void>
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Apply temporary changes, run a callback, then restore original state
|
|
125
|
+
* Useful for exporting with temporary asset replacements
|
|
126
|
+
*/
|
|
127
|
+
export async function withTemporaryChanges<T>(
|
|
128
|
+
nodeIds: string[],
|
|
129
|
+
changes: Record<string, Record<string, unknown>>,
|
|
130
|
+
callback: () => T | Promise<T>,
|
|
131
|
+
): Promise<T> {
|
|
132
|
+
// Create snapshot before changes
|
|
133
|
+
const snapshot = createSnapshot(nodeIds)
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
// Apply changes
|
|
137
|
+
for (const [nodeId, data] of Object.entries(changes)) {
|
|
138
|
+
window.app.dispatchAction({
|
|
139
|
+
type: 'updateObjWithUndo',
|
|
140
|
+
objId: nodeId,
|
|
141
|
+
data: data,
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Wait for changes to sync
|
|
146
|
+
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
147
|
+
|
|
148
|
+
// Run callback
|
|
149
|
+
return await callback()
|
|
150
|
+
} finally {
|
|
151
|
+
// Always restore original state
|
|
152
|
+
restoreFromSnapshot(snapshot)
|
|
153
|
+
}
|
|
154
|
+
}
|