@stardeck-customer-apps/compose 0.9.0 → 0.10.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/SKILL.md +6 -0
- package/dist/cli.js +99 -134
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +261 -296
- package/dist/index.mjs +260 -296
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -18,6 +18,12 @@ Compose turns that declaration into the code Next.js actually builds:
|
|
|
18
18
|
per composed Module that ships `server/registrations.ts`
|
|
19
19
|
- one `page.tsx` / `route.ts` stub under `apps/web/src/app/**` per declared
|
|
20
20
|
mount and endpoint
|
|
21
|
+
- `apps/web/tsconfig.build.gen.json` (apps with a Module tree only) — extends
|
|
22
|
+
`tsconfig.json` and excludes every Module `--enabled` left out, plus each
|
|
23
|
+
kept Module's `enhancements/<excluded>/`. Their source stays on disk but their
|
|
24
|
+
stubs are gone, so `next build` must type-check through this file
|
|
25
|
+
(`typescript.tsconfigPath` in `next.config.ts`), never through `tsconfig.json`.
|
|
26
|
+
Gitignore it; do not hand-maintain an exclude list.
|
|
21
27
|
|
|
22
28
|
## Running it
|
|
23
29
|
|
package/dist/cli.js
CHANGED
|
@@ -3901,7 +3901,7 @@ var MODULES_GEN_PATH = `${APP_WEB_PREFIX}src/modules.gen.ts`;
|
|
|
3901
3901
|
var APP_EXTENSIONS_PATH = `${APP_WEB_PREFIX}src/lib/modules/app-extensions.ts`;
|
|
3902
3902
|
|
|
3903
3903
|
// src/cli.ts
|
|
3904
|
-
var
|
|
3904
|
+
var import_typescript7 = __toESM(require("typescript"));
|
|
3905
3905
|
var import_node_path4 = __toESM(require("path"));
|
|
3906
3906
|
|
|
3907
3907
|
// src/index.ts
|
|
@@ -3966,147 +3966,29 @@ function shellQuote(value) {
|
|
|
3966
3966
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
3967
3967
|
}
|
|
3968
3968
|
|
|
3969
|
-
// ../../packages/lib/src/shared/module-composition.ts
|
|
3970
|
-
var import_zod6 = require("zod");
|
|
3971
|
-
var moduleRefSchema = import_zod6.z.object({
|
|
3972
|
-
homeProjectId: import_zod6.z.string().uuid(),
|
|
3973
|
-
moduleName: moduleNameSchema
|
|
3974
|
-
});
|
|
3975
|
-
var creationSourceBlankSchema = import_zod6.z.object({
|
|
3976
|
-
type: import_zod6.z.literal("blank")
|
|
3977
|
-
});
|
|
3978
|
-
var creationSourceBlueprintSchema = import_zod6.z.object({
|
|
3979
|
-
type: import_zod6.z.literal("blueprint"),
|
|
3980
|
-
/** Internal template/fork project id — keep template naming in identifiers. */
|
|
3981
|
-
blueprintProjectId: import_zod6.z.string().uuid(),
|
|
3982
|
-
/**
|
|
3983
|
-
* `null`/absent means every feature Module. `[]` is refused: the platform
|
|
3984
|
-
* serialises it to an empty `NEXT_PUBLIC_STARDECK_ENABLED_MODULES`, which the
|
|
3985
|
-
* enablement parser reads back as "all" (`module-enablement.ts`) — the
|
|
3986
|
-
* opposite of what an empty selection means.
|
|
3987
|
-
*/
|
|
3988
|
-
enabledModules: import_zod6.z.array(moduleNameSchema).min(1, "Enable at least one Module").max(100).nullable().optional()
|
|
3989
|
-
});
|
|
3990
|
-
var creationSourceModulesSchema = import_zod6.z.object({
|
|
3991
|
-
type: import_zod6.z.literal("modules"),
|
|
3992
|
-
requested: import_zod6.z.array(moduleRefSchema).min(1)
|
|
3993
|
-
});
|
|
3994
|
-
var creationSourceSchema = import_zod6.z.discriminatedUnion("type", [
|
|
3995
|
-
creationSourceBlankSchema,
|
|
3996
|
-
creationSourceBlueprintSchema,
|
|
3997
|
-
creationSourceModulesSchema
|
|
3998
|
-
]);
|
|
3999
|
-
var moduleCompositionStatusSchema = import_zod6.z.enum([
|
|
4000
|
-
"pending",
|
|
4001
|
-
"installing",
|
|
4002
|
-
"ready",
|
|
4003
|
-
"partial",
|
|
4004
|
-
"failed"
|
|
4005
|
-
]);
|
|
4006
|
-
var resolvedModuleSnapshotSchema = moduleRefSchema.extend({
|
|
4007
|
-
version: import_zod6.z.string().min(1),
|
|
4008
|
-
homeCommitSha: import_zod6.z.string().min(1)
|
|
4009
|
-
});
|
|
4010
|
-
var moduleInstallHandoffSchema = import_zod6.z.object({
|
|
4011
|
-
moduleName: import_zod6.z.string().min(1),
|
|
4012
|
-
homeProjectId: import_zod6.z.string().uuid(),
|
|
4013
|
-
installedVersion: import_zod6.z.string().min(1),
|
|
4014
|
-
baselineSha: import_zod6.z.string().min(1),
|
|
4015
|
-
mounts: import_zod6.z.array(
|
|
4016
|
-
import_zod6.z.object({
|
|
4017
|
-
group: import_zod6.z.string(),
|
|
4018
|
-
segment: import_zod6.z.string()
|
|
4019
|
-
})
|
|
4020
|
-
),
|
|
4021
|
-
integration: import_zod6.z.array(import_zod6.z.string()),
|
|
4022
|
-
workflows: import_zod6.z.array(import_zod6.z.string()),
|
|
4023
|
-
prunedEnhancements: import_zod6.z.array(import_zod6.z.string()),
|
|
4024
|
-
restoredEnhancements: import_zod6.z.array(import_zod6.z.string()).optional(),
|
|
4025
|
-
permissions: import_zod6.z.array(
|
|
4026
|
-
import_zod6.z.object({
|
|
4027
|
-
key: import_zod6.z.string().min(1),
|
|
4028
|
-
description: import_zod6.z.string().min(1)
|
|
4029
|
-
})
|
|
4030
|
-
).optional()
|
|
4031
|
-
});
|
|
4032
|
-
var moduleCompositionRunAttemptSchema = import_zod6.z.object({
|
|
4033
|
-
module: moduleRefSchema,
|
|
4034
|
-
runId: import_zod6.z.string().min(1),
|
|
4035
|
-
status: import_zod6.z.string().min(1),
|
|
4036
|
-
schemaApplied: import_zod6.z.boolean(),
|
|
4037
|
-
error: import_zod6.z.string().optional(),
|
|
4038
|
-
/** Prefer full ModuleInstallHandoff; identity fields optional for older rows. */
|
|
4039
|
-
handoff: moduleInstallHandoffSchema.partial({ moduleName: true, homeProjectId: true }).optional()
|
|
4040
|
-
});
|
|
4041
|
-
var initialModuleCompositionSchema = import_zod6.z.object({
|
|
4042
|
-
version: import_zod6.z.literal(1),
|
|
4043
|
-
status: moduleCompositionStatusSchema,
|
|
4044
|
-
requested: import_zod6.z.array(moduleRefSchema).min(1),
|
|
4045
|
-
resolved: import_zod6.z.array(resolvedModuleSnapshotSchema),
|
|
4046
|
-
installOrder: import_zod6.z.array(moduleRefSchema),
|
|
4047
|
-
runs: import_zod6.z.array(moduleCompositionRunAttemptSchema).default([]),
|
|
4048
|
-
/**
|
|
4049
|
-
* True when any failed/partial attempt applied schema before failing.
|
|
4050
|
-
* Never claim transactional rollback across git/schema.
|
|
4051
|
-
*/
|
|
4052
|
-
schemaApplied: import_zod6.z.boolean().default(false),
|
|
4053
|
-
/**
|
|
4054
|
-
* Present when retry would silently change pinned home SHAs — caller must
|
|
4055
|
-
* reconfirm the new plan rather than continue.
|
|
4056
|
-
*/
|
|
4057
|
-
reconfirmationRequired: import_zod6.z.object({
|
|
4058
|
-
reason: import_zod6.z.string(),
|
|
4059
|
-
previous: import_zod6.z.array(resolvedModuleSnapshotSchema),
|
|
4060
|
-
next: import_zod6.z.array(resolvedModuleSnapshotSchema)
|
|
4061
|
-
}).optional(),
|
|
4062
|
-
error: import_zod6.z.string().optional(),
|
|
4063
|
-
/**
|
|
4064
|
-
* First-turn system handoff lifecycle. Absent/`pending` means inject when
|
|
4065
|
-
* status is ready; `consumed` means a successful agent turn already used it.
|
|
4066
|
-
*/
|
|
4067
|
-
systemHandoffStatus: import_zod6.z.enum(["pending", "consumed"]).optional(),
|
|
4068
|
-
/**
|
|
4069
|
-
* CAS ownership token for concurrent retry attempts. Only the attempt that
|
|
4070
|
-
* currently owns this value may reset or compensate durable composition state.
|
|
4071
|
-
*/
|
|
4072
|
-
retryAttemptId: import_zod6.z.string().min(1).optional(),
|
|
4073
|
-
/**
|
|
4074
|
-
* When the current `installing` attempt was claimed. A setup run that dies
|
|
4075
|
-
* with its host (a killed Vercel instance) leaves the composition `installing`
|
|
4076
|
-
* forever, and the creating page's poll only stops on ready/partial/failed —
|
|
4077
|
-
* so staleness, not a queue's stall detector, is what settles it. Absent on
|
|
4078
|
-
* rows claimed before this field existed; treated as stale.
|
|
4079
|
-
*/
|
|
4080
|
-
attemptStartedAt: import_zod6.z.string().datetime().optional(),
|
|
4081
|
-
/** Outside-module files the agent changed during connection work. */
|
|
4082
|
-
integrationFiles: import_zod6.z.array(import_zod6.z.string()).optional(),
|
|
4083
|
-
verificationSummary: import_zod6.z.string().optional()
|
|
4084
|
-
});
|
|
4085
|
-
var MODULE_SETUP_ATTEMPT_STALE_MS = 10 * 60 * 1e3;
|
|
4086
|
-
|
|
4087
3969
|
// ../../packages/lib/src/shared/compose-inputs.ts
|
|
4088
|
-
var
|
|
3970
|
+
var import_zod6 = require("zod");
|
|
4089
3971
|
var COMPOSE_INPUTS_PATH = "apps/web/stardeck.compose.json";
|
|
4090
|
-
var composeInputsSchema =
|
|
4091
|
-
connectedStores:
|
|
4092
|
-
|
|
4093
|
-
storeId:
|
|
4094
|
-
slug:
|
|
3972
|
+
var composeInputsSchema = import_zod6.z.strictObject({
|
|
3973
|
+
connectedStores: import_zod6.z.array(
|
|
3974
|
+
import_zod6.z.strictObject({
|
|
3975
|
+
storeId: import_zod6.z.string().min(1),
|
|
3976
|
+
slug: import_zod6.z.string().min(1),
|
|
4095
3977
|
// A row with an empty binding key must not fail a deploy: the rail
|
|
4096
3978
|
// treats falsy as "no binding key", so normalise rather than reject.
|
|
4097
|
-
bindingKey:
|
|
4098
|
-
accessLevel:
|
|
3979
|
+
bindingKey: import_zod6.z.string().nullish().transform((value) => value || null),
|
|
3980
|
+
accessLevel: import_zod6.z.enum(["read", "write", "admin"]),
|
|
4099
3981
|
// Defaulted so a file written before the platform emitted store types
|
|
4100
3982
|
// (database rows only) still parses. The platform starts writing
|
|
4101
3983
|
// storage rows, with `type` set, once forks run a compose that reads it.
|
|
4102
|
-
type:
|
|
3984
|
+
type: import_zod6.z.enum(["database", "storage"]).default("database")
|
|
4103
3985
|
})
|
|
4104
3986
|
).default([]),
|
|
4105
|
-
installs:
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
installedVersion:
|
|
4109
|
-
datastoreBindings:
|
|
3987
|
+
installs: import_zod6.z.record(
|
|
3988
|
+
import_zod6.z.string(),
|
|
3989
|
+
import_zod6.z.strictObject({
|
|
3990
|
+
installedVersion: import_zod6.z.string().min(1),
|
|
3991
|
+
datastoreBindings: import_zod6.z.record(import_zod6.z.string(), import_zod6.z.string()).nullish()
|
|
4110
3992
|
})
|
|
4111
3993
|
).default({})
|
|
4112
3994
|
});
|
|
@@ -6043,6 +5925,50 @@ function rejectPseudoModuleEntries(entries, parentDir, label) {
|
|
|
6043
5925
|
return dirs;
|
|
6044
5926
|
}
|
|
6045
5927
|
|
|
5928
|
+
// ../../packages/lib/src/shared/module-composition.ts
|
|
5929
|
+
var import_zod7 = require("zod");
|
|
5930
|
+
var creationSourceBlankSchema = import_zod7.z.object({
|
|
5931
|
+
type: import_zod7.z.literal("blank")
|
|
5932
|
+
});
|
|
5933
|
+
var creationSourceBlueprintSchema = import_zod7.z.object({
|
|
5934
|
+
type: import_zod7.z.literal("blueprint"),
|
|
5935
|
+
/** Internal template/fork project id — keep template naming in identifiers. */
|
|
5936
|
+
blueprintProjectId: import_zod7.z.string().uuid(),
|
|
5937
|
+
/**
|
|
5938
|
+
* `null`/absent means every feature Module. `[]` is refused: the platform
|
|
5939
|
+
* serialises it to an empty `NEXT_PUBLIC_STARDECK_ENABLED_MODULES`, which the
|
|
5940
|
+
* enablement parser reads back as "all" (`module-enablement.ts`) — the
|
|
5941
|
+
* opposite of what an empty selection means.
|
|
5942
|
+
*/
|
|
5943
|
+
enabledModules: import_zod7.z.array(moduleNameSchema).min(1, "Enable at least one Module").max(100).nullable().optional()
|
|
5944
|
+
});
|
|
5945
|
+
var creationSourceSchema = import_zod7.z.discriminatedUnion("type", [
|
|
5946
|
+
creationSourceBlankSchema,
|
|
5947
|
+
creationSourceBlueprintSchema
|
|
5948
|
+
]);
|
|
5949
|
+
var moduleInstallHandoffSchema = import_zod7.z.object({
|
|
5950
|
+
moduleName: import_zod7.z.string().min(1),
|
|
5951
|
+
homeProjectId: import_zod7.z.string().uuid(),
|
|
5952
|
+
installedVersion: import_zod7.z.string().min(1),
|
|
5953
|
+
baselineSha: import_zod7.z.string().min(1),
|
|
5954
|
+
mounts: import_zod7.z.array(
|
|
5955
|
+
import_zod7.z.object({
|
|
5956
|
+
group: import_zod7.z.string(),
|
|
5957
|
+
segment: import_zod7.z.string()
|
|
5958
|
+
})
|
|
5959
|
+
),
|
|
5960
|
+
integration: import_zod7.z.array(import_zod7.z.string()),
|
|
5961
|
+
workflows: import_zod7.z.array(import_zod7.z.string()),
|
|
5962
|
+
prunedEnhancements: import_zod7.z.array(import_zod7.z.string()),
|
|
5963
|
+
restoredEnhancements: import_zod7.z.array(import_zod7.z.string()).optional(),
|
|
5964
|
+
permissions: import_zod7.z.array(
|
|
5965
|
+
import_zod7.z.object({
|
|
5966
|
+
key: import_zod7.z.string().min(1),
|
|
5967
|
+
description: import_zod7.z.string().min(1)
|
|
5968
|
+
})
|
|
5969
|
+
).optional()
|
|
5970
|
+
});
|
|
5971
|
+
|
|
6046
5972
|
// ../../packages/lib/src/shared/schema-ops.ts
|
|
6047
5973
|
var import_zod8 = require("zod");
|
|
6048
5974
|
var columnSpecSchema = import_zod8.z.object({
|
|
@@ -7506,6 +7432,9 @@ async function reconcileCompositionArtifacts(context, options = {}) {
|
|
|
7506
7432
|
var HOME_I18N_SUBSTRATE_DIR = `${APP_PACKAGE_DIR}/src/lib/i18n/substrate`;
|
|
7507
7433
|
var HOME_I18N_MESSAGES_DIR = `${APP_PACKAGE_DIR}/src/lib/i18n/messages`;
|
|
7508
7434
|
|
|
7435
|
+
// src/index.ts
|
|
7436
|
+
var import_typescript6 = __toESM(require("typescript"));
|
|
7437
|
+
|
|
7509
7438
|
// src/module-boundaries.ts
|
|
7510
7439
|
var import_node_fs2 = __toESM(require("fs"));
|
|
7511
7440
|
var import_node_path2 = __toESM(require("path"));
|
|
@@ -7775,6 +7704,41 @@ function assertNoAppLayerImporters(cwd, excluded) {
|
|
|
7775
7704
|
);
|
|
7776
7705
|
}
|
|
7777
7706
|
}
|
|
7707
|
+
var TSCONFIG_PATH = "apps/web/tsconfig.json";
|
|
7708
|
+
var BUILD_TSCONFIG_PATH = "apps/web/tsconfig.build.gen.json";
|
|
7709
|
+
var BUILD_TSCONFIG_HEADER = "// Generated by stardeck-compose \u2014 the tsconfig `next build` type-checks. Do not edit or commit.";
|
|
7710
|
+
function writeBuildTsconfig(cwd, excluded) {
|
|
7711
|
+
const baseFile = import_node_path3.default.join(cwd, TSCONFIG_PATH);
|
|
7712
|
+
if (!import_node_fs3.default.existsSync(import_node_path3.default.join(cwd, MODULES_DIR2)) || !import_node_fs3.default.existsSync(baseFile)) return;
|
|
7713
|
+
const base = import_typescript6.default.readConfigFile(baseFile, import_typescript6.default.sys.readFile);
|
|
7714
|
+
if (base.error) {
|
|
7715
|
+
throw new Error(
|
|
7716
|
+
`[compose] cannot read ${TSCONFIG_PATH}: ${import_typescript6.default.flattenDiagnosticMessageText(base.error.messageText, "\n")}`
|
|
7717
|
+
);
|
|
7718
|
+
}
|
|
7719
|
+
const baseExclude = base.config?.exclude ?? ["node_modules"];
|
|
7720
|
+
const modulesDir = import_node_path3.default.posix.relative("apps/web", MODULES_DIR2);
|
|
7721
|
+
const config = {
|
|
7722
|
+
extends: "./tsconfig.json",
|
|
7723
|
+
exclude: [
|
|
7724
|
+
...baseExclude,
|
|
7725
|
+
...excluded.flatMap((name) => [
|
|
7726
|
+
`${modulesDir}/${name}`,
|
|
7727
|
+
`${modulesDir}/*/enhancements/${name}`
|
|
7728
|
+
])
|
|
7729
|
+
]
|
|
7730
|
+
};
|
|
7731
|
+
const content = `${BUILD_TSCONFIG_HEADER}
|
|
7732
|
+
${JSON.stringify(config, null, 2)}
|
|
7733
|
+
`;
|
|
7734
|
+
const file = import_node_path3.default.join(cwd, BUILD_TSCONFIG_PATH);
|
|
7735
|
+
if (!import_node_fs3.default.existsSync(file) || import_node_fs3.default.readFileSync(file, "utf8") !== content) {
|
|
7736
|
+
import_node_fs3.default.writeFileSync(file, content);
|
|
7737
|
+
}
|
|
7738
|
+
console.log(
|
|
7739
|
+
`[compose] ${BUILD_TSCONFIG_PATH} excludes ${excluded.length} Module(s): ${excluded.join(",") || "none"}`
|
|
7740
|
+
);
|
|
7741
|
+
}
|
|
7778
7742
|
function removeDir(absolute) {
|
|
7779
7743
|
if (!import_node_fs3.default.existsSync(absolute)) return false;
|
|
7780
7744
|
import_node_fs3.default.rmSync(absolute, { recursive: true, force: true });
|
|
@@ -7822,6 +7786,7 @@ async function compose(options) {
|
|
|
7822
7786
|
skipComposeInputs: true
|
|
7823
7787
|
});
|
|
7824
7788
|
const gitignoreEntries = options.enabled ? null : writeStubGitignore(options.cwd, result.artifactPaths);
|
|
7789
|
+
writeBuildTsconfig(options.cwd, result.excludedModules);
|
|
7825
7790
|
let pruned = 0;
|
|
7826
7791
|
if (options.prune) {
|
|
7827
7792
|
for (const name of result.excludedModules) {
|
|
@@ -7845,7 +7810,7 @@ async function compose(options) {
|
|
|
7845
7810
|
|
|
7846
7811
|
// src/cli.ts
|
|
7847
7812
|
async function main() {
|
|
7848
|
-
assertSupportedTypescript(
|
|
7813
|
+
assertSupportedTypescript(import_typescript7.default.versionMajorMinor);
|
|
7849
7814
|
const { values } = (0, import_node_util.parseArgs)({
|
|
7850
7815
|
options: {
|
|
7851
7816
|
enabled: { type: "string" },
|
package/dist/index.d.mts
CHANGED
|
@@ -129,10 +129,11 @@ declare function assertSupportedTypescript(versionMajorMinor: string): void;
|
|
|
129
129
|
* rules those out today; a total helper keeps it that way).
|
|
130
130
|
*/
|
|
131
131
|
declare function escapeGitignore(pattern: string): string;
|
|
132
|
+
declare const BUILD_TSCONFIG_PATH = "apps/web/tsconfig.build.gen.json";
|
|
132
133
|
/**
|
|
133
134
|
* Regenerate the Module-rail artifacts (the six `src/*.gen.ts` files and every
|
|
134
135
|
* route/endpoint stub under `src/app`) for the app rooted at `options.cwd`.
|
|
135
136
|
*/
|
|
136
137
|
declare function compose(options: ComposeOptions): Promise<ComposeResult>;
|
|
137
138
|
|
|
138
|
-
export { type BoundaryViolation, COMPOSE_INPUTS_PATH, type ComposeInputs, type ComposeOptions, type ComposeResult, assertSupportedTypescript, compose, escapeGitignore, findModuleBoundaryViolations, findOptionalPeerViolations, formatBoundaryViolations, readComposeInputs };
|
|
139
|
+
export { BUILD_TSCONFIG_PATH, type BoundaryViolation, COMPOSE_INPUTS_PATH, type ComposeInputs, type ComposeOptions, type ComposeResult, assertSupportedTypescript, compose, escapeGitignore, findModuleBoundaryViolations, findOptionalPeerViolations, formatBoundaryViolations, readComposeInputs };
|
package/dist/index.d.ts
CHANGED
|
@@ -129,10 +129,11 @@ declare function assertSupportedTypescript(versionMajorMinor: string): void;
|
|
|
129
129
|
* rules those out today; a total helper keeps it that way).
|
|
130
130
|
*/
|
|
131
131
|
declare function escapeGitignore(pattern: string): string;
|
|
132
|
+
declare const BUILD_TSCONFIG_PATH = "apps/web/tsconfig.build.gen.json";
|
|
132
133
|
/**
|
|
133
134
|
* Regenerate the Module-rail artifacts (the six `src/*.gen.ts` files and every
|
|
134
135
|
* route/endpoint stub under `src/app`) for the app rooted at `options.cwd`.
|
|
135
136
|
*/
|
|
136
137
|
declare function compose(options: ComposeOptions): Promise<ComposeResult>;
|
|
137
138
|
|
|
138
|
-
export { type BoundaryViolation, COMPOSE_INPUTS_PATH, type ComposeInputs, type ComposeOptions, type ComposeResult, assertSupportedTypescript, compose, escapeGitignore, findModuleBoundaryViolations, findOptionalPeerViolations, formatBoundaryViolations, readComposeInputs };
|
|
139
|
+
export { BUILD_TSCONFIG_PATH, type BoundaryViolation, COMPOSE_INPUTS_PATH, type ComposeInputs, type ComposeOptions, type ComposeResult, assertSupportedTypescript, compose, escapeGitignore, findModuleBoundaryViolations, findOptionalPeerViolations, formatBoundaryViolations, readComposeInputs };
|