@codio-ai/opencode-authoring-agent 0.1.3 → 0.1.5
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/index.js +139 -104
- package/dist/tools/fetch-course.d.ts.map +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/publish-course.d.ts +1 -0
- package/dist/tools/publish-course.d.ts.map +1 -1
- package/dist/utils/load-env.d.ts +7 -0
- package/dist/utils/load-env.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3945,7 +3945,7 @@ var require_lodash = __commonJS((exports, module) => {
|
|
|
3945
3945
|
}
|
|
3946
3946
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
3947
3947
|
});
|
|
3948
|
-
function
|
|
3948
|
+
function join6(array, separator) {
|
|
3949
3949
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
3950
3950
|
}
|
|
3951
3951
|
function last(array) {
|
|
@@ -5882,7 +5882,7 @@ __p += '`;
|
|
|
5882
5882
|
lodash.isUndefined = isUndefined;
|
|
5883
5883
|
lodash.isWeakMap = isWeakMap;
|
|
5884
5884
|
lodash.isWeakSet = isWeakSet;
|
|
5885
|
-
lodash.join =
|
|
5885
|
+
lodash.join = join6;
|
|
5886
5886
|
lodash.kebabCase = kebabCase;
|
|
5887
5887
|
lodash.last = last;
|
|
5888
5888
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -16380,11 +16380,11 @@ var require_path_arg = __commonJS((exports, module) => {
|
|
|
16380
16380
|
|
|
16381
16381
|
// node_modules/tar/node_modules/mkdirp/lib/find-made.js
|
|
16382
16382
|
var require_find_made = __commonJS((exports, module) => {
|
|
16383
|
-
var { dirname:
|
|
16383
|
+
var { dirname: dirname3 } = __require("path");
|
|
16384
16384
|
var findMade = (opts, parent, path = undefined) => {
|
|
16385
16385
|
if (path === parent)
|
|
16386
16386
|
return Promise.resolve();
|
|
16387
|
-
return opts.statAsync(parent).then((st) => st.isDirectory() ? path : undefined, (er) => er.code === "ENOENT" ? findMade(opts,
|
|
16387
|
+
return opts.statAsync(parent).then((st) => st.isDirectory() ? path : undefined, (er) => er.code === "ENOENT" ? findMade(opts, dirname3(parent), parent) : undefined);
|
|
16388
16388
|
};
|
|
16389
16389
|
var findMadeSync = (opts, parent, path = undefined) => {
|
|
16390
16390
|
if (path === parent)
|
|
@@ -16392,7 +16392,7 @@ var require_find_made = __commonJS((exports, module) => {
|
|
|
16392
16392
|
try {
|
|
16393
16393
|
return opts.statSync(parent).isDirectory() ? path : undefined;
|
|
16394
16394
|
} catch (er) {
|
|
16395
|
-
return er.code === "ENOENT" ? findMadeSync(opts,
|
|
16395
|
+
return er.code === "ENOENT" ? findMadeSync(opts, dirname3(parent), parent) : undefined;
|
|
16396
16396
|
}
|
|
16397
16397
|
};
|
|
16398
16398
|
module.exports = { findMade, findMadeSync };
|
|
@@ -16400,10 +16400,10 @@ var require_find_made = __commonJS((exports, module) => {
|
|
|
16400
16400
|
|
|
16401
16401
|
// node_modules/tar/node_modules/mkdirp/lib/mkdirp-manual.js
|
|
16402
16402
|
var require_mkdirp_manual = __commonJS((exports, module) => {
|
|
16403
|
-
var { dirname:
|
|
16403
|
+
var { dirname: dirname3 } = __require("path");
|
|
16404
16404
|
var mkdirpManual = (path, opts, made) => {
|
|
16405
16405
|
opts.recursive = false;
|
|
16406
|
-
const parent =
|
|
16406
|
+
const parent = dirname3(path);
|
|
16407
16407
|
if (parent === path) {
|
|
16408
16408
|
return opts.mkdirAsync(path, opts).catch((er) => {
|
|
16409
16409
|
if (er.code !== "EISDIR")
|
|
@@ -16426,7 +16426,7 @@ var require_mkdirp_manual = __commonJS((exports, module) => {
|
|
|
16426
16426
|
});
|
|
16427
16427
|
};
|
|
16428
16428
|
var mkdirpManualSync = (path, opts, made) => {
|
|
16429
|
-
const parent =
|
|
16429
|
+
const parent = dirname3(path);
|
|
16430
16430
|
opts.recursive = false;
|
|
16431
16431
|
if (parent === path) {
|
|
16432
16432
|
try {
|
|
@@ -16459,12 +16459,12 @@ var require_mkdirp_manual = __commonJS((exports, module) => {
|
|
|
16459
16459
|
|
|
16460
16460
|
// node_modules/tar/node_modules/mkdirp/lib/mkdirp-native.js
|
|
16461
16461
|
var require_mkdirp_native = __commonJS((exports, module) => {
|
|
16462
|
-
var { dirname:
|
|
16462
|
+
var { dirname: dirname3 } = __require("path");
|
|
16463
16463
|
var { findMade, findMadeSync } = require_find_made();
|
|
16464
16464
|
var { mkdirpManual, mkdirpManualSync } = require_mkdirp_manual();
|
|
16465
16465
|
var mkdirpNative = (path, opts) => {
|
|
16466
16466
|
opts.recursive = true;
|
|
16467
|
-
const parent =
|
|
16467
|
+
const parent = dirname3(path);
|
|
16468
16468
|
if (parent === path)
|
|
16469
16469
|
return opts.mkdirAsync(path, opts);
|
|
16470
16470
|
return findMade(opts, path).then((made) => opts.mkdirAsync(path, opts).then(() => made).catch((er) => {
|
|
@@ -16476,7 +16476,7 @@ var require_mkdirp_native = __commonJS((exports, module) => {
|
|
|
16476
16476
|
};
|
|
16477
16477
|
var mkdirpNativeSync = (path, opts) => {
|
|
16478
16478
|
opts.recursive = true;
|
|
16479
|
-
const parent =
|
|
16479
|
+
const parent = dirname3(path);
|
|
16480
16480
|
if (parent === path)
|
|
16481
16481
|
return opts.mkdirSync(path, opts);
|
|
16482
16482
|
const made = findMadeSync(opts, path);
|
|
@@ -16865,7 +16865,7 @@ var require_path_reservations = __commonJS((exports, module) => {
|
|
|
16865
16865
|
var assert = __require("assert");
|
|
16866
16866
|
var normalize = require_normalize_unicode();
|
|
16867
16867
|
var stripSlashes = require_strip_trailing_slashes();
|
|
16868
|
-
var { join:
|
|
16868
|
+
var { join: join6 } = __require("path");
|
|
16869
16869
|
var platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
|
|
16870
16870
|
var isWindows = platform === "win32";
|
|
16871
16871
|
module.exports = () => {
|
|
@@ -16874,7 +16874,7 @@ var require_path_reservations = __commonJS((exports, module) => {
|
|
|
16874
16874
|
const getDirs = (path) => {
|
|
16875
16875
|
const dirs = path.split("/").slice(0, -1).reduce((set, path2) => {
|
|
16876
16876
|
if (set.length) {
|
|
16877
|
-
path2 =
|
|
16877
|
+
path2 = join6(set[set.length - 1], path2);
|
|
16878
16878
|
}
|
|
16879
16879
|
set.push(path2 || "/");
|
|
16880
16880
|
return set;
|
|
@@ -16942,7 +16942,7 @@ var require_path_reservations = __commonJS((exports, module) => {
|
|
|
16942
16942
|
};
|
|
16943
16943
|
const reserve = (paths, fn) => {
|
|
16944
16944
|
paths = isWindows ? ["win32 parallelization disabled"] : paths.map((p) => {
|
|
16945
|
-
return stripSlashes(
|
|
16945
|
+
return stripSlashes(join6(normalize(p))).toLowerCase();
|
|
16946
16946
|
});
|
|
16947
16947
|
const dirs = new Set(paths.map((path) => getDirs(path)).reduce((a, b) => a.concat(b)));
|
|
16948
16948
|
reservations.set(fn, { dirs, paths });
|
|
@@ -18231,7 +18231,7 @@ var require_BufferList = __commonJS((exports, module) => {
|
|
|
18231
18231
|
this.head = this.tail = null;
|
|
18232
18232
|
this.length = 0;
|
|
18233
18233
|
};
|
|
18234
|
-
BufferList.prototype.join = function
|
|
18234
|
+
BufferList.prototype.join = function join6(s) {
|
|
18235
18235
|
if (this.length === 0)
|
|
18236
18236
|
return "";
|
|
18237
18237
|
var p = this.head;
|
|
@@ -20411,7 +20411,7 @@ var require_BufferList2 = __commonJS((exports, module) => {
|
|
|
20411
20411
|
this.head = this.tail = null;
|
|
20412
20412
|
this.length = 0;
|
|
20413
20413
|
};
|
|
20414
|
-
BufferList.prototype.join = function
|
|
20414
|
+
BufferList.prototype.join = function join6(s) {
|
|
20415
20415
|
if (this.length === 0)
|
|
20416
20416
|
return "";
|
|
20417
20417
|
var p = this.head;
|
|
@@ -22536,7 +22536,7 @@ var require_buffer_list = __commonJS((exports, module) => {
|
|
|
22536
22536
|
}
|
|
22537
22537
|
}, {
|
|
22538
22538
|
key: "join",
|
|
22539
|
-
value: function
|
|
22539
|
+
value: function join6(s) {
|
|
22540
22540
|
if (this.length === 0)
|
|
22541
22541
|
return "";
|
|
22542
22542
|
var p = this.head;
|
|
@@ -45914,7 +45914,7 @@ ${enabledAgents}
|
|
|
45914
45914
|
|
|
45915
45915
|
### Codio platform tools
|
|
45916
45916
|
- \`fetch_course({workspace, courseId, outputDir?, domain?})\` — pull an existing Codio course from the platform into an AI-ready local project. Requires \`CODIO_CLIENT_ID\` and \`CODIO_CLIENT_SECRET\` env vars. Returns \`{ outputDir, manifestPath, moduleCount, assignmentCount }\`. Writes \`course-manifest.json\`, \`course-assignments.csv\`, and extracted assignment content under \`course-content/\`. **Delegate when:** user wants to fetch, pull, import, or export an existing Codio course.
|
|
45917
|
-
- \`publish_course({manifestPath, dryRun?, force?, module?, assignment?, changelog?, stack?})\` — push course assignments back to the Codio platform using \`course-manifest.json\` as the source of truth. Creates missing courses/modules/assignments automatically. Skips unchanged assignments by content hash. Returns \`{ published, created, unchanged, skipped }\`. **Delegate when:** user wants to publish, push, deploy, or sync assignments to Codio. Always suggest \`dryRun: true\` first to preview.
|
|
45917
|
+
- \`publish_course({workspace, manifestPath, dryRun?, force?, module?, assignment?, changelog?, stack?})\` — push course assignments back to the Codio platform using \`course-manifest.json\` as the source of truth. Creates missing courses/modules/assignments automatically. Skips unchanged assignments by content hash. Returns \`{ published, created, unchanged, skipped }\`. **Delegate when:** user wants to publish, push, deploy, or sync assignments to Codio. Always suggest \`dryRun: true\` first to preview.
|
|
45918
45918
|
|
|
45919
45919
|
### Platform tool routing
|
|
45920
45920
|
- User says "fetch/pull/import/export this course" → \`fetch_course\`
|
|
@@ -46365,8 +46365,8 @@ function getAgentConfigs(agents) {
|
|
|
46365
46365
|
import { existsSync, readFileSync } from "node:fs";
|
|
46366
46366
|
import { join } from "node:path";
|
|
46367
46367
|
import { z } from "zod";
|
|
46368
|
-
var DEFAULT_PRIMARY = "
|
|
46369
|
-
var DEFAULT_CHEAP = "
|
|
46368
|
+
var DEFAULT_PRIMARY = "anthropic/claude-sonnet-4-6";
|
|
46369
|
+
var DEFAULT_CHEAP = "anthropic/claude-haiku-4-5-20251001";
|
|
46370
46370
|
var agentOverrideSchema = z.object({
|
|
46371
46371
|
model: z.string().optional(),
|
|
46372
46372
|
prompt: z.string().optional(),
|
|
@@ -47032,22 +47032,52 @@ ${freezeErrors.join(`
|
|
|
47032
47032
|
}
|
|
47033
47033
|
|
|
47034
47034
|
// src/tools/fetch-course.ts
|
|
47035
|
-
var import_codio_api_js = __toESM(require_lib3(), 1);
|
|
47036
|
-
var import_json_2_csv = __toESM(require_converter(), 1);
|
|
47037
47035
|
import { execFile } from "node:child_process";
|
|
47038
47036
|
import {
|
|
47039
|
-
|
|
47037
|
+
copyFileSync,
|
|
47038
|
+
existsSync as existsSync4,
|
|
47040
47039
|
mkdirSync as mkdirSync2,
|
|
47041
47040
|
readdirSync,
|
|
47042
47041
|
rmSync,
|
|
47043
47042
|
statSync,
|
|
47044
47043
|
unlinkSync as unlinkSync2
|
|
47045
47044
|
} from "node:fs";
|
|
47046
|
-
import {
|
|
47045
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
47047
47046
|
import { tmpdir } from "node:os";
|
|
47048
|
-
import { dirname as
|
|
47047
|
+
import { dirname as dirname3, join as join6 } from "node:path";
|
|
47049
47048
|
import { promisify } from "node:util";
|
|
47050
47049
|
import { z as z4 } from "zod";
|
|
47050
|
+
|
|
47051
|
+
// src/utils/load-env.ts
|
|
47052
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
47053
|
+
import { dirname as dirname2, join as join5 } from "node:path";
|
|
47054
|
+
function loadEnvWalkUp(startDir) {
|
|
47055
|
+
let dir = startDir.replace(/\/+$/, "");
|
|
47056
|
+
while (true) {
|
|
47057
|
+
const candidate = join5(dir, ".env");
|
|
47058
|
+
if (existsSync3(candidate)) {
|
|
47059
|
+
for (const line of readFileSync2(candidate, "utf8").split(`
|
|
47060
|
+
`)) {
|
|
47061
|
+
const t = line.trim();
|
|
47062
|
+
if (!t || t.startsWith("#"))
|
|
47063
|
+
continue;
|
|
47064
|
+
const eq = t.indexOf("=");
|
|
47065
|
+
if (eq < 1)
|
|
47066
|
+
continue;
|
|
47067
|
+
const key = t.slice(0, eq).trim();
|
|
47068
|
+
const val = t.slice(eq + 1).trim().replace(/^(['"])(.*)\1$/, "$2");
|
|
47069
|
+
process.env[key] = val;
|
|
47070
|
+
}
|
|
47071
|
+
return;
|
|
47072
|
+
}
|
|
47073
|
+
const parent = dirname2(dir);
|
|
47074
|
+
if (parent === dir)
|
|
47075
|
+
return;
|
|
47076
|
+
dir = parent;
|
|
47077
|
+
}
|
|
47078
|
+
}
|
|
47079
|
+
|
|
47080
|
+
// src/tools/fetch-course.ts
|
|
47051
47081
|
var execFileAsync = promisify(execFile);
|
|
47052
47082
|
var fetchCourseInputSchema = z4.object({
|
|
47053
47083
|
workspace: z4.string().min(1).describe("Absolute path to the Codio workspace root"),
|
|
@@ -47065,7 +47095,7 @@ async function extractZip(zipPath, destDir) {
|
|
|
47065
47095
|
function findTarZstFiles(dir) {
|
|
47066
47096
|
const results = [];
|
|
47067
47097
|
for (const name of readdirSync(dir)) {
|
|
47068
|
-
const full =
|
|
47098
|
+
const full = join6(dir, name);
|
|
47069
47099
|
if (statSync(full).isDirectory())
|
|
47070
47100
|
results.push(...findTarZstFiles(full));
|
|
47071
47101
|
else if (name.endsWith(".tar.zst"))
|
|
@@ -47082,10 +47112,10 @@ async function extractTarZstArchives(stagingDir) {
|
|
|
47082
47112
|
}
|
|
47083
47113
|
}
|
|
47084
47114
|
function removeExportedReadmes(dir) {
|
|
47085
|
-
if (!
|
|
47115
|
+
if (!existsSync4(dir))
|
|
47086
47116
|
return;
|
|
47087
47117
|
for (const name of readdirSync(dir)) {
|
|
47088
|
-
const full =
|
|
47118
|
+
const full = join6(dir, name);
|
|
47089
47119
|
if (statSync(full).isDirectory())
|
|
47090
47120
|
removeExportedReadmes(full);
|
|
47091
47121
|
else if (name.toLowerCase() === "readme.md")
|
|
@@ -47095,32 +47125,35 @@ function removeExportedReadmes(dir) {
|
|
|
47095
47125
|
function copyDir(src, dst) {
|
|
47096
47126
|
mkdirSync2(dst, { recursive: true });
|
|
47097
47127
|
for (const name of readdirSync(src)) {
|
|
47098
|
-
const srcPath =
|
|
47099
|
-
const dstPath =
|
|
47128
|
+
const srcPath = join6(src, name);
|
|
47129
|
+
const dstPath = join6(dst, name);
|
|
47100
47130
|
if (statSync(srcPath).isDirectory())
|
|
47101
47131
|
copyDir(srcPath, dstPath);
|
|
47102
|
-
else
|
|
47103
|
-
const { copyFileSync } = __require("node:fs");
|
|
47132
|
+
else
|
|
47104
47133
|
copyFileSync(srcPath, dstPath);
|
|
47105
|
-
}
|
|
47106
47134
|
}
|
|
47107
47135
|
}
|
|
47108
47136
|
async function fetchCourseHandler(raw) {
|
|
47109
47137
|
const input = fetchCourseInputSchema.parse(raw);
|
|
47138
|
+
loadEnvWalkUp(input.workspace);
|
|
47139
|
+
const [{ default: codio }, { json2csv }] = await Promise.all([
|
|
47140
|
+
Promise.resolve().then(() => __toESM(require_lib3(), 1)),
|
|
47141
|
+
Promise.resolve().then(() => __toESM(require_converter(), 1))
|
|
47142
|
+
]);
|
|
47110
47143
|
const clientId = process.env["CODIO_CLIENT_ID"];
|
|
47111
47144
|
const clientSecret = process.env["CODIO_CLIENT_SECRET"];
|
|
47112
47145
|
if (!clientId || !clientSecret) {
|
|
47113
|
-
throw new Error("CODIO_CLIENT_ID and CODIO_CLIENT_SECRET must be set as environment variables
|
|
47146
|
+
throw new Error("CODIO_CLIENT_ID and CODIO_CLIENT_SECRET must be set in .env at the workspace root or as environment variables.");
|
|
47114
47147
|
}
|
|
47115
47148
|
const domain = input.domain ?? process.env["CODIO_DOMAIN"] ?? "codio.com";
|
|
47116
47149
|
const outputFolderName = input.outputDir ?? "course-project";
|
|
47117
|
-
const outputDir =
|
|
47118
|
-
const contentDir =
|
|
47119
|
-
const manifestPath =
|
|
47120
|
-
const csvPath =
|
|
47121
|
-
|
|
47122
|
-
await
|
|
47123
|
-
const courseInfo = await
|
|
47150
|
+
const outputDir = join6(input.workspace, outputFolderName);
|
|
47151
|
+
const contentDir = join6(outputDir, "course-content");
|
|
47152
|
+
const manifestPath = join6(outputDir, "course-manifest.json");
|
|
47153
|
+
const csvPath = join6(outputDir, "course-assignments.csv");
|
|
47154
|
+
codio.v1.setDomain(domain);
|
|
47155
|
+
await codio.v1.auth(clientId, clientSecret);
|
|
47156
|
+
const courseInfo = await codio.v1.course.info(input.courseId);
|
|
47124
47157
|
const modules = (courseInfo.modules ?? []).map((mod, mi) => {
|
|
47125
47158
|
const moduleName = mod.name ?? `Module ${mi + 1}`;
|
|
47126
47159
|
const moduleFolder = codioFolderSlug(moduleName);
|
|
@@ -47156,7 +47189,7 @@ async function fetchCourseHandler(raw) {
|
|
|
47156
47189
|
};
|
|
47157
47190
|
rmSync(outputDir, { recursive: true, force: true });
|
|
47158
47191
|
mkdirSync2(contentDir, { recursive: true });
|
|
47159
|
-
await mkdir(
|
|
47192
|
+
await mkdir(dirname3(manifestPath), { recursive: true });
|
|
47160
47193
|
await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
47161
47194
|
`, "utf8");
|
|
47162
47195
|
const rows = modules.flatMap((m) => m.assignments.map((a) => ({
|
|
@@ -47168,14 +47201,14 @@ async function fetchCourseHandler(raw) {
|
|
|
47168
47201
|
assignmentFolder: a.folder,
|
|
47169
47202
|
assignmentPath: a.path
|
|
47170
47203
|
})));
|
|
47171
|
-
const csv = await
|
|
47204
|
+
const csv = await json2csv(rows, { emptyFieldValue: "", prependHeader: true });
|
|
47172
47205
|
await writeFile(csvPath, csv, "utf8");
|
|
47173
|
-
const workDir =
|
|
47174
|
-
const zipPath =
|
|
47206
|
+
const workDir = join6(tmpdir(), `codio-fetch-${Date.now()}`);
|
|
47207
|
+
const zipPath = join6(workDir, "course-export.zip");
|
|
47175
47208
|
mkdirSync2(workDir, { recursive: true });
|
|
47176
47209
|
try {
|
|
47177
|
-
await
|
|
47178
|
-
const stagingDir =
|
|
47210
|
+
await codio.v1.course.downloadSourceExport(input.courseId, zipPath);
|
|
47211
|
+
const stagingDir = join6(workDir, "staging");
|
|
47179
47212
|
await extractZip(zipPath, stagingDir);
|
|
47180
47213
|
await extractTarZstArchives(stagingDir);
|
|
47181
47214
|
removeExportedReadmes(stagingDir);
|
|
@@ -47193,18 +47226,18 @@ async function fetchCourseHandler(raw) {
|
|
|
47193
47226
|
}
|
|
47194
47227
|
|
|
47195
47228
|
// src/tools/publish-course.ts
|
|
47196
|
-
var import_codio_api_js2 = __toESM(require_lib3(), 1);
|
|
47197
47229
|
import { createHash } from "node:crypto";
|
|
47198
47230
|
import {
|
|
47199
|
-
existsSync as
|
|
47231
|
+
existsSync as existsSync5,
|
|
47200
47232
|
readdirSync as readdirSync2,
|
|
47201
|
-
readFileSync as
|
|
47202
|
-
writeFileSync as
|
|
47233
|
+
readFileSync as readFileSync3,
|
|
47234
|
+
writeFileSync as writeFileSync3
|
|
47203
47235
|
} from "node:fs";
|
|
47204
|
-
import { join as
|
|
47236
|
+
import { join as join7, relative } from "node:path";
|
|
47205
47237
|
import { z as z5 } from "zod";
|
|
47206
47238
|
var DEFAULT_STACK = "e0195698-d647-4490-8834-350583b532eb:latest";
|
|
47207
47239
|
var publishCourseInputSchema = z5.object({
|
|
47240
|
+
workspace: z5.string().min(1).describe("Absolute path to the Codio workspace root (where .env lives)"),
|
|
47208
47241
|
manifestPath: z5.string().min(1).describe("Absolute path to course-manifest.json"),
|
|
47209
47242
|
dryRun: z5.boolean().optional().describe("Preview actions without making changes"),
|
|
47210
47243
|
force: z5.boolean().optional().describe("Publish all, bypassing change detection"),
|
|
@@ -47214,17 +47247,17 @@ var publishCourseInputSchema = z5.object({
|
|
|
47214
47247
|
stack: z5.string().optional().describe("Force a specific stack ID for all assignments")
|
|
47215
47248
|
});
|
|
47216
47249
|
function saveManifest(manifestPath, manifest) {
|
|
47217
|
-
|
|
47250
|
+
writeFileSync3(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
47218
47251
|
`, "utf8");
|
|
47219
47252
|
}
|
|
47220
47253
|
function findZip(dir) {
|
|
47221
47254
|
const zip = readdirSync2(dir).find((f) => f.endsWith(".zip"));
|
|
47222
|
-
return zip ?
|
|
47255
|
+
return zip ? join7(dir, zip) : null;
|
|
47223
47256
|
}
|
|
47224
47257
|
function walkFiles(dir) {
|
|
47225
47258
|
const results = [];
|
|
47226
47259
|
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
47227
|
-
const full =
|
|
47260
|
+
const full = join7(dir, entry.name);
|
|
47228
47261
|
if (entry.isDirectory())
|
|
47229
47262
|
results.push(...walkFiles(full));
|
|
47230
47263
|
else
|
|
@@ -47236,12 +47269,12 @@ function computeContentHash(dir) {
|
|
|
47236
47269
|
const hash = createHash("sha256");
|
|
47237
47270
|
const zipPath = findZip(dir);
|
|
47238
47271
|
if (zipPath) {
|
|
47239
|
-
hash.update(
|
|
47272
|
+
hash.update(readFileSync3(zipPath));
|
|
47240
47273
|
} else {
|
|
47241
47274
|
for (const file of walkFiles(dir).sort()) {
|
|
47242
|
-
hash.update(
|
|
47275
|
+
hash.update(relative(dir, file));
|
|
47243
47276
|
hash.update("\x00");
|
|
47244
|
-
hash.update(
|
|
47277
|
+
hash.update(readFileSync3(file));
|
|
47245
47278
|
hash.update("\x00");
|
|
47246
47279
|
}
|
|
47247
47280
|
}
|
|
@@ -47249,19 +47282,21 @@ function computeContentHash(dir) {
|
|
|
47249
47282
|
}
|
|
47250
47283
|
async function publishCourseHandler(raw) {
|
|
47251
47284
|
const input = publishCourseInputSchema.parse(raw);
|
|
47285
|
+
loadEnvWalkUp(input.workspace);
|
|
47286
|
+
const { default: codio } = await Promise.resolve().then(() => __toESM(require_lib3(), 1));
|
|
47252
47287
|
const clientId = process.env["CODIO_CLIENT_ID"];
|
|
47253
47288
|
const clientSecret = process.env["CODIO_CLIENT_SECRET"];
|
|
47254
47289
|
if (!clientId || !clientSecret) {
|
|
47255
47290
|
throw new Error("CODIO_CLIENT_ID and CODIO_CLIENT_SECRET must be set as environment variables on the box.");
|
|
47256
47291
|
}
|
|
47257
|
-
if (!
|
|
47292
|
+
if (!existsSync5(input.manifestPath)) {
|
|
47258
47293
|
throw new Error(`course-manifest.json not found at ${input.manifestPath}`);
|
|
47259
47294
|
}
|
|
47260
47295
|
const domain = process.env["CODIO_DOMAIN"] ?? "codio.com";
|
|
47261
|
-
|
|
47262
|
-
await
|
|
47263
|
-
const manifest = JSON.parse(
|
|
47264
|
-
const manifestDir =
|
|
47296
|
+
codio.v1.setDomain(domain);
|
|
47297
|
+
await codio.v1.auth(clientId, clientSecret);
|
|
47298
|
+
const manifest = JSON.parse(readFileSync3(input.manifestPath, "utf8"));
|
|
47299
|
+
const manifestDir = join7(input.manifestPath, "..");
|
|
47265
47300
|
if (!manifest.courseId) {
|
|
47266
47301
|
const courseName = manifest.courseName ?? "Codio Course";
|
|
47267
47302
|
if (input.dryRun) {
|
|
@@ -47269,7 +47304,7 @@ async function publishCourseHandler(raw) {
|
|
|
47269
47304
|
} else {
|
|
47270
47305
|
const start = manifest.start ?? new Date().toISOString().replace(/T.*/, "T00:00:00.000Z");
|
|
47271
47306
|
const timezone = manifest.timezone ?? "UTC";
|
|
47272
|
-
manifest.courseId = await
|
|
47307
|
+
manifest.courseId = await codio.v1.course.createCourse({ name: courseName, start, timezone });
|
|
47273
47308
|
if (!manifest.courseName)
|
|
47274
47309
|
manifest.courseName = courseName;
|
|
47275
47310
|
saveManifest(input.manifestPath, manifest);
|
|
@@ -47278,7 +47313,7 @@ async function publishCourseHandler(raw) {
|
|
|
47278
47313
|
const existingModuleIds = new Map;
|
|
47279
47314
|
if (manifest.courseId && !input.dryRun) {
|
|
47280
47315
|
try {
|
|
47281
|
-
const courseInfo = await
|
|
47316
|
+
const courseInfo = await codio.v1.course.info(manifest.courseId);
|
|
47282
47317
|
for (const m of courseInfo.modules ?? []) {
|
|
47283
47318
|
if (m.id && m.name)
|
|
47284
47319
|
existingModuleIds.set(m.name, m.id);
|
|
@@ -47295,7 +47330,7 @@ async function publishCourseHandler(raw) {
|
|
|
47295
47330
|
mod.id = knownId;
|
|
47296
47331
|
saveManifest(input.manifestPath, manifest);
|
|
47297
47332
|
} else if (!input.dryRun && mod.assignments.some((a) => !a.id)) {
|
|
47298
|
-
mod.id = await
|
|
47333
|
+
mod.id = await codio.v1.course.createModule(manifest.courseId, mod.name);
|
|
47299
47334
|
saveManifest(input.manifestPath, manifest);
|
|
47300
47335
|
created++;
|
|
47301
47336
|
}
|
|
@@ -47303,8 +47338,8 @@ async function publishCourseHandler(raw) {
|
|
|
47303
47338
|
for (const asgn of mod.assignments) {
|
|
47304
47339
|
if (input.assignment && asgn.name !== input.assignment && asgn.folder !== input.assignment)
|
|
47305
47340
|
continue;
|
|
47306
|
-
const asgnAbsPath =
|
|
47307
|
-
if (!
|
|
47341
|
+
const asgnAbsPath = join7(manifestDir, asgn.path);
|
|
47342
|
+
if (!existsSync5(asgnAbsPath)) {
|
|
47308
47343
|
skipped++;
|
|
47309
47344
|
continue;
|
|
47310
47345
|
}
|
|
@@ -47318,7 +47353,7 @@ async function publishCourseHandler(raw) {
|
|
|
47318
47353
|
skipped++;
|
|
47319
47354
|
continue;
|
|
47320
47355
|
}
|
|
47321
|
-
asgn.id = await
|
|
47356
|
+
asgn.id = await codio.v1.assignment.createAssignment(manifest.courseId, {
|
|
47322
47357
|
moduleId: mod.id,
|
|
47323
47358
|
settings: { name: asgn.name }
|
|
47324
47359
|
});
|
|
@@ -47342,9 +47377,9 @@ async function publishCourseHandler(raw) {
|
|
|
47342
47377
|
const zipPath = findZip(asgnAbsPath);
|
|
47343
47378
|
try {
|
|
47344
47379
|
if (zipPath) {
|
|
47345
|
-
await
|
|
47380
|
+
await codio.v1.assignment.publishArchive(manifest.courseId, asgn.id, zipPath, publishOpts);
|
|
47346
47381
|
} else {
|
|
47347
|
-
await
|
|
47382
|
+
await codio.v1.assignment.publish(manifest.courseId, asgn.id, asgnAbsPath, publishOpts);
|
|
47348
47383
|
}
|
|
47349
47384
|
asgn.contentHash = computeContentHash(asgnAbsPath);
|
|
47350
47385
|
saveManifest(input.manifestPath, manifest);
|
|
@@ -47358,19 +47393,19 @@ async function publishCourseHandler(raw) {
|
|
|
47358
47393
|
}
|
|
47359
47394
|
|
|
47360
47395
|
// src/tools/validate-guide.ts
|
|
47361
|
-
import { existsSync as
|
|
47362
|
-
import { join as
|
|
47396
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync4, statSync as statSync2 } from "node:fs";
|
|
47397
|
+
import { join as join8, relative as relative2 } from "node:path";
|
|
47363
47398
|
import { z as z6 } from "zod";
|
|
47364
47399
|
var validateGuideInputSchema = z6.object({
|
|
47365
47400
|
workspace: z6.string().min(1)
|
|
47366
47401
|
});
|
|
47367
47402
|
function walkJsonFiles(root) {
|
|
47368
|
-
if (!
|
|
47403
|
+
if (!existsSync6(root))
|
|
47369
47404
|
return [];
|
|
47370
47405
|
const out = [];
|
|
47371
47406
|
for (const name of readdirSync3(root)) {
|
|
47372
|
-
const p =
|
|
47373
|
-
const s =
|
|
47407
|
+
const p = join8(root, name);
|
|
47408
|
+
const s = statSync2(p);
|
|
47374
47409
|
if (s.isDirectory())
|
|
47375
47410
|
out.push(...walkJsonFiles(p));
|
|
47376
47411
|
else if (name.endsWith(".json"))
|
|
@@ -47396,12 +47431,12 @@ var LANG_COMMENT_PREFIX2 = {
|
|
|
47396
47431
|
sql: "--"
|
|
47397
47432
|
};
|
|
47398
47433
|
function walkMdFiles(root) {
|
|
47399
|
-
if (!
|
|
47434
|
+
if (!existsSync6(root))
|
|
47400
47435
|
return [];
|
|
47401
47436
|
const out = [];
|
|
47402
47437
|
for (const name of readdirSync3(root)) {
|
|
47403
|
-
const p =
|
|
47404
|
-
const s =
|
|
47438
|
+
const p = join8(root, name);
|
|
47439
|
+
const s = statSync2(p);
|
|
47405
47440
|
if (s.isDirectory())
|
|
47406
47441
|
out.push(...walkMdFiles(p));
|
|
47407
47442
|
else if (name.endsWith(".md"))
|
|
@@ -47474,7 +47509,7 @@ async function validateGuideHandler(raw) {
|
|
|
47474
47509
|
directory: input.workspace
|
|
47475
47510
|
});
|
|
47476
47511
|
const findings = [];
|
|
47477
|
-
if (!
|
|
47512
|
+
if (!existsSync6(content)) {
|
|
47478
47513
|
findings.push({
|
|
47479
47514
|
category: "missing_content_dir",
|
|
47480
47515
|
detail: `${content} does not exist`,
|
|
@@ -47485,7 +47520,7 @@ async function validateGuideHandler(raw) {
|
|
|
47485
47520
|
for (const f of walkJsonFiles(guides)) {
|
|
47486
47521
|
let parsed;
|
|
47487
47522
|
try {
|
|
47488
|
-
parsed = JSON.parse(
|
|
47523
|
+
parsed = JSON.parse(readFileSync4(f, "utf8"));
|
|
47489
47524
|
} catch {
|
|
47490
47525
|
continue;
|
|
47491
47526
|
}
|
|
@@ -47495,7 +47530,7 @@ async function validateGuideHandler(raw) {
|
|
|
47495
47530
|
if (!isUuidV4(id)) {
|
|
47496
47531
|
findings.push({
|
|
47497
47532
|
category: "invalid_uuid",
|
|
47498
|
-
detail: `${
|
|
47533
|
+
detail: `${relative2(input.workspace, f)}: ${id}`,
|
|
47499
47534
|
severity: "error"
|
|
47500
47535
|
});
|
|
47501
47536
|
}
|
|
@@ -47506,45 +47541,45 @@ async function validateGuideHandler(raw) {
|
|
|
47506
47541
|
continue;
|
|
47507
47542
|
let parsed;
|
|
47508
47543
|
try {
|
|
47509
|
-
parsed = JSON.parse(
|
|
47544
|
+
parsed = JSON.parse(readFileSync4(f, "utf8"));
|
|
47510
47545
|
} catch {
|
|
47511
47546
|
continue;
|
|
47512
47547
|
}
|
|
47513
47548
|
const base = f.slice(0, -"/index.json".length);
|
|
47514
47549
|
for (const stem of parsed?.order ?? []) {
|
|
47515
|
-
const jsonPair =
|
|
47516
|
-
const chapter =
|
|
47550
|
+
const jsonPair = existsSync6(join8(base, `${stem}.json`)) && existsSync6(join8(base, `${stem}.md`));
|
|
47551
|
+
const chapter = existsSync6(join8(base, stem, "index.json"));
|
|
47517
47552
|
if (!jsonPair && !chapter) {
|
|
47518
47553
|
findings.push({
|
|
47519
47554
|
category: "orphan_order_stem",
|
|
47520
|
-
detail: `${
|
|
47555
|
+
detail: `${relative2(input.workspace, f)} references missing stem '${stem}'`,
|
|
47521
47556
|
severity: "error"
|
|
47522
47557
|
});
|
|
47523
47558
|
}
|
|
47524
47559
|
}
|
|
47525
47560
|
}
|
|
47526
47561
|
for (const md of walkMdFiles(content)) {
|
|
47527
|
-
const body =
|
|
47562
|
+
const body = readFileSync4(md, "utf8");
|
|
47528
47563
|
const re = new RegExp(ANY_TASKID_RE.source, "g");
|
|
47529
47564
|
for (const match of body.matchAll(re)) {
|
|
47530
47565
|
const tid = match[0];
|
|
47531
|
-
if (!
|
|
47566
|
+
if (!existsSync6(join8(assessments, `${tid}.json`))) {
|
|
47532
47567
|
findings.push({
|
|
47533
47568
|
category: "broken_assessment_ref",
|
|
47534
|
-
detail: `${
|
|
47569
|
+
detail: `${relative2(input.workspace, md)} references missing ${tid}.json`,
|
|
47535
47570
|
severity: "error"
|
|
47536
47571
|
});
|
|
47537
47572
|
}
|
|
47538
47573
|
}
|
|
47539
47574
|
}
|
|
47540
|
-
if (
|
|
47575
|
+
if (existsSync6(assessments)) {
|
|
47541
47576
|
for (const f of walkJsonFiles(assessments)) {
|
|
47542
47577
|
if (!f.endsWith(".json"))
|
|
47543
47578
|
continue;
|
|
47544
47579
|
const expected = f.split("/").pop().replace(/\.json$/, "");
|
|
47545
47580
|
let parsed;
|
|
47546
47581
|
try {
|
|
47547
|
-
parsed = JSON.parse(
|
|
47582
|
+
parsed = JSON.parse(readFileSync4(f, "utf8"));
|
|
47548
47583
|
} catch {
|
|
47549
47584
|
continue;
|
|
47550
47585
|
}
|
|
@@ -47552,7 +47587,7 @@ async function validateGuideHandler(raw) {
|
|
|
47552
47587
|
if (expected !== actual) {
|
|
47553
47588
|
findings.push({
|
|
47554
47589
|
category: "taskid_filename_mismatch",
|
|
47555
|
-
detail: `${
|
|
47590
|
+
detail: `${relative2(input.workspace, f)}: filename '${expected}' vs taskId '${actual}'`,
|
|
47556
47591
|
severity: "error"
|
|
47557
47592
|
});
|
|
47558
47593
|
}
|
|
@@ -47563,7 +47598,7 @@ async function validateGuideHandler(raw) {
|
|
|
47563
47598
|
continue;
|
|
47564
47599
|
let pageTitle;
|
|
47565
47600
|
try {
|
|
47566
|
-
const parsed = JSON.parse(
|
|
47601
|
+
const parsed = JSON.parse(readFileSync4(f, "utf8"));
|
|
47567
47602
|
pageTitle = parsed?.title;
|
|
47568
47603
|
} catch {
|
|
47569
47604
|
continue;
|
|
@@ -47571,34 +47606,34 @@ async function validateGuideHandler(raw) {
|
|
|
47571
47606
|
if (!pageTitle)
|
|
47572
47607
|
continue;
|
|
47573
47608
|
const mdPath = f.replace(/\.json$/, ".md");
|
|
47574
|
-
if (!
|
|
47609
|
+
if (!existsSync6(mdPath))
|
|
47575
47610
|
continue;
|
|
47576
|
-
const body =
|
|
47611
|
+
const body = readFileSync4(mdPath, "utf8");
|
|
47577
47612
|
const firstH1 = findFirstH1(body);
|
|
47578
47613
|
if (firstH1 && firstH1 === pageTitle) {
|
|
47579
47614
|
findings.push({
|
|
47580
47615
|
category: "double_header",
|
|
47581
|
-
detail: `${
|
|
47616
|
+
detail: `${relative2(input.workspace, mdPath)}: first H1 "${firstH1}" duplicates page title — remove H1 from body`,
|
|
47582
47617
|
severity: "warning"
|
|
47583
47618
|
});
|
|
47584
47619
|
}
|
|
47585
47620
|
}
|
|
47586
47621
|
for (const md of walkMdFiles(content)) {
|
|
47587
|
-
const body =
|
|
47622
|
+
const body = readFileSync4(md, "utf8");
|
|
47588
47623
|
for (const err of checkFreezeDirectives(body)) {
|
|
47589
47624
|
findings.push({
|
|
47590
47625
|
category: "freeze_syntax_error",
|
|
47591
|
-
detail: `${
|
|
47626
|
+
detail: `${relative2(input.workspace, md)}: ${err}`,
|
|
47592
47627
|
severity: "error"
|
|
47593
47628
|
});
|
|
47594
47629
|
}
|
|
47595
47630
|
}
|
|
47596
47631
|
for (const md of walkMdFiles(content)) {
|
|
47597
|
-
const body =
|
|
47632
|
+
const body = readFileSync4(md, "utf8");
|
|
47598
47633
|
for (const err of findMalformedTryIt(body)) {
|
|
47599
47634
|
findings.push({
|
|
47600
47635
|
category: "try_it_syntax_error",
|
|
47601
|
-
detail: `${
|
|
47636
|
+
detail: `${relative2(input.workspace, md)}: ${err}`,
|
|
47602
47637
|
severity: "error"
|
|
47603
47638
|
});
|
|
47604
47639
|
}
|
|
@@ -47608,7 +47643,7 @@ async function validateGuideHandler(raw) {
|
|
|
47608
47643
|
continue;
|
|
47609
47644
|
let parsed;
|
|
47610
47645
|
try {
|
|
47611
|
-
parsed = JSON.parse(
|
|
47646
|
+
parsed = JSON.parse(readFileSync4(f, "utf8"));
|
|
47612
47647
|
} catch {
|
|
47613
47648
|
continue;
|
|
47614
47649
|
}
|
|
@@ -47616,10 +47651,10 @@ async function validateGuideHandler(raw) {
|
|
|
47616
47651
|
const filePath = entry?.path;
|
|
47617
47652
|
if (!filePath)
|
|
47618
47653
|
continue;
|
|
47619
|
-
if (!
|
|
47654
|
+
if (!existsSync6(join8(input.workspace, filePath))) {
|
|
47620
47655
|
findings.push({
|
|
47621
47656
|
category: "missing_referenced_file",
|
|
47622
|
-
detail: `${
|
|
47657
|
+
detail: `${relative2(input.workspace, f)}: references file "${filePath}" which does not exist in workspace`,
|
|
47623
47658
|
severity: "warning"
|
|
47624
47659
|
});
|
|
47625
47660
|
}
|
|
@@ -47663,7 +47698,7 @@ var fetch_course = tool({
|
|
|
47663
47698
|
}
|
|
47664
47699
|
});
|
|
47665
47700
|
var publish_course = tool({
|
|
47666
|
-
description: "Publish Codio course assignments to the platform. Reads course-manifest.json, creates missing courses/modules/assignments, and publishes each one. Skips unchanged assignments by content hash. Returns { published, created, unchanged, skipped }.",
|
|
47701
|
+
description: "Publish Codio course assignments to the platform. Reads course-manifest.json from manifestPath, creates missing courses/modules/assignments, and publishes each one. Skips unchanged assignments by content hash. Returns { published, created, unchanged, skipped }.",
|
|
47667
47702
|
args: publishCourseInputSchema.shape,
|
|
47668
47703
|
async execute(args) {
|
|
47669
47704
|
return JSON.stringify(await publishCourseHandler(args));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-course.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-course.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch-course.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-course.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,sBAAsB;;;;;iBAQjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAyDD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8GjF"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export declare const fetch_course: {
|
|
|
76
76
|
export declare const publish_course: {
|
|
77
77
|
description: string;
|
|
78
78
|
args: {
|
|
79
|
+
workspace: import("zod").ZodString;
|
|
79
80
|
manifestPath: import("zod").ZodString;
|
|
80
81
|
dryRun: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
81
82
|
force: import("zod").ZodOptional<import("zod").ZodBoolean>;
|
|
@@ -85,6 +86,7 @@ export declare const publish_course: {
|
|
|
85
86
|
stack: import("zod").ZodOptional<import("zod").ZodString>;
|
|
86
87
|
};
|
|
87
88
|
execute(args: {
|
|
89
|
+
workspace: string;
|
|
88
90
|
manifestPath: string;
|
|
89
91
|
dryRun?: boolean | undefined;
|
|
90
92
|
force?: boolean | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOtB,CAAC;AAOH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;CAkB5B,CAAC;AAIH,eAAO,MAAM,cAAc;;;;;;;;CAOzB,CAAC;AAIH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAOvB,CAAC;AAIH,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOtB,CAAC;AAOH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;CAkB5B,CAAC;AAIH,eAAO,MAAM,cAAc;;;;;;;;CAOzB,CAAC;AAIH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAOvB,CAAC;AAIH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;CAOzB,CAAC;AAQH,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAMzC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-course.d.ts","sourceRoot":"","sources":["../../src/tools/publish-course.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish-course.d.ts","sourceRoot":"","sources":["../../src/tools/publish-course.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,wBAAwB;;;;;;;;;iBASnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AA6DD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA2HrF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk up from startDir looking for a .env file.
|
|
3
|
+
* When found, load it with override semantics — .env values always win
|
|
4
|
+
* over whatever is already in process.env.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadEnvWalkUp(startDir: string): void;
|
|
7
|
+
//# sourceMappingURL=load-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-env.d.ts","sourceRoot":"","sources":["../../src/utils/load-env.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAoBpD"}
|
package/package.json
CHANGED