@hitch42/applet 0.1.1-beta.6 → 0.1.1-beta.8
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/_internal/server.d.ts +14 -1
- package/dist/_internal/server.js +23 -74
- package/dist/applet.js +50 -29
- package/dist/build-CFCKKMn7.js +2 -0
- package/dist/{build-DIsKQQT0.js → build-DANx9Hgg.js} +28 -13
- package/dist/{ci-D0nC_Ho7.js → ci-5qWl7lT3.js} +20 -4
- package/dist/client.d.ts +2 -2
- package/dist/{contract-DMrpbaLJ.d.ts → contract-rP_eV9PK.d.ts} +1 -1
- package/dist/{deploy-0dlUvCt3.js → deploy-MQWLG2EA.js} +130 -15
- package/dist/email-DBTVhNB_.js +62 -0
- package/dist/{generate-C6eAL5eo.js → generate-BxYHdoAQ.js} +18 -17
- package/dist/generate-CQ07Hdpo.js +2 -0
- package/dist/index.d.ts +115 -4
- package/dist/index.js +141 -26
- package/dist/{init-tEMeys9M.js → init-jDEgYIXg.js} +5 -5
- package/dist/load-config-BYSxDVAl.js +27 -0
- package/dist/login-C7RKmmTe.js +12 -0
- package/dist/{logs-m00pzr_O.js → logs-DgjgAxj2.js} +3 -3
- package/dist/{manifest-DyoJ1MIL.js → manifest-Bp87Uz0a.js} +6 -0
- package/dist/{manifest-BQCAxATS.d.ts → manifest-DD_SGkS6.d.ts} +5 -0
- package/dist/me-BW7Paary.js +32 -0
- package/dist/{project-mW0vsN8A.js → project-CbYPtpPq.js} +16 -14
- package/dist/prompt-ChS-grYO.js +29 -0
- package/dist/schedules-dhU1yyFr.js +42 -0
- package/dist/server.d.ts +2 -2
- package/dist/telephony-protocol-DRgiYjqQ.d.ts +74 -0
- package/dist/telephony.d.ts +77 -0
- package/dist/telephony.js +607 -0
- package/dist/{variables-CP7Ce3Np.js → variables-Bwnr7oxf.js} +3 -28
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +458 -27
- package/dist/workflow-engine-MogejNfF.js +117 -0
- package/dist/{auth-DaVK0k5R.js → workspace-XVtM12ZC.js} +44 -4
- package/package.json +6 -1
- package/scaffold/.agents/skills/hitch-applets/SKILL.md +32 -16
- package/scaffold/.agents/skills/hitch-applets/references/email-tracking.md +49 -0
- package/scaffold/.agents/skills/hitch-applets/references/files.md +3 -3
- package/scaffold/.agents/skills/hitch-applets/references/manifest.md +21 -2
- package/scaffold/.agents/skills/hitch-applets/references/performance.md +1 -1
- package/scaffold/.agents/skills/hitch-applets/references/records.md +4 -3
- package/scaffold/.agents/skills/hitch-applets/references/schedules.md +7 -2
- package/scaffold/.agents/skills/hitch-applets/references/server.md +0 -3
- package/scaffold/.agents/skills/hitch-applets/references/workflows.md +11 -3
- package/scaffold/.agents/skills/hitch-cli/SKILL.md +24 -22
- package/scaffold/.agents/skills/hitch-data/SKILL.md +2 -2
- package/scaffold/.agents/skills/hitch-data/references/limits.md +10 -10
- package/scaffold/.agents/skills/hitch-theory/SKILL.md +150 -0
- package/scaffold/.github/workflows/hitch.yml +0 -6
- package/dist/build-B70gkDi5.js +0 -2
- package/dist/generate-D5rSXXa-.js +0 -2
- package/dist/load-config-BnxocLAQ.js +0 -56
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as readWorkspaceConfig } from "./workspace-XVtM12ZC.js";
|
|
2
|
+
import { n as loadAppletSourceDefinition } from "./load-config-BYSxDVAl.js";
|
|
2
3
|
import { z } from "zod";
|
|
3
4
|
import { existsSync } from "node:fs";
|
|
4
5
|
import { cp, mkdir, readFile, rm, symlink, writeFile } from "node:fs/promises";
|
|
@@ -130,7 +131,8 @@ const GITIGNORE_END = "# END Hitch generated files";
|
|
|
130
131
|
const SKILLS = [
|
|
131
132
|
"hitch-applets",
|
|
132
133
|
"hitch-cli",
|
|
133
|
-
"hitch-data"
|
|
134
|
+
"hitch-data",
|
|
135
|
+
"hitch-theory"
|
|
134
136
|
];
|
|
135
137
|
const GITIGNORE = `${GITIGNORE_START}
|
|
136
138
|
${SKILLS.map((skill) => `/.agents/skills/${skill}/`).join("\n")}
|
|
@@ -178,7 +180,7 @@ async function writeWorkspaceSupport(root, config, cli) {
|
|
|
178
180
|
const agents = await readFile(new URL("../scaffold/AGENTS.md", import.meta.url), "utf8");
|
|
179
181
|
await Promise.all([
|
|
180
182
|
mkdir(resolve(root, ".agents/skills"), { recursive: true }),
|
|
181
|
-
mkdir(resolve(root, ".github/workflows"), { recursive: true }),
|
|
183
|
+
config.githubWorkflow === false ? void 0 : mkdir(resolve(root, ".github/workflows"), { recursive: true }),
|
|
182
184
|
...SKILLS.map((skill) => rm(resolve(root, ".agents/skills", skill), {
|
|
183
185
|
force: true,
|
|
184
186
|
recursive: true
|
|
@@ -188,7 +190,7 @@ async function writeWorkspaceSupport(root, config, cli) {
|
|
|
188
190
|
...SKILLS.map((skill) => cp(new URL(`../scaffold/.agents/skills/${skill}`, import.meta.url), resolve(root, ".agents/skills", skill), { recursive: true })),
|
|
189
191
|
writeFile(resolve(root, "package.json"), `${JSON.stringify(workspacePackage(config.org), null, 2)}\n`),
|
|
190
192
|
writeFile(resolve(root, "pnpm-workspace.yaml"), workspaceFile(resolvedCli)),
|
|
191
|
-
existsSync(deployWorkflowTarget) ? void 0 : cp(new URL("../scaffold/.github/workflows/hitch.yml", import.meta.url), deployWorkflowTarget),
|
|
193
|
+
config.githubWorkflow === false || existsSync(deployWorkflowTarget) ? void 0 : cp(new URL("../scaffold/.github/workflows/hitch.yml", import.meta.url), deployWorkflowTarget),
|
|
192
194
|
writeFile(resolve(root, ".node-version"), "24\n"),
|
|
193
195
|
writeGitignore(root),
|
|
194
196
|
writeFile(resolve(root, "AGENTS.md"), agents)
|
|
@@ -340,17 +342,17 @@ export default defineConfig({
|
|
|
340
342
|
hasClient ? writeFile(resolve(root, "components.json"), await readFile(new URL("../scaffold/applet/components.json", import.meta.url), "utf8")) : void 0
|
|
341
343
|
]);
|
|
342
344
|
}
|
|
343
|
-
async function
|
|
344
|
-
const
|
|
345
|
-
const workspaceRoot = dirname(dirname(resolve(appletRoot)));
|
|
345
|
+
async function prepareAppletProjects(workspaceRoot, appletRoots) {
|
|
346
|
+
const definitions = await Promise.all(appletRoots.map((root) => loadAppletSourceDefinition(root)));
|
|
346
347
|
const workspace = readWorkspaceConfig(workspaceRoot);
|
|
347
|
-
if (workspace === void 0) throw new Error(`No Hitch workspace found
|
|
348
|
+
if (workspace === void 0) throw new Error(`No Hitch workspace found at ${workspaceRoot}.`);
|
|
348
349
|
const cli = await loadCliManifest({ allowDevelopment: true });
|
|
349
|
-
await Promise.all([cli === void 0 ? void 0 : writeWorkspaceSupport(workspaceRoot, workspace, cli), writeAppletSupport(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
350
|
+
await Promise.all([cli === void 0 ? void 0 : writeWorkspaceSupport(workspaceRoot, workspace, cli), ...appletRoots.map((root, index) => writeAppletSupport(root, definitions[index]))]);
|
|
351
|
+
}
|
|
352
|
+
async function prepareAppletProject(appletRoot = process.cwd()) {
|
|
353
|
+
const workspaceRoot = dirname(dirname(resolve(appletRoot)));
|
|
354
|
+
await prepareAppletProjects(workspaceRoot, [appletRoot]);
|
|
355
|
+
return workspaceRoot;
|
|
354
356
|
}
|
|
355
357
|
//#endregion
|
|
356
|
-
export {
|
|
358
|
+
export { writeAppletSupport as a, prepareAppletProjects as i, loadCliManifest as n, writeWorkspaceSupport as o, prepareAppletProject as r, assertWorkspaceCli as t };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Writable } from "node:stream";
|
|
2
|
+
import { createInterface } from "node:readline";
|
|
3
|
+
//#region src/prompt.ts
|
|
4
|
+
function question(prompt, hidden = false) {
|
|
5
|
+
return new Promise((resolveAnswer, rejectAnswer) => {
|
|
6
|
+
let muted = false;
|
|
7
|
+
const output = hidden ? new Writable({ write(chunk, encoding, callback) {
|
|
8
|
+
if (!muted) process.stdout.write(chunk, encoding);
|
|
9
|
+
callback();
|
|
10
|
+
} }) : process.stdout;
|
|
11
|
+
const readline = createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output,
|
|
14
|
+
terminal: true
|
|
15
|
+
});
|
|
16
|
+
readline.once("error", rejectAnswer);
|
|
17
|
+
if (hidden) {
|
|
18
|
+
process.stdout.write(prompt);
|
|
19
|
+
muted = true;
|
|
20
|
+
}
|
|
21
|
+
readline.question(hidden ? "" : prompt, (answer) => {
|
|
22
|
+
readline.close();
|
|
23
|
+
if (hidden) process.stdout.write("\n");
|
|
24
|
+
resolveAnswer(answer);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { question as t };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { t as loadAppletConfig } from "./load-config-BYSxDVAl.js";
|
|
2
|
+
import { t as question } from "./prompt-ChS-grYO.js";
|
|
3
|
+
import { RPCLink } from "@orpc/client/fetch";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
//#region src/schedules.ts
|
|
7
|
+
async function runSchedule(options) {
|
|
8
|
+
const manifest = await loadAppletConfig(process.cwd());
|
|
9
|
+
const schedules = manifest.schedules ?? [];
|
|
10
|
+
if (schedules.length === 0) throw new Error("This applet has no schedules.");
|
|
11
|
+
const schedule = schedules.find(({ code }) => code === options.code);
|
|
12
|
+
if (schedule === void 0) throw new Error(`Unknown schedule "${options.code}". Valid codes: ${schedules.map(({ code }) => code).join(", ")}.`);
|
|
13
|
+
const unavailable = "The dev server is not running. Start it with pnpm dev.";
|
|
14
|
+
let url;
|
|
15
|
+
try {
|
|
16
|
+
const file = JSON.parse(await readFile(resolve(process.cwd(), ".hitch/dev-server.json"), "utf8"));
|
|
17
|
+
if (file === null || typeof file !== "object" || !("url" in file) || typeof file.url !== "string" || !("pid" in file) || typeof file.pid !== "number" || !Number.isInteger(file.pid) || file.pid < 1) throw new Error(unavailable);
|
|
18
|
+
try {
|
|
19
|
+
process.kill(file.pid, 0);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
if (!(error instanceof Error && "code" in error && error.code === "EPERM")) throw error;
|
|
22
|
+
}
|
|
23
|
+
url = new URL(file.url).origin;
|
|
24
|
+
} catch {
|
|
25
|
+
throw new Error(unavailable);
|
|
26
|
+
}
|
|
27
|
+
if (options.yes !== true) {
|
|
28
|
+
if (process.stdin.isTTY !== true) throw new Error("Pass --yes to run a schedule without a terminal.");
|
|
29
|
+
const answer = await question(`Run schedule "${options.code}" (${schedule.path}) now? It runs your local code as you in production org "${manifest.org}". [y/N] `);
|
|
30
|
+
if (!["y", "yes"].includes(answer.trim().toLowerCase())) throw new Error("Schedule run cancelled.");
|
|
31
|
+
}
|
|
32
|
+
await new RPCLink({
|
|
33
|
+
url: `${url}/${manifest.code}/api`,
|
|
34
|
+
fetch
|
|
35
|
+
}).call(schedule.path.split("/").filter(Boolean), {}, { context: {} }).catch((error) => {
|
|
36
|
+
if (error instanceof TypeError && error.message === "fetch failed") throw new Error(unavailable);
|
|
37
|
+
throw error;
|
|
38
|
+
});
|
|
39
|
+
console.log(`Schedule "${options.code}" finished.`);
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
export { runSchedule };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as createWorkflow, i as WorkflowStep, n as WorkflowDefinition, r as WorkflowDuration } from "./workflow-DurM6Fwx.js";
|
|
2
|
-
import { _ as RegisteredWorkflows, f as RegisteredContract, g as RegisteredVariables, p as RegisteredManifest } from "./manifest-
|
|
3
|
-
import { t as NarrowContract } from "./contract-
|
|
2
|
+
import { _ as RegisteredWorkflows, f as RegisteredContract, g as RegisteredVariables, p as RegisteredManifest } from "./manifest-DD_SGkS6.js";
|
|
3
|
+
import { t as NarrowContract } from "./contract-rP_eV9PK.js";
|
|
4
4
|
import { t as WithBatchRecorder } from "./batch-Qa4B4-Yp.js";
|
|
5
5
|
import { o as WithFilesUpload } from "./upload-YbRKEqR6.js";
|
|
6
6
|
import { ContractRouterClient } from "@orpc/contract";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ContractProcedure, Meta } from "@orpc/contract";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/hitch/email.d.ts
|
|
4
|
+
type EmailTags = Record<string, string>;
|
|
5
|
+
type CreateEmailPixelInput = {
|
|
6
|
+
tags?: EmailTags;
|
|
7
|
+
};
|
|
8
|
+
type CreateEmailPixelOutput = {
|
|
9
|
+
id: string;
|
|
10
|
+
url: string;
|
|
11
|
+
};
|
|
12
|
+
type GetEmailTrackerInput = {
|
|
13
|
+
id: string;
|
|
14
|
+
};
|
|
15
|
+
type MarkEmailTrackerSentInput = {
|
|
16
|
+
id: string;
|
|
17
|
+
sentAt?: string;
|
|
18
|
+
};
|
|
19
|
+
type EmailTracker = {
|
|
20
|
+
id: string;
|
|
21
|
+
url: string;
|
|
22
|
+
tags: EmailTags;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
sentAt: string | null;
|
|
25
|
+
firstHitAt: string | null;
|
|
26
|
+
lastHitAt: string | null;
|
|
27
|
+
};
|
|
28
|
+
type ListEmailTrackersInput = {
|
|
29
|
+
filter?: EmailTags;
|
|
30
|
+
sentAt?: {
|
|
31
|
+
$gte?: string;
|
|
32
|
+
$lt?: string;
|
|
33
|
+
};
|
|
34
|
+
cursor?: string;
|
|
35
|
+
limit?: number;
|
|
36
|
+
};
|
|
37
|
+
type ListEmailTrackersOutput = {
|
|
38
|
+
trackers: EmailTracker[];
|
|
39
|
+
nextCursor: string | null;
|
|
40
|
+
};
|
|
41
|
+
declare const emailTagKeySchema: z.ZodType<string>;
|
|
42
|
+
declare const emailTagsSchema: z.ZodType<EmailTags>;
|
|
43
|
+
declare const createEmailPixelInputSchema: z.ZodType<CreateEmailPixelInput>;
|
|
44
|
+
declare const createEmailPixelOutputSchema: z.ZodType<CreateEmailPixelOutput>;
|
|
45
|
+
declare const getEmailTrackerInputSchema: z.ZodType<GetEmailTrackerInput>;
|
|
46
|
+
declare const markEmailTrackerSentInputSchema: z.ZodType<MarkEmailTrackerSentInput>;
|
|
47
|
+
declare const markEmailTrackerSentBodySchema: z.ZodType<{
|
|
48
|
+
sentAt?: string;
|
|
49
|
+
}>;
|
|
50
|
+
declare const emailTrackerSchema: z.ZodType<EmailTracker>;
|
|
51
|
+
declare const listEmailTrackersInputSchema: z.ZodType<ListEmailTrackersInput>;
|
|
52
|
+
declare const listEmailTrackersOutputSchema: z.ZodType<ListEmailTrackersOutput>;
|
|
53
|
+
type EmailContract = {
|
|
54
|
+
tracking: {
|
|
55
|
+
createPixel: ContractProcedure<z.ZodType<CreateEmailPixelInput | undefined>, z.ZodType<CreateEmailPixelOutput>, Record<never, never>, Meta>;
|
|
56
|
+
markSent: ContractProcedure<z.ZodType<MarkEmailTrackerSentInput>, z.ZodType<EmailTracker>, Record<never, never>, Meta>;
|
|
57
|
+
get: ContractProcedure<z.ZodType<GetEmailTrackerInput>, z.ZodType<EmailTracker>, Record<never, never>, Meta>;
|
|
58
|
+
list: ContractProcedure<z.ZodType<ListEmailTrackersInput | undefined>, z.ZodType<ListEmailTrackersOutput>, Record<never, never>, Meta>;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
declare function emailContract(appletCode: string): EmailContract;
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/server/telephony-protocol.d.ts
|
|
64
|
+
/** Handle events at least once and without order. Use eventId for idempotency.
|
|
65
|
+
* Read the message with hitch.telephony.messages.get({ id: messageId }). */
|
|
66
|
+
type TelephonyMessageReceivedEvent = {
|
|
67
|
+
eventId: string;
|
|
68
|
+
type: "message.received";
|
|
69
|
+
messageId: string;
|
|
70
|
+
numberId: string;
|
|
71
|
+
occurredAt: string;
|
|
72
|
+
};
|
|
73
|
+
//#endregion
|
|
74
|
+
export { createEmailPixelOutputSchema as a, emailTagsSchema as c, listEmailTrackersInputSchema as d, listEmailTrackersOutputSchema as f, createEmailPixelInputSchema as i, emailTrackerSchema as l, markEmailTrackerSentInputSchema as m, EmailTracker as n, emailContract as o, markEmailTrackerSentBodySchema as p, ListEmailTrackersOutput as r, emailTagKeySchema as s, TelephonyMessageReceivedEvent as t, getEmailTrackerInputSchema as u };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//#region src/telephony/phone.d.ts
|
|
2
|
+
type PhoneState = {
|
|
3
|
+
status: "off" | "connecting" | "ready" | "error";
|
|
4
|
+
error: string | null;
|
|
5
|
+
active: null | {
|
|
6
|
+
callId: string;
|
|
7
|
+
to: string;
|
|
8
|
+
from: string;
|
|
9
|
+
state: "connecting" | "ringing" | "active" | "held" | "ended";
|
|
10
|
+
muted: boolean;
|
|
11
|
+
startedAt: number;
|
|
12
|
+
recording: boolean;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type CallInput = {
|
|
16
|
+
numberId: string;
|
|
17
|
+
to: string;
|
|
18
|
+
};
|
|
19
|
+
type Listener = () => void;
|
|
20
|
+
type ActiveControls = {
|
|
21
|
+
hangup: () => Promise<void>;
|
|
22
|
+
mute: () => void;
|
|
23
|
+
unmute: () => void;
|
|
24
|
+
hold: () => Promise<unknown>;
|
|
25
|
+
unhold: () => Promise<unknown>;
|
|
26
|
+
dtmf: (digit: string) => void;
|
|
27
|
+
};
|
|
28
|
+
declare class Phone {
|
|
29
|
+
state: PhoneState;
|
|
30
|
+
private readonly listeners;
|
|
31
|
+
private readonly api;
|
|
32
|
+
private client;
|
|
33
|
+
private currentCall;
|
|
34
|
+
private connectPromise;
|
|
35
|
+
private releaseLock;
|
|
36
|
+
private lockAbortController;
|
|
37
|
+
private channel;
|
|
38
|
+
private ownsPhone;
|
|
39
|
+
private connectResolve;
|
|
40
|
+
private readonly pendingCommands;
|
|
41
|
+
private pollTimer;
|
|
42
|
+
private stopRecording;
|
|
43
|
+
private recordingPromise;
|
|
44
|
+
private audio;
|
|
45
|
+
private firstLogin;
|
|
46
|
+
private callStarting;
|
|
47
|
+
constructor(options?: {
|
|
48
|
+
baseUrl?: string;
|
|
49
|
+
});
|
|
50
|
+
subscribe: (listener: Listener) => (() => void);
|
|
51
|
+
getSnapshot: () => PhoneState;
|
|
52
|
+
private update;
|
|
53
|
+
get active(): ActiveControls | null;
|
|
54
|
+
connect: () => Promise<void>;
|
|
55
|
+
private connectInternal;
|
|
56
|
+
private connectOwned;
|
|
57
|
+
disconnect: () => void;
|
|
58
|
+
private beforeUnload;
|
|
59
|
+
call: ({ numberId, to }: CallInput) => Promise<void>;
|
|
60
|
+
private sendCommand;
|
|
61
|
+
private onChannelMessage;
|
|
62
|
+
private runCommand;
|
|
63
|
+
private pollCall;
|
|
64
|
+
private onCallUpdate;
|
|
65
|
+
}
|
|
66
|
+
declare const createPhone: (options?: {
|
|
67
|
+
baseUrl?: string;
|
|
68
|
+
}) => Phone;
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/telephony/use-phone.d.ts
|
|
71
|
+
declare const usePhone: () => {
|
|
72
|
+
state: PhoneState;
|
|
73
|
+
call: Phone["call"];
|
|
74
|
+
active: Phone["active"];
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
export { type Phone, type PhoneState, createPhone, usePhone };
|