@beignet/cli 0.0.44 → 0.0.45
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/CHANGELOG.md +13 -0
- package/README.md +59 -7
- package/dist/choices.d.ts +4 -0
- package/dist/choices.d.ts.map +1 -1
- package/dist/choices.js +9 -0
- package/dist/choices.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +8 -4
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/inspect.js +78 -21
- package/dist/inspect.js.map +1 -1
- package/dist/lib.d.ts +4 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +1 -1
- package/dist/lib.js.map +1 -1
- package/dist/mcp.d.ts +2 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +354 -3
- package/dist/mcp.js.map +1 -1
- package/dist/operational-lifecycle.d.ts +12 -0
- package/dist/operational-lifecycle.d.ts.map +1 -0
- package/dist/operational-lifecycle.js +39 -0
- package/dist/operational-lifecycle.js.map +1 -0
- package/dist/operational-path.d.ts +3 -0
- package/dist/operational-path.d.ts.map +1 -0
- package/dist/operational-path.js +26 -0
- package/dist/operational-path.js.map +1 -0
- package/dist/operational-process.d.ts +78 -0
- package/dist/operational-process.d.ts.map +1 -0
- package/dist/operational-process.js +228 -0
- package/dist/operational-process.js.map +1 -0
- package/dist/operational-runner.d.ts +2 -0
- package/dist/operational-runner.d.ts.map +1 -0
- package/dist/operational-runner.js +168 -0
- package/dist/operational-runner.js.map +1 -0
- package/dist/outbox.d.ts +14 -6
- package/dist/outbox.d.ts.map +1 -1
- package/dist/outbox.js +140 -124
- package/dist/outbox.js.map +1 -1
- package/dist/schedule.d.ts +2 -1
- package/dist/schedule.d.ts.map +1 -1
- package/dist/schedule.js +79 -81
- package/dist/schedule.js.map +1 -1
- package/dist/task.d.ts +2 -1
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +57 -61
- package/dist/task.js.map +1 -1
- package/dist/templates/agents.d.ts.map +1 -1
- package/dist/templates/agents.js +19 -6
- package/dist/templates/agents.js.map +1 -1
- package/dist/templates/server.d.ts.map +1 -1
- package/dist/templates/server.js +9 -2
- package/dist/templates/server.js.map +1 -1
- package/dist/templates/shadcn.d.ts.map +1 -1
- package/dist/templates/shadcn.js +3 -1
- package/dist/templates/shadcn.js.map +1 -1
- package/package.json +2 -2
- package/skills/app-structure/SKILL.md +19 -6
- package/src/choices.ts +19 -0
- package/src/db.ts +8 -4
- package/src/index.ts +19 -16
- package/src/inspect.ts +114 -26
- package/src/lib.ts +27 -1
- package/src/mcp.ts +457 -2
- package/src/operational-lifecycle.ts +56 -0
- package/src/operational-path.ts +35 -0
- package/src/operational-process.ts +454 -0
- package/src/operational-runner.ts +221 -0
- package/src/outbox.ts +154 -128
- package/src/schedule.ts +84 -89
- package/src/task.ts +58 -62
- package/src/templates/agents.ts +19 -6
- package/src/templates/server.ts +9 -2
- package/src/templates/shadcn.ts +3 -1
package/src/inspect.ts
CHANGED
|
@@ -2347,6 +2347,10 @@ async function inspectProductionReadiness(
|
|
|
2347
2347
|
packageJson,
|
|
2348
2348
|
);
|
|
2349
2349
|
const configFiles = operationalConfigFiles(files, config);
|
|
2350
|
+
const cronDirectory = path.posix.join(
|
|
2351
|
+
directoryPath(config.paths.routes),
|
|
2352
|
+
"cron",
|
|
2353
|
+
);
|
|
2350
2354
|
const infrastructurePath = directoryPath(
|
|
2351
2355
|
path.dirname(config.paths.portWiring),
|
|
2352
2356
|
);
|
|
@@ -2380,16 +2384,17 @@ async function inspectProductionReadiness(
|
|
|
2380
2384
|
}
|
|
2381
2385
|
|
|
2382
2386
|
if (
|
|
2383
|
-
file
|
|
2387
|
+
fileWithinDirectory(file, cronDirectory) &&
|
|
2384
2388
|
file.endsWith("/route.ts") &&
|
|
2385
2389
|
!/\bCRON_SECRET\b/.test(source) &&
|
|
2386
|
-
!/\bcreateOutboxDrainRoute\s*\(/.test(source)
|
|
2390
|
+
!/\bcreateOutboxDrainRoute\s*\(/.test(source) &&
|
|
2391
|
+
!/\bcreateScheduleRoute\s*\(/.test(source)
|
|
2387
2392
|
) {
|
|
2388
2393
|
diagnostics.push({
|
|
2389
2394
|
severity: "warning",
|
|
2390
2395
|
code: "BEIGNET_CRON_SECRET_MISSING",
|
|
2391
2396
|
file,
|
|
2392
|
-
message: `${file} looks like a cron route that does not reference CRON_SECRET. Protect cron entrypoints with a shared secret or a framework helper such as createOutboxDrainRoute(...).`,
|
|
2397
|
+
message: `${file} looks like a cron route that does not reference CRON_SECRET. Protect cron entrypoints with a shared secret or a framework helper such as createOutboxDrainRoute(...) or createScheduleRoute(...).`,
|
|
2393
2398
|
});
|
|
2394
2399
|
}
|
|
2395
2400
|
|
|
@@ -3882,9 +3887,15 @@ function isInfraOrServerFile(
|
|
|
3882
3887
|
}
|
|
3883
3888
|
|
|
3884
3889
|
function containsCallExpression(source: string, name: string): boolean {
|
|
3885
|
-
|
|
3890
|
+
const codeIndexes = new Set(codeCharacterIndexes(source));
|
|
3891
|
+
const pattern = new RegExp(
|
|
3886
3892
|
`\\b${escapeRegExp(name)}\\s*(?:<[^;=(){}]*>\\s*)?\\(`,
|
|
3887
|
-
|
|
3893
|
+
"g",
|
|
3894
|
+
);
|
|
3895
|
+
|
|
3896
|
+
return [...source.matchAll(pattern)].some(
|
|
3897
|
+
(match) => match.index !== undefined && codeIndexes.has(match.index),
|
|
3898
|
+
);
|
|
3888
3899
|
}
|
|
3889
3900
|
|
|
3890
3901
|
type WorkflowRegistryKind =
|
|
@@ -4607,6 +4618,8 @@ async function inspectServerlessFootguns(
|
|
|
4607
4618
|
convention: InspectConvention,
|
|
4608
4619
|
): Promise<InspectDiagnostic[]> {
|
|
4609
4620
|
const diagnostics: InspectDiagnostic[] = [];
|
|
4621
|
+
const routeDirectory = directoryPath(config.paths.routes);
|
|
4622
|
+
const cronDirectory = path.posix.join(routeDirectory, "cron");
|
|
4610
4623
|
|
|
4611
4624
|
for (const file of files) {
|
|
4612
4625
|
if (
|
|
@@ -4617,12 +4630,9 @@ async function inspectServerlessFootguns(
|
|
|
4617
4630
|
continue;
|
|
4618
4631
|
}
|
|
4619
4632
|
|
|
4620
|
-
const isInfraOrServerFile =
|
|
4621
|
-
file.startsWith("infra/") || file.startsWith("server/");
|
|
4622
|
-
const isProviderFile =
|
|
4623
|
-
/(^|\/)provider(s)?\.ts$/.test(file) ||
|
|
4624
|
-
/(^|\/)[^/]*provider[^/]*\.ts$/.test(file);
|
|
4625
4633
|
const source = await readFile(path.join(targetDir, file), "utf8");
|
|
4634
|
+
const isInfraOrServerFile = isRuntimeFile(file, config);
|
|
4635
|
+
const isProviderFile = isProviderLifecycleFile(file, source);
|
|
4626
4636
|
|
|
4627
4637
|
if (
|
|
4628
4638
|
config.framework === "next" &&
|
|
@@ -4666,7 +4676,7 @@ async function inspectServerlessFootguns(
|
|
|
4666
4676
|
}
|
|
4667
4677
|
|
|
4668
4678
|
if (
|
|
4669
|
-
file
|
|
4679
|
+
fileWithinDirectory(file, cronDirectory) &&
|
|
4670
4680
|
file.endsWith("/route.ts") &&
|
|
4671
4681
|
!/\bauthorization\b/i.test(source) &&
|
|
4672
4682
|
!/\bcreateOutboxDrainRoute\s*\(/.test(source) &&
|
|
@@ -4682,8 +4692,8 @@ async function inspectServerlessFootguns(
|
|
|
4682
4692
|
}
|
|
4683
4693
|
|
|
4684
4694
|
if (
|
|
4685
|
-
hasOutboxRegistry(files) &&
|
|
4686
|
-
!(await appHasOutboxDrainEntrypoint(targetDir, files))
|
|
4695
|
+
hasOutboxRegistry(files, config) &&
|
|
4696
|
+
!(await appHasOutboxDrainEntrypoint(targetDir, files, config))
|
|
4687
4697
|
) {
|
|
4688
4698
|
diagnostics.push({
|
|
4689
4699
|
severity: "warning",
|
|
@@ -4696,6 +4706,82 @@ async function inspectServerlessFootguns(
|
|
|
4696
4706
|
return diagnostics;
|
|
4697
4707
|
}
|
|
4698
4708
|
|
|
4709
|
+
function configuredRuntimeFiles(config: ResolvedBeignetConfig): string[] {
|
|
4710
|
+
return [
|
|
4711
|
+
config.paths.server,
|
|
4712
|
+
config.paths.listeners,
|
|
4713
|
+
config.paths.tasks,
|
|
4714
|
+
config.paths.outbox,
|
|
4715
|
+
config.paths.schedules,
|
|
4716
|
+
config.paths.portWiring,
|
|
4717
|
+
];
|
|
4718
|
+
}
|
|
4719
|
+
|
|
4720
|
+
function configuredRuntimeDirectories(config: ResolvedBeignetConfig): string[] {
|
|
4721
|
+
const applicationDirectories = configuredApplicationDirectories(config);
|
|
4722
|
+
|
|
4723
|
+
return configuredRuntimeFiles(config)
|
|
4724
|
+
.map((file) => directoryPath(path.posix.dirname(file)))
|
|
4725
|
+
.filter((directory) => directory !== ".")
|
|
4726
|
+
.filter(
|
|
4727
|
+
(directory) =>
|
|
4728
|
+
!applicationDirectories.some(
|
|
4729
|
+
(applicationDirectory) =>
|
|
4730
|
+
applicationDirectory !== directory &&
|
|
4731
|
+
fileWithinDirectory(applicationDirectory, directory),
|
|
4732
|
+
),
|
|
4733
|
+
)
|
|
4734
|
+
.filter((directory, index, all) => all.indexOf(directory) === index);
|
|
4735
|
+
}
|
|
4736
|
+
|
|
4737
|
+
function configuredApplicationDirectories(
|
|
4738
|
+
config: ResolvedBeignetConfig,
|
|
4739
|
+
): string[] {
|
|
4740
|
+
return [
|
|
4741
|
+
config.paths.contracts,
|
|
4742
|
+
config.paths.routes,
|
|
4743
|
+
config.paths.features,
|
|
4744
|
+
config.paths.policies,
|
|
4745
|
+
config.paths.useCases,
|
|
4746
|
+
config.paths.tests,
|
|
4747
|
+
]
|
|
4748
|
+
.map(directoryPath)
|
|
4749
|
+
.filter((directory) => directory !== ".")
|
|
4750
|
+
.filter((directory, index, all) => all.indexOf(directory) === index);
|
|
4751
|
+
}
|
|
4752
|
+
|
|
4753
|
+
function isRuntimeFile(file: string, config: ResolvedBeignetConfig): boolean {
|
|
4754
|
+
if (configuredRuntimeFiles(config).includes(file)) return true;
|
|
4755
|
+
if (
|
|
4756
|
+
configuredApplicationDirectories(config).some((directory) =>
|
|
4757
|
+
fileWithinDirectory(file, directory),
|
|
4758
|
+
)
|
|
4759
|
+
) {
|
|
4760
|
+
return false;
|
|
4761
|
+
}
|
|
4762
|
+
|
|
4763
|
+
return (
|
|
4764
|
+
fileWithinDirectory(file, "infra") ||
|
|
4765
|
+
fileWithinDirectory(file, "server") ||
|
|
4766
|
+
configuredRuntimeDirectories(config).some((directory) =>
|
|
4767
|
+
fileWithinDirectory(file, directory),
|
|
4768
|
+
)
|
|
4769
|
+
);
|
|
4770
|
+
}
|
|
4771
|
+
|
|
4772
|
+
function fileWithinDirectory(file: string, directory: string): boolean {
|
|
4773
|
+
return directory === "." || file.startsWith(`${directory}/`);
|
|
4774
|
+
}
|
|
4775
|
+
|
|
4776
|
+
function isProviderLifecycleFile(file: string, source?: string): boolean {
|
|
4777
|
+
return (
|
|
4778
|
+
/(^|\/)provider(s)?\.ts$/.test(file) ||
|
|
4779
|
+
/(^|\/)[^/]*provider[^/]*\.ts$/.test(file) ||
|
|
4780
|
+
/(^|\/)providers?\//.test(file) ||
|
|
4781
|
+
(source !== undefined && containsCallExpression(source, "createProvider"))
|
|
4782
|
+
);
|
|
4783
|
+
}
|
|
4784
|
+
|
|
4699
4785
|
function isNextRouteFile(file: string, config: ResolvedBeignetConfig): boolean {
|
|
4700
4786
|
const routesPath = directoryPath(config.paths.routes);
|
|
4701
4787
|
|
|
@@ -4727,33 +4813,35 @@ function importsEagerServer(
|
|
|
4727
4813
|
return false;
|
|
4728
4814
|
}
|
|
4729
4815
|
|
|
4730
|
-
function hasOutboxRegistry(
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
return file === "server/outbox.ts";
|
|
4816
|
+
function hasOutboxRegistry(
|
|
4817
|
+
files: string[],
|
|
4818
|
+
config: ResolvedBeignetConfig,
|
|
4819
|
+
): boolean {
|
|
4820
|
+
return files.includes(config.paths.outbox);
|
|
4736
4821
|
}
|
|
4737
4822
|
|
|
4738
4823
|
async function appHasOutboxDrainEntrypoint(
|
|
4739
4824
|
targetDir: string,
|
|
4740
4825
|
files: string[],
|
|
4826
|
+
config: ResolvedBeignetConfig,
|
|
4741
4827
|
): Promise<boolean> {
|
|
4828
|
+
const routesDirectory = directoryPath(config.paths.routes);
|
|
4829
|
+
|
|
4742
4830
|
for (const file of files) {
|
|
4743
4831
|
if (!file.endsWith(".ts") || file.endsWith(".test.ts")) continue;
|
|
4744
4832
|
if (
|
|
4745
|
-
!file
|
|
4746
|
-
!file
|
|
4747
|
-
!file.startsWith("infra/")
|
|
4833
|
+
!fileWithinDirectory(file, routesDirectory) &&
|
|
4834
|
+
!isRuntimeFile(file, config)
|
|
4748
4835
|
) {
|
|
4749
4836
|
continue;
|
|
4750
4837
|
}
|
|
4751
4838
|
|
|
4752
4839
|
const source = await readFile(path.join(targetDir, file), "utf8");
|
|
4753
|
-
if (
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
)
|
|
4840
|
+
if (containsCallExpression(source, "createOutboxDrainRoute")) {
|
|
4841
|
+
return true;
|
|
4842
|
+
}
|
|
4843
|
+
if (isProviderLifecycleFile(file, source)) continue;
|
|
4844
|
+
if (containsCallExpression(source, "drainOutbox")) {
|
|
4757
4845
|
return true;
|
|
4758
4846
|
}
|
|
4759
4847
|
}
|
package/src/lib.ts
CHANGED
|
@@ -103,7 +103,33 @@ export {
|
|
|
103
103
|
makeUpload,
|
|
104
104
|
makeUseCase,
|
|
105
105
|
} from "./make.js";
|
|
106
|
-
export {
|
|
106
|
+
export type {
|
|
107
|
+
RunOutboxDrainOptions,
|
|
108
|
+
RunOutboxDrainResult,
|
|
109
|
+
RunOutboxListOptions,
|
|
110
|
+
RunOutboxListResult,
|
|
111
|
+
RunOutboxPruneOptions,
|
|
112
|
+
RunOutboxPruneResult,
|
|
113
|
+
RunOutboxPurgeOptions,
|
|
114
|
+
RunOutboxPurgeResult,
|
|
115
|
+
RunOutboxRequeueOptions,
|
|
116
|
+
RunOutboxRequeueResult,
|
|
117
|
+
RunOutboxShowOptions,
|
|
118
|
+
RunOutboxShowResult,
|
|
119
|
+
} from "./outbox.js";
|
|
120
|
+
export {
|
|
121
|
+
runOutboxDrain,
|
|
122
|
+
runOutboxList,
|
|
123
|
+
runOutboxPrune,
|
|
124
|
+
runOutboxPurge,
|
|
125
|
+
runOutboxRequeue,
|
|
126
|
+
runOutboxShow,
|
|
127
|
+
} from "./outbox.js";
|
|
128
|
+
export type {
|
|
129
|
+
RunAppScheduleOptions,
|
|
130
|
+
RunAppScheduleResult,
|
|
131
|
+
} from "./schedule.js";
|
|
107
132
|
export { runAppSchedule } from "./schedule.js";
|
|
133
|
+
export type { RunAppTaskOptions, RunAppTaskResult } from "./task.js";
|
|
108
134
|
export { runAppTask } from "./task.js";
|
|
109
135
|
export type { StarterProviderName } from "./templates/index.js";
|