@plotday/twister 0.20.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/LICENSE +21 -0
- package/README.md +261 -0
- package/bin/commands/build.js +108 -0
- package/bin/commands/build.js.map +1 -0
- package/bin/commands/create.js +230 -0
- package/bin/commands/create.js.map +1 -0
- package/bin/commands/deploy.js +292 -0
- package/bin/commands/deploy.js.map +1 -0
- package/bin/commands/generate.js +301 -0
- package/bin/commands/generate.js.map +1 -0
- package/bin/commands/lint.js +69 -0
- package/bin/commands/lint.js.map +1 -0
- package/bin/commands/login.js +140 -0
- package/bin/commands/login.js.map +1 -0
- package/bin/commands/priority-create.js +102 -0
- package/bin/commands/priority-create.js.map +1 -0
- package/bin/commands/priority-list.js +47 -0
- package/bin/commands/priority-list.js.map +1 -0
- package/bin/commands/twist-logs.js +187 -0
- package/bin/commands/twist-logs.js.map +1 -0
- package/bin/index.js +129 -0
- package/bin/index.js.map +1 -0
- package/bin/package.json +3 -0
- package/bin/plot.cjs +3 -0
- package/bin/templates/AGENTS.template.md +403 -0
- package/bin/templates/CLAUDE.template.md +1 -0
- package/bin/templates/README.template.md +189 -0
- package/bin/utils/bundle.js +106 -0
- package/bin/utils/bundle.js.map +1 -0
- package/bin/utils/output.js +133 -0
- package/bin/utils/output.js.map +1 -0
- package/bin/utils/packageManager.js +65 -0
- package/bin/utils/packageManager.js.map +1 -0
- package/bin/utils/sse.js +100 -0
- package/bin/utils/sse.js.map +1 -0
- package/bin/utils/token.js +75 -0
- package/bin/utils/token.js.map +1 -0
- package/cli/templates/AGENTS.template.md +403 -0
- package/cli/templates/CLAUDE.template.md +1 -0
- package/cli/templates/README.template.md +189 -0
- package/dist/common/calendar.d.ts +144 -0
- package/dist/common/calendar.d.ts.map +1 -0
- package/dist/common/calendar.js +2 -0
- package/dist/common/calendar.js.map +1 -0
- package/dist/common/messaging.d.ts +84 -0
- package/dist/common/messaging.d.ts.map +1 -0
- package/dist/common/messaging.js +2 -0
- package/dist/common/messaging.js.map +1 -0
- package/dist/creator-docs.d.ts +11 -0
- package/dist/creator-docs.d.ts.map +1 -0
- package/dist/creator-docs.js +27 -0
- package/dist/creator-docs.js.map +1 -0
- package/dist/docs/.nojekyll +1 -0
- package/dist/docs/assets/favicon.svg +8 -0
- package/dist/docs/assets/hierarchy.js +1 -0
- package/dist/docs/assets/highlight.css +134 -0
- package/dist/docs/assets/icons.js +18 -0
- package/dist/docs/assets/icons.svg +1 -0
- package/dist/docs/assets/main.js +60 -0
- package/dist/docs/assets/navigation.js +1 -0
- package/dist/docs/assets/search.js +1 -0
- package/dist/docs/assets/style.css +1633 -0
- package/dist/docs/classes/tool.ITool.html +4 -0
- package/dist/docs/classes/tool.Tool.html +116 -0
- package/dist/docs/classes/tools_ai.AI.html +27 -0
- package/dist/docs/classes/tools_callbacks.Callbacks.html +45 -0
- package/dist/docs/classes/tools_integrations.Integrations.html +26 -0
- package/dist/docs/classes/tools_network.Network.html +68 -0
- package/dist/docs/classes/tools_plot.Plot.html +82 -0
- package/dist/docs/classes/tools_store.Store.html +53 -0
- package/dist/docs/classes/tools_tasks.Tasks.html +39 -0
- package/dist/docs/classes/tools_twists.Twists.html +59 -0
- package/dist/docs/classes/twist.Twist.html +96 -0
- package/dist/docs/documents/Advanced.html +91 -0
- package/dist/docs/documents/Building_Custom_Tools.html +200 -0
- package/dist/docs/documents/Built-in_Tools.html +170 -0
- package/dist/docs/documents/CLI_Reference.html +193 -0
- package/dist/docs/documents/Core_Concepts.html +163 -0
- package/dist/docs/documents/Getting_Started.html +94 -0
- package/dist/docs/documents/Runtime_Environment.html +128 -0
- package/dist/docs/enums/plot.ActivityLinkType.html +12 -0
- package/dist/docs/enums/plot.ActivityType.html +10 -0
- package/dist/docs/enums/plot.ActorType.html +10 -0
- package/dist/docs/enums/plot.ConferencingProvider.html +14 -0
- package/dist/docs/enums/tag.Tag.html +45 -0
- package/dist/docs/enums/tools_ai.AIModel.html +31 -0
- package/dist/docs/enums/tools_integrations.AuthLevel.html +7 -0
- package/dist/docs/enums/tools_integrations.AuthProvider.html +24 -0
- package/dist/docs/enums/tools_plot.ActivityAccess.html +8 -0
- package/dist/docs/enums/tools_plot.ContactAccess.html +5 -0
- package/dist/docs/enums/tools_plot.PriorityAccess.html +8 -0
- package/dist/docs/hierarchy.html +1 -0
- package/dist/docs/index.html +100 -0
- package/dist/docs/interfaces/common_calendar.Calendar.html +13 -0
- package/dist/docs/interfaces/common_calendar.CalendarTool.html +49 -0
- package/dist/docs/interfaces/common_calendar.SyncOptions.html +8 -0
- package/dist/docs/interfaces/tools_ai.AIRequest.html +46 -0
- package/dist/docs/interfaces/tools_ai.AIResponse.html +19 -0
- package/dist/docs/interfaces/tools_ai.FilePart.html +14 -0
- package/dist/docs/interfaces/tools_ai.ImagePart.html +11 -0
- package/dist/docs/interfaces/tools_ai.ReasoningPart.html +7 -0
- package/dist/docs/interfaces/tools_ai.RedactedReasoningPart.html +5 -0
- package/dist/docs/interfaces/tools_ai.TextPart.html +5 -0
- package/dist/docs/interfaces/tools_ai.ToolCallPart.html +9 -0
- package/dist/docs/interfaces/tools_ai.ToolExecutionOptions.html +9 -0
- package/dist/docs/interfaces/tools_ai.ToolResultPart.html +9 -0
- package/dist/docs/interfaces/tools_twists.TwistSource.html +13 -0
- package/dist/docs/interfaces/utils_types.ToolShed.html +11 -0
- package/dist/docs/modules/common_calendar.html +1 -0
- package/dist/docs/modules/index.html +1 -0
- package/dist/docs/modules/plot.html +1 -0
- package/dist/docs/modules/tag.html +1 -0
- package/dist/docs/modules/tool.html +1 -0
- package/dist/docs/modules/tools_ai.html +1 -0
- package/dist/docs/modules/tools_callbacks.html +1 -0
- package/dist/docs/modules/tools_integrations.html +1 -0
- package/dist/docs/modules/tools_network.html +1 -0
- package/dist/docs/modules/tools_plot.html +1 -0
- package/dist/docs/modules/tools_store.html +1 -0
- package/dist/docs/modules/tools_tasks.html +1 -0
- package/dist/docs/modules/tools_twists.html +1 -0
- package/dist/docs/modules/twist.html +1 -0
- package/dist/docs/modules/utils_types.html +1 -0
- package/dist/docs/modules.html +1 -0
- package/dist/docs/types/common_calendar.CalendarAuth.html +7 -0
- package/dist/docs/types/plot.Activity.html +64 -0
- package/dist/docs/types/plot.ActivityLink.html +22 -0
- package/dist/docs/types/plot.ActivityMeta.html +11 -0
- package/dist/docs/types/plot.ActivityUpdate.html +13 -0
- package/dist/docs/types/plot.Actor.html +15 -0
- package/dist/docs/types/plot.ActorId.html +4 -0
- package/dist/docs/types/plot.NewActivity.html +16 -0
- package/dist/docs/types/plot.NewContact.html +13 -0
- package/dist/docs/types/plot.NewPriority.html +5 -0
- package/dist/docs/types/plot.NoteType.html +1 -0
- package/dist/docs/types/plot.PickPriorityConfig.html +22 -0
- package/dist/docs/types/plot.Priority.html +8 -0
- package/dist/docs/types/tools_ai.AIAssistantMessage.html +4 -0
- package/dist/docs/types/tools_ai.AIMessage.html +3 -0
- package/dist/docs/types/tools_ai.AISource.html +11 -0
- package/dist/docs/types/tools_ai.AISystemMessage.html +7 -0
- package/dist/docs/types/tools_ai.AITool.html +19 -0
- package/dist/docs/types/tools_ai.AIToolMessage.html +4 -0
- package/dist/docs/types/tools_ai.AIToolSet.html +1 -0
- package/dist/docs/types/tools_ai.AIUsage.html +10 -0
- package/dist/docs/types/tools_ai.AIUserMessage.html +4 -0
- package/dist/docs/types/tools_ai.DataContent.html +2 -0
- package/dist/docs/types/tools_ai.ModelPreferences.html +24 -0
- package/dist/docs/types/tools_callbacks.Callback.html +8 -0
- package/dist/docs/types/tools_integrations.AuthToken.html +16 -0
- package/dist/docs/types/tools_integrations.Authorization.html +10 -0
- package/dist/docs/types/tools_network.WebhookRequest.html +15 -0
- package/dist/docs/types/tools_plot.ActivityIntentHandler.html +9 -0
- package/dist/docs/types/tools_twists.Log.html +6 -0
- package/dist/docs/types/tools_twists.TwistPermissions.html +12 -0
- package/dist/docs/types/utils_types.BuiltInTools.html +5 -0
- package/dist/docs/types/utils_types.CallbackMethods.html +3 -0
- package/dist/docs/types/utils_types.ExtractBuildReturn.html +2 -0
- package/dist/docs/types/utils_types.InferOptions.html +2 -0
- package/dist/docs/types/utils_types.InferTools.html +3 -0
- package/dist/docs/types/utils_types.NoFunctions.html +3 -0
- package/dist/docs/types/utils_types.NonFunction.html +2 -0
- package/dist/docs/types/utils_types.PromiseValues.html +3 -0
- package/dist/docs/types/utils_types.ToolBuilder.html +3 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-docs/common/calendar.d.ts +9 -0
- package/dist/llm-docs/common/calendar.d.ts.map +1 -0
- package/dist/llm-docs/common/calendar.js +8 -0
- package/dist/llm-docs/common/calendar.js.map +1 -0
- package/dist/llm-docs/common/messaging.d.ts +9 -0
- package/dist/llm-docs/common/messaging.d.ts.map +1 -0
- package/dist/llm-docs/common/messaging.js +8 -0
- package/dist/llm-docs/common/messaging.js.map +1 -0
- package/dist/llm-docs/creator-docs.d.ts +9 -0
- package/dist/llm-docs/creator-docs.d.ts.map +1 -0
- package/dist/llm-docs/creator-docs.js +8 -0
- package/dist/llm-docs/creator-docs.js.map +1 -0
- package/dist/llm-docs/index.d.ts +11 -0
- package/dist/llm-docs/index.d.ts.map +1 -0
- package/dist/llm-docs/index.js +42 -0
- package/dist/llm-docs/index.js.map +1 -0
- package/dist/llm-docs/plot.d.ts +9 -0
- package/dist/llm-docs/plot.d.ts.map +1 -0
- package/dist/llm-docs/plot.js +8 -0
- package/dist/llm-docs/plot.js.map +1 -0
- package/dist/llm-docs/tag.d.ts +9 -0
- package/dist/llm-docs/tag.d.ts.map +1 -0
- package/dist/llm-docs/tag.js +8 -0
- package/dist/llm-docs/tag.js.map +1 -0
- package/dist/llm-docs/tool.d.ts +9 -0
- package/dist/llm-docs/tool.d.ts.map +1 -0
- package/dist/llm-docs/tool.js +8 -0
- package/dist/llm-docs/tool.js.map +1 -0
- package/dist/llm-docs/tools/ai.d.ts +9 -0
- package/dist/llm-docs/tools/ai.d.ts.map +1 -0
- package/dist/llm-docs/tools/ai.js +8 -0
- package/dist/llm-docs/tools/ai.js.map +1 -0
- package/dist/llm-docs/tools/callbacks.d.ts +9 -0
- package/dist/llm-docs/tools/callbacks.d.ts.map +1 -0
- package/dist/llm-docs/tools/callbacks.js +8 -0
- package/dist/llm-docs/tools/callbacks.js.map +1 -0
- package/dist/llm-docs/tools/integrations.d.ts +9 -0
- package/dist/llm-docs/tools/integrations.d.ts.map +1 -0
- package/dist/llm-docs/tools/integrations.js +8 -0
- package/dist/llm-docs/tools/integrations.js.map +1 -0
- package/dist/llm-docs/tools/network.d.ts +9 -0
- package/dist/llm-docs/tools/network.d.ts.map +1 -0
- package/dist/llm-docs/tools/network.js +8 -0
- package/dist/llm-docs/tools/network.js.map +1 -0
- package/dist/llm-docs/tools/plot.d.ts +9 -0
- package/dist/llm-docs/tools/plot.d.ts.map +1 -0
- package/dist/llm-docs/tools/plot.js +8 -0
- package/dist/llm-docs/tools/plot.js.map +1 -0
- package/dist/llm-docs/tools/store.d.ts +9 -0
- package/dist/llm-docs/tools/store.d.ts.map +1 -0
- package/dist/llm-docs/tools/store.js +8 -0
- package/dist/llm-docs/tools/store.js.map +1 -0
- package/dist/llm-docs/tools/tasks.d.ts +9 -0
- package/dist/llm-docs/tools/tasks.d.ts.map +1 -0
- package/dist/llm-docs/tools/tasks.js +8 -0
- package/dist/llm-docs/tools/tasks.js.map +1 -0
- package/dist/llm-docs/tools/twists.d.ts +9 -0
- package/dist/llm-docs/tools/twists.d.ts.map +1 -0
- package/dist/llm-docs/tools/twists.js +8 -0
- package/dist/llm-docs/tools/twists.js.map +1 -0
- package/dist/llm-docs/twist-guide-template.d.ts +9 -0
- package/dist/llm-docs/twist-guide-template.d.ts.map +1 -0
- package/dist/llm-docs/twist-guide-template.js +8 -0
- package/dist/llm-docs/twist-guide-template.js.map +1 -0
- package/dist/llm-docs/twist.d.ts +9 -0
- package/dist/llm-docs/twist.d.ts.map +1 -0
- package/dist/llm-docs/twist.js +8 -0
- package/dist/llm-docs/twist.js.map +1 -0
- package/dist/plot.d.ts +463 -0
- package/dist/plot.d.ts.map +1 -0
- package/dist/plot.js +68 -0
- package/dist/plot.js.map +1 -0
- package/dist/tag.d.ts +47 -0
- package/dist/tag.d.ts.map +1 -0
- package/dist/tag.js +51 -0
- package/dist/tag.js.map +1 -0
- package/dist/tool.d.ts +242 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +283 -0
- package/dist/tool.js.map +1 -0
- package/dist/tools/ai.d.ts +697 -0
- package/dist/tools/ai.d.ts.map +1 -0
- package/dist/tools/ai.js +104 -0
- package/dist/tools/ai.js.map +1 -0
- package/dist/tools/callbacks.d.ts +96 -0
- package/dist/tools/callbacks.d.ts.map +1 -0
- package/dist/tools/callbacks.js +40 -0
- package/dist/tools/callbacks.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/integrations.d.ts +142 -0
- package/dist/tools/integrations.d.ts.map +1 -0
- package/dist/tools/integrations.js +79 -0
- package/dist/tools/integrations.js.map +1 -0
- package/dist/tools/network.d.ts +188 -0
- package/dist/tools/network.d.ts.map +1 -0
- package/dist/tools/network.js +87 -0
- package/dist/tools/network.js.map +1 -0
- package/dist/tools/plot.d.ts +252 -0
- package/dist/tools/plot.d.ts.map +1 -0
- package/dist/tools/plot.js +72 -0
- package/dist/tools/plot.js.map +1 -0
- package/dist/tools/store.d.ts +90 -0
- package/dist/tools/store.d.ts.map +1 -0
- package/dist/tools/store.js +48 -0
- package/dist/tools/store.js.map +1 -0
- package/dist/tools/tasks.d.ts +93 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +58 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/twists.d.ts +213 -0
- package/dist/tools/twists.d.ts.map +1 -0
- package/dist/tools/twists.js +26 -0
- package/dist/tools/twists.js.map +1 -0
- package/dist/twist-guide.d.ts +2 -0
- package/dist/twist-guide.d.ts.map +1 -0
- package/dist/twist-guide.js +9 -0
- package/dist/twist-guide.js.map +1 -0
- package/dist/twist.d.ts +204 -0
- package/dist/twist.d.ts.map +1 -0
- package/dist/twist.js +216 -0
- package/dist/twist.js.map +1 -0
- package/dist/utils/types.d.ts +91 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +206 -0
- package/tsconfig.base.json +28 -0
package/bin/index.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const twist_logs_1 = require("./commands/twist-logs");
|
|
8
|
+
const build_1 = require("./commands/build");
|
|
9
|
+
const create_1 = require("./commands/create");
|
|
10
|
+
const deploy_1 = require("./commands/deploy");
|
|
11
|
+
const generate_1 = require("./commands/generate");
|
|
12
|
+
const lint_1 = require("./commands/lint");
|
|
13
|
+
const login_1 = require("./commands/login");
|
|
14
|
+
const priority_create_1 = require("./commands/priority-create");
|
|
15
|
+
const priority_list_1 = require("./commands/priority-list");
|
|
16
|
+
const output_1 = require("./utils/output");
|
|
17
|
+
// Get the version from package.json
|
|
18
|
+
const packageJsonPath = (0, path_1.join)(__dirname, "..", "package.json");
|
|
19
|
+
const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, "utf-8"));
|
|
20
|
+
const version = packageJson.version;
|
|
21
|
+
// Display CLI header
|
|
22
|
+
(0, output_1.cliHeader)(version);
|
|
23
|
+
const program = new commander_1.Command();
|
|
24
|
+
program
|
|
25
|
+
.name("plot")
|
|
26
|
+
.description("CLI tool for building and deploying Plot twists")
|
|
27
|
+
.version(version)
|
|
28
|
+
.addOption(new commander_1.Option("--api-url <url>", "API endpoint URL")
|
|
29
|
+
.default(process.env.PLOT_API_URL || "https://api.plot.day")
|
|
30
|
+
.hideHelp())
|
|
31
|
+
.addOption(new commander_1.Option("--site-url <url>", "Site endpoint URL")
|
|
32
|
+
.default(process.env.PLOT_SITE_URL || "https://plot.day")
|
|
33
|
+
.hideHelp());
|
|
34
|
+
// Top-level login command
|
|
35
|
+
program
|
|
36
|
+
.command("login")
|
|
37
|
+
.description("Authenticate with Plot to generate an API token")
|
|
38
|
+
.action(function () {
|
|
39
|
+
const opts = this.optsWithGlobals();
|
|
40
|
+
return (0, login_1.loginCommand)(opts);
|
|
41
|
+
});
|
|
42
|
+
// Top-level create command
|
|
43
|
+
program
|
|
44
|
+
.command("create")
|
|
45
|
+
.description("Create a new Plot twist")
|
|
46
|
+
.option("-d, --dir <directory>", "Directory to create the twist in")
|
|
47
|
+
.option("-n, --name <name>", "Package name (kebab-case)")
|
|
48
|
+
.option("--display-name <displayName>", "Display name for the twist")
|
|
49
|
+
.action(create_1.createCommand);
|
|
50
|
+
// Top-level lint command
|
|
51
|
+
program
|
|
52
|
+
.command("lint")
|
|
53
|
+
.description("Check for build or lint errors")
|
|
54
|
+
.option("-d, --dir <directory>", "Twist directory to lint", process.cwd())
|
|
55
|
+
.action(lint_1.lintCommand);
|
|
56
|
+
// Top-level build command
|
|
57
|
+
program
|
|
58
|
+
.command("build")
|
|
59
|
+
.description("Bundle the twist without deploying")
|
|
60
|
+
.option("-d, --dir <directory>", "Twist directory to build", process.cwd())
|
|
61
|
+
.action(build_1.buildCommand);
|
|
62
|
+
// Top-level generate command
|
|
63
|
+
program
|
|
64
|
+
.command("generate")
|
|
65
|
+
.description("Generate twist code from a spec file")
|
|
66
|
+
.option("-d, --dir <directory>", "Twist directory to generate in", process.cwd())
|
|
67
|
+
.option("--spec <file>", "Spec file to generate from (defaults to plot-twist.md)")
|
|
68
|
+
.option("--id <twistId>", "Twist ID")
|
|
69
|
+
.option("--deploy-token <token>", "Authentication token")
|
|
70
|
+
.action(function () {
|
|
71
|
+
const opts = this.optsWithGlobals();
|
|
72
|
+
return (0, generate_1.generateCommand)(opts);
|
|
73
|
+
});
|
|
74
|
+
// Top-level deploy command
|
|
75
|
+
program
|
|
76
|
+
.command("deploy")
|
|
77
|
+
.description("Bundle and deploy the twist")
|
|
78
|
+
.option("-d, --dir <directory>", "Twist directory to deploy", process.cwd())
|
|
79
|
+
.option("--id <twistId>", "Twist ID for deployment")
|
|
80
|
+
.option("--deploy-token <token>", "Authentication token for deployment")
|
|
81
|
+
.option("--name <name>", "Twist name")
|
|
82
|
+
.option("--description <description>", "Twist description")
|
|
83
|
+
.option("--dry-run", "Validate without deploying")
|
|
84
|
+
.option("-e, --environment <env>", "Deployment environment (personal, private, review)", "personal")
|
|
85
|
+
.action(function () {
|
|
86
|
+
const opts = this.optsWithGlobals();
|
|
87
|
+
return (0, deploy_1.deployCommand)(opts);
|
|
88
|
+
});
|
|
89
|
+
// Top-level logs command
|
|
90
|
+
program
|
|
91
|
+
.command("logs [twist-id]")
|
|
92
|
+
.description("Stream real-time logs from a twist")
|
|
93
|
+
.option("-d, --dir <directory>", "Twist directory", process.cwd())
|
|
94
|
+
.option("--id <twistId>", "Twist ID")
|
|
95
|
+
.option("-e, --environment <env>", "Twist environment (personal, private, review)", "personal")
|
|
96
|
+
.option("--deploy-token <token>", "Authentication token")
|
|
97
|
+
.action(function (twistId) {
|
|
98
|
+
const opts = this.optsWithGlobals();
|
|
99
|
+
return (0, twist_logs_1.twistLogsCommand)({
|
|
100
|
+
twistId,
|
|
101
|
+
id: opts.id,
|
|
102
|
+
dir: opts.dir,
|
|
103
|
+
environment: opts.environment,
|
|
104
|
+
deployToken: opts.deployToken,
|
|
105
|
+
apiUrl: opts.apiUrl,
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
// Priority subcommand group
|
|
109
|
+
const priority = program
|
|
110
|
+
.command("priority")
|
|
111
|
+
.description("Manage Plot priorities");
|
|
112
|
+
priority
|
|
113
|
+
.command("create")
|
|
114
|
+
.description("Create a new priority")
|
|
115
|
+
.option("--name <name>", "Priority name")
|
|
116
|
+
.option("--parent-id <parentId>", "Parent priority ID")
|
|
117
|
+
.action(function () {
|
|
118
|
+
const opts = this.optsWithGlobals();
|
|
119
|
+
return (0, priority_create_1.priorityCreateCommand)(opts);
|
|
120
|
+
});
|
|
121
|
+
priority
|
|
122
|
+
.command("list")
|
|
123
|
+
.description("List all your priorities")
|
|
124
|
+
.action(function () {
|
|
125
|
+
const opts = this.optsWithGlobals();
|
|
126
|
+
return (0, priority_list_1.priorityListCommand)(opts);
|
|
127
|
+
});
|
|
128
|
+
program.parse();
|
|
129
|
+
//# sourceMappingURL=index.js.map
|
package/bin/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../cli/index.ts"],"names":[],"mappings":"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"}
|
package/bin/package.json
ADDED
package/bin/plot.cjs
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# Twist Implementation Guide for LLMs
|
|
2
|
+
|
|
3
|
+
This document provides context for AI assistants generating or modifying twists.
|
|
4
|
+
|
|
5
|
+
## Architecture Overview
|
|
6
|
+
|
|
7
|
+
Plot Twists are TypeScript classes that extend the `Twist` base class. Twists interact with external services and Plot's core functionality through a tool-based architecture.
|
|
8
|
+
|
|
9
|
+
### Runtime Environment
|
|
10
|
+
|
|
11
|
+
**Critical**: All Twists and tool functions are executed in a sandboxed, ephemeral environment with limited resources:
|
|
12
|
+
|
|
13
|
+
- **Memory is temporary**: Anything stored in memory (e.g. as a variable in the twist/tool object) is lost after the function completes. Use the Store tool instead. Only use memory for temporary caching.
|
|
14
|
+
- **Limited CPU time**: Each execution has limited CPU time (typically 10 seconds) and memory (128MB)
|
|
15
|
+
- **Use the Run tool**: Queue separate chunks of work with `run.now(functionName, context)`
|
|
16
|
+
- **Break long operations**: Split large operations into smaller batches that can be processed independently
|
|
17
|
+
- **Store intermediate state**: Use the Store tool to persist state between batches
|
|
18
|
+
- **Examples**: Syncing large datasets, processing many API calls, or performing batch operations
|
|
19
|
+
|
|
20
|
+
## twist Structure Pattern
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import {
|
|
24
|
+
type Activity,
|
|
25
|
+
twist,
|
|
26
|
+
type Priority,
|
|
27
|
+
type ToolBuilder,
|
|
28
|
+
} from "@plotday/twister";
|
|
29
|
+
import { Plot } from "@plotday/twister/tools/plot";
|
|
30
|
+
|
|
31
|
+
export default class MyTwist extends twist<MyTwist> {
|
|
32
|
+
build(build: ToolBuilder) {
|
|
33
|
+
return {
|
|
34
|
+
plot: build(Plot),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async activate(priority: Pick<Priority, "id">) {
|
|
39
|
+
// Called when twist is enabled for a priority
|
|
40
|
+
// Common actions: request auth, create setup activities
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async activity(activity: Activity) {
|
|
44
|
+
// Called when an activity is routed to this twist
|
|
45
|
+
// Common actions: process external events, update activities
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Tool System
|
|
51
|
+
|
|
52
|
+
### Accessing Tools
|
|
53
|
+
|
|
54
|
+
All tools are declared in the `build` method:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
build(build: ToolBuilder) {
|
|
58
|
+
return {
|
|
59
|
+
toolName: build(ToolClass),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
All `build()` calls must occur in the `build` method as they are used for dependency analysis.
|
|
65
|
+
|
|
66
|
+
IMPORTANT: HTTP access is restricted to URLs requested via `build(Network, { urls: [url1, url2, ...] })` in the `build` method. Wildcards are supported. Use `build(Network, { urls: ['*'] })` if full access is needed.
|
|
67
|
+
|
|
68
|
+
### Built-in Tools (Always Available)
|
|
69
|
+
|
|
70
|
+
For complete API documentation of built-in tools including all methods, types, and detailed examples, see the TypeScript definitions in your installed package at `node_modules/@plotday/twister/src/tools/*.ts`. Each tool file contains comprehensive JSDoc documentation.
|
|
71
|
+
|
|
72
|
+
**Quick reference - Available tools:**
|
|
73
|
+
|
|
74
|
+
- `@plotday/twister/tools/plot` - Core data layer (create/update activities, priorities, contacts)
|
|
75
|
+
- `@plotday/twister/tools/ai` - LLM integration (text generation, structured output, reasoning)
|
|
76
|
+
- Use ModelPreferences to specify `speed` (fast/balanced/capable) and `cost` (low/medium/high)
|
|
77
|
+
- `@plotday/twister/tools/store` - Persistent key-value storage (also via `this.set()`, `this.get()`)
|
|
78
|
+
- `@plotday/twister/tools/tasks` - Queue batched work (also via `this.run()`)
|
|
79
|
+
- `@plotday/twister/tools/callbacks` - Persistent function references (also via `this.callback()`)
|
|
80
|
+
- `@plotday/twister/tools/integrations` - OAuth2 authentication flows
|
|
81
|
+
- `@plotday/twister/tools/network` - HTTP access permissions and webhook management
|
|
82
|
+
- `@plotday/twister/tools/twists` - Manage other Twists
|
|
83
|
+
|
|
84
|
+
**Critical**: Never use instance variables for state. They are lost after function execution. Always use Store methods.
|
|
85
|
+
|
|
86
|
+
### External Tools (Add to package.json)
|
|
87
|
+
|
|
88
|
+
Add tool dependencies to `package.json`:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"dependencies": {
|
|
93
|
+
"@plotday/twister": "workspace:^",
|
|
94
|
+
"@plotday/tool-google-calendar": "workspace:^"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Common External Tools
|
|
100
|
+
|
|
101
|
+
- `@plotday/tool-google-calendar`: Google Calendar integration
|
|
102
|
+
- `@plotday/tool-outlook-calendar`: Outlook Calendar integration
|
|
103
|
+
- `@plotday/tool-google-contacts`: Google Contacts integration
|
|
104
|
+
|
|
105
|
+
## Lifecycle Methods
|
|
106
|
+
|
|
107
|
+
### activate(priority: Pick<Priority, "id">)
|
|
108
|
+
|
|
109
|
+
Called when the twist is enabled for a priority. Common patterns:
|
|
110
|
+
|
|
111
|
+
**Request Authentication:**
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
async activate(_priority: Pick<Priority, "id">) {
|
|
115
|
+
const authLink = await this.tools.externalTool.requestAuth(
|
|
116
|
+
this.onAuthComplete,
|
|
117
|
+
"google"
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
await this.tools.plot.createActivity({
|
|
121
|
+
type: ActivityType.Task,
|
|
122
|
+
title: "Connect your account",
|
|
123
|
+
links: [authLink],
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Store Parent Activity for Later:**
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const activity = await this.tools.plot.createActivity({
|
|
132
|
+
type: ActivityType.Task,
|
|
133
|
+
title: "Setup",
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await this.set("setup_activity_id", activity.id);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### activity(activity: Activity)
|
|
140
|
+
|
|
141
|
+
Called when an activity is routed to the twist. Common patterns:
|
|
142
|
+
|
|
143
|
+
**Create Activities from External Events:**
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
async activity(activity: Activity) {
|
|
147
|
+
await this.tools.plot.createActivity(activity);
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Update Based on User Action:**
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
async activity(activity: Activity) {
|
|
155
|
+
if (activity.completed) {
|
|
156
|
+
await this.handleCompletion(activity);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Activity Links
|
|
162
|
+
|
|
163
|
+
Activity links enable user interaction:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { type ActivityLink, ActivityLinkType } from "@plotday/twister";
|
|
167
|
+
|
|
168
|
+
// URL link
|
|
169
|
+
const urlLink: ActivityLink = {
|
|
170
|
+
title: "Open website",
|
|
171
|
+
type: ActivityLinkType.url,
|
|
172
|
+
url: "https://example.com",
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Callback link (uses Callbacks tool)
|
|
176
|
+
const token = await this.callback(this.onLinkClicked, "context");
|
|
177
|
+
const callbackLink: ActivityLink = {
|
|
178
|
+
title: "Click me",
|
|
179
|
+
type: ActivityLinkType.callback,
|
|
180
|
+
token: token,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Add to activity
|
|
184
|
+
await this.tools.plot.createActivity({
|
|
185
|
+
type: ActivityType.Task,
|
|
186
|
+
title: "Task with links",
|
|
187
|
+
links: [urlLink, callbackLink],
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Authentication Pattern
|
|
192
|
+
|
|
193
|
+
Common pattern for OAuth authentication:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
async activate(_priority: Pick<Priority, "id">) {
|
|
197
|
+
// Request auth link from tool with callback
|
|
198
|
+
const authLink = await this.tools.googleTool.requestAuth(
|
|
199
|
+
this.onAuthComplete,
|
|
200
|
+
"google"
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// Create activity with auth link
|
|
204
|
+
const activity = await this.tools.plot.createActivity({
|
|
205
|
+
type: ActivityType.Task,
|
|
206
|
+
title: "Connect Google account",
|
|
207
|
+
links: [authLink],
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Store for later use
|
|
211
|
+
await this.set("auth_activity_id", activity.id);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async onAuthComplete(authResult: { authToken: string }, provider: string) {
|
|
215
|
+
// Store auth token
|
|
216
|
+
await this.set(`${provider}_auth`, authResult.authToken);
|
|
217
|
+
|
|
218
|
+
// Continue setup flow
|
|
219
|
+
await this.setupSyncOptions(authResult.authToken);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Sync Pattern
|
|
224
|
+
|
|
225
|
+
Pattern for syncing external data with callbacks:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
async startSync(calendarId: string): Promise<void> {
|
|
229
|
+
const authToken = await this.get<string>("auth_token");
|
|
230
|
+
|
|
231
|
+
await this.tools.calendarTool.startSync(
|
|
232
|
+
authToken,
|
|
233
|
+
calendarId,
|
|
234
|
+
this.handleEvent,
|
|
235
|
+
calendarId
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async handleEvent(activity: Activity, calendarId: string): Promise<void> {
|
|
240
|
+
// Process incoming event from external service
|
|
241
|
+
await this.tools.plot.createActivity(activity);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async stopSync(calendarId: string): Promise<void> {
|
|
245
|
+
const authToken = await this.get<string>("auth_token");
|
|
246
|
+
await this.tools.calendarTool.stopSync(authToken, calendarId);
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Calendar Selection Pattern
|
|
251
|
+
|
|
252
|
+
Pattern for letting users select from multiple calendars/accounts:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
private async createCalendarSelectionActivity(
|
|
256
|
+
provider: string,
|
|
257
|
+
calendars: Calendar[],
|
|
258
|
+
authToken: string
|
|
259
|
+
): Promise<void> {
|
|
260
|
+
const links: ActivityLink[] = [];
|
|
261
|
+
|
|
262
|
+
for (const calendar of calendars) {
|
|
263
|
+
const token = await this.callback(
|
|
264
|
+
this.onCalendarSelected,
|
|
265
|
+
provider,
|
|
266
|
+
calendar.id,
|
|
267
|
+
calendar.name,
|
|
268
|
+
authToken
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
links.push({
|
|
272
|
+
title: `📅 ${calendar.name}${calendar.primary ? " (Primary)" : ""}`,
|
|
273
|
+
type: ActivityLinkType.callback,
|
|
274
|
+
token: token,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
await this.tools.plot.createActivity({
|
|
279
|
+
type: ActivityType.Note,
|
|
280
|
+
title: "Which calendars would you like to connect?",
|
|
281
|
+
links,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async onCalendarSelected(
|
|
286
|
+
link: ActivityLink,
|
|
287
|
+
provider: string,
|
|
288
|
+
calendarId: string,
|
|
289
|
+
calendarName: string,
|
|
290
|
+
authToken: string
|
|
291
|
+
): Promise<void> {
|
|
292
|
+
// Start sync for selected calendar
|
|
293
|
+
await this.tools.tool.startSync(
|
|
294
|
+
authToken,
|
|
295
|
+
calendarId,
|
|
296
|
+
this.handleEvent,
|
|
297
|
+
provider,
|
|
298
|
+
calendarId
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Batch Processing Pattern
|
|
304
|
+
|
|
305
|
+
**Important**: Because Twists run in an ephemeral environment with limited execution time, you must break long operations into batches. Each batch runs independently in a new execution context.
|
|
306
|
+
|
|
307
|
+
### Key Principles
|
|
308
|
+
|
|
309
|
+
1. **Store state between batches**: Use the Store tool to persist progress
|
|
310
|
+
2. **Queue next batch**: Use the Run tool to schedule the next chunk
|
|
311
|
+
3. **Clean up when done**: Delete stored state after completion
|
|
312
|
+
4. **Handle failures**: Store enough state to resume if a batch fails
|
|
313
|
+
|
|
314
|
+
### Example Implementation
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
async startSync(resourceId: string): Promise<void> {
|
|
318
|
+
// Initialize state in Store (persists between executions)
|
|
319
|
+
await this.set(`sync_state_${resourceId}`, {
|
|
320
|
+
nextPageToken: null,
|
|
321
|
+
batchNumber: 1,
|
|
322
|
+
itemsProcessed: 0,
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// Queue first batch using runTask method
|
|
326
|
+
const callback = await this.callback(this.syncBatch, resourceId);
|
|
327
|
+
await this.runTask(callback);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async syncBatch(args: any, resourceId: string): Promise<void> {
|
|
331
|
+
// Load state from Store (set by previous execution)
|
|
332
|
+
const state = await this.get(`sync_state_${resourceId}`);
|
|
333
|
+
|
|
334
|
+
// Process one batch (keep under time limit)
|
|
335
|
+
const result = await this.fetchBatch(state.nextPageToken);
|
|
336
|
+
|
|
337
|
+
// Process results
|
|
338
|
+
for (const item of result.items) {
|
|
339
|
+
await this.tools.plot.createActivity(item);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (result.nextPageToken) {
|
|
343
|
+
// Update state in Store for next batch
|
|
344
|
+
await this.set(`sync_state_${resourceId}`, {
|
|
345
|
+
nextPageToken: result.nextPageToken,
|
|
346
|
+
batchNumber: state.batchNumber + 1,
|
|
347
|
+
itemsProcessed: state.itemsProcessed + result.items.length,
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// Queue next batch (runs in new execution context)
|
|
351
|
+
const nextCallback = await this.callback(this.syncBatch, resourceId);
|
|
352
|
+
await this.runTask(nextCallback);
|
|
353
|
+
} else {
|
|
354
|
+
// Cleanup when complete
|
|
355
|
+
await this.clear(`sync_state_${resourceId}`);
|
|
356
|
+
|
|
357
|
+
// Optionally notify user of completion
|
|
358
|
+
await this.tools.plot.createActivity({
|
|
359
|
+
type: ActivityType.Note,
|
|
360
|
+
note: `Sync complete: ${state.itemsProcessed + result.items.length} items processed`,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## Error Handling
|
|
367
|
+
|
|
368
|
+
Always handle errors gracefully and communicate them to users:
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
try {
|
|
372
|
+
await this.externalOperation();
|
|
373
|
+
} catch (error) {
|
|
374
|
+
console.error("Operation failed:", error);
|
|
375
|
+
|
|
376
|
+
await this.tools.plot.createActivity({
|
|
377
|
+
type: ActivityType.Note,
|
|
378
|
+
note: `Failed to complete operation: ${error.message}`,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Common Pitfalls
|
|
384
|
+
|
|
385
|
+
- **Don't use instance variables for state** - Anything stored in memory is lost after function execution. Always use the Store tool for data that needs to persist.
|
|
386
|
+
- **Processing self-created activities** - Other users may change an Activity created by the twist, resulting in an \`activity\` call. Be sure to check the \`changes === null\` and/or \`activity.author.id !== this.id\` to avoid re-processing.
|
|
387
|
+
- Most activity should be `type = ActivityType.Note` with a `title` and `note`, and no `start` or `end`. This represents a typical message. `start` and `end` should only be used for a note if it should be displayed for a specific date or time, such as a birthday.
|
|
388
|
+
- Tools are declared in the `build` method and accessed via `this.tools.toolName` in twist methods.
|
|
389
|
+
- **Don't forget runtime limits** - Each execution has ~10 seconds. Break long operations into batches with the Tasks tool. Process enough items per batch to be efficient, but few enough to stay under time limits.
|
|
390
|
+
- **Always use Callbacks tool for persistent references** - Direct function references don't survive worker restarts.
|
|
391
|
+
- **Store auth tokens** - Don't re-request authentication unnecessarily.
|
|
392
|
+
- **Clean up callbacks and stored state** - Delete callbacks and Store entries when no longer needed.
|
|
393
|
+
- **Handle missing auth gracefully** - Check for stored auth before operations.
|
|
394
|
+
|
|
395
|
+
## Testing
|
|
396
|
+
|
|
397
|
+
Before deploying, verify:
|
|
398
|
+
|
|
399
|
+
1. Linting passes: `{{packageManager}} lint`
|
|
400
|
+
2. All dependencies are in package.json
|
|
401
|
+
3. Authentication flow works end-to-end
|
|
402
|
+
4. Batch operations handle pagination correctly
|
|
403
|
+
5. Error cases are handled gracefully
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|