codiedev 0.9.86 → 0.9.87
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/codie.js +13 -1
- package/dist/codieLauncher.d.ts +4 -0
- package/dist/codieLauncher.js +8 -0
- package/dist/commands/pack.d.ts +1 -1
- package/dist/commands/pack.js +58 -5
- package/dist/managedPi.js +3 -0
- package/dist/packs/localSkills.d.ts +18 -0
- package/dist/packs/localSkills.js +130 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +50 -10
- package/package.json +1 -1
package/dist/codie.js
CHANGED
|
@@ -50,6 +50,7 @@ const path = __importStar(require("path"));
|
|
|
50
50
|
const child_process_1 = require("child_process");
|
|
51
51
|
const url_1 = require("url");
|
|
52
52
|
const configDir_1 = require("./configDir");
|
|
53
|
+
const utils_1 = require("./utils");
|
|
53
54
|
const codieLauncher_1 = require("./codieLauncher");
|
|
54
55
|
const codieBrandInstall_1 = require("./codieBrandInstall");
|
|
55
56
|
const codieUsage_1 = require("./codieUsage");
|
|
@@ -274,12 +275,23 @@ async function main() {
|
|
|
274
275
|
const capturePlugin = (0, codieLauncher_1.resolveCapturePlugin)({ homeDir: os.homedir(), existsSync: fs.existsSync });
|
|
275
276
|
(0, codieBrandInstall_1.installTuiPlugin)();
|
|
276
277
|
installBrandWordmark(runtime);
|
|
277
|
-
|
|
278
|
+
// OpenCode doesn't read the instruction blocks `connect` writes for other
|
|
279
|
+
// tools, so Codie ships its own copy of the Codiedev commands.
|
|
280
|
+
const instructionsFile = path.join(stateDir, "codie-instructions.md");
|
|
281
|
+
try {
|
|
282
|
+
fs.mkdirSync(stateDir, { recursive: true });
|
|
283
|
+
fs.writeFileSync(instructionsFile, (0, utils_1.codiedevInstructionsText)(), "utf8");
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
console.error(`codie: couldn't write the Codiedev instructions (${error instanceof Error ? error.message : error})`);
|
|
287
|
+
}
|
|
288
|
+
const baseConfig = (0, codieLauncher_1.buildCodieConfig)({
|
|
278
289
|
existing: withStarterPacks(existingInlineConfig(), new Set(catalog.map((model) => (0, codieLauncher_1.bareModel)(model.id)).filter(Boolean)), catalog),
|
|
279
290
|
catalog,
|
|
280
291
|
env: { ...process.env, ...parsed.overrides, CODIEDEV_GATEWAY_URL: gatewayUrl },
|
|
281
292
|
plugins: [capturePlugin, metadataPlugin],
|
|
282
293
|
});
|
|
294
|
+
const config = fs.existsSync(instructionsFile) ? (0, codieLauncher_1.withCodiedevInstructions)(baseConfig, instructionsFile) : baseConfig;
|
|
283
295
|
const env = {
|
|
284
296
|
...process.env,
|
|
285
297
|
...parsed.overrides,
|
package/dist/codieLauncher.d.ts
CHANGED
|
@@ -33,6 +33,10 @@ export declare function usableModelLimit(value: unknown): ModelLimit | undefined
|
|
|
33
33
|
*/
|
|
34
34
|
export declare function withCodieWorkingDirectory(args: string[], cwd: string): string[];
|
|
35
35
|
export declare function bareModel(value: unknown): string;
|
|
36
|
+
/** Add the Codiedev instructions file to OpenCode's `instructions` (kept
|
|
37
|
+
* alongside the user's own, never duplicated). Codie writes the file itself:
|
|
38
|
+
* OpenCode never sees the instruction blocks `connect` writes for other tools. */
|
|
39
|
+
export declare function withCodiedevInstructions(config: Record<string, any>, file: string): Record<string, any>;
|
|
36
40
|
export declare function buildCodieConfig({ existing, catalog, env, plugin, plugins, }: {
|
|
37
41
|
existing?: Record<string, any>;
|
|
38
42
|
catalog: CatalogModel[];
|
package/dist/codieLauncher.js
CHANGED
|
@@ -47,6 +47,7 @@ exports.usableModelCost = usableModelCost;
|
|
|
47
47
|
exports.usableModelLimit = usableModelLimit;
|
|
48
48
|
exports.withCodieWorkingDirectory = withCodieWorkingDirectory;
|
|
49
49
|
exports.bareModel = bareModel;
|
|
50
|
+
exports.withCodiedevInstructions = withCodiedevInstructions;
|
|
50
51
|
exports.buildCodieConfig = buildCodieConfig;
|
|
51
52
|
exports.stageUsageModule = stageUsageModule;
|
|
52
53
|
exports.withBrandPlugin = withBrandPlugin;
|
|
@@ -140,6 +141,13 @@ function normalizeAgentModels(agents, approved, fallback) {
|
|
|
140
141
|
}
|
|
141
142
|
return normalized;
|
|
142
143
|
}
|
|
144
|
+
/** Add the Codiedev instructions file to OpenCode's `instructions` (kept
|
|
145
|
+
* alongside the user's own, never duplicated). Codie writes the file itself:
|
|
146
|
+
* OpenCode never sees the instruction blocks `connect` writes for other tools. */
|
|
147
|
+
function withCodiedevInstructions(config, file) {
|
|
148
|
+
const current = Array.isArray(config.instructions) ? config.instructions.filter((x) => typeof x === "string") : [];
|
|
149
|
+
return { ...config, instructions: current.includes(file) ? current : [...current, file] };
|
|
150
|
+
}
|
|
143
151
|
function buildCodieConfig({ existing = {}, catalog, env = {}, plugin, plugins = [], }) {
|
|
144
152
|
if (!Array.isArray(catalog) || catalog.length === 0) {
|
|
145
153
|
throw new Error("No company-approved models were returned by Codiedev");
|
package/dist/commands/pack.d.ts
CHANGED
|
@@ -67,4 +67,4 @@ export interface PublishResult {
|
|
|
67
67
|
/** `codiedev pack publish <slug> [--channel stable|beta|alpha]`: snapshot the
|
|
68
68
|
* draft onto a channel. Re-running with no changes publishes nothing. */
|
|
69
69
|
export declare function runPublish(config: CodiedevConfig, args: PackArgs): Promise<PublishResult>;
|
|
70
|
-
export declare const PACK_HELP = "Usage:\n codiedev pack list Packs assigned to your team\n codiedev pack install [slug] [--harness claude,codex,copilot,cursor,codie,pi] [--dry-run] [--json] [--quiet]\n Install one pack, or every pack that applies\n codiedev pack status [--json] Installed packs and whether they're up to date\n codiedev pack export <slug> --out <dir> [--git] [--manifest]\n Write the pack as a Claude-format plugin folder plus\n .claude-plugin/marketplace.json (commit it for CI).\n --git inits the folder and commits; --manifest writes\n an editable <slug>.pack.md instead\n codiedev pack apply <pack.md> [--publish] [--channel stable|beta|alpha] [--dry-run]\n Create or update a pack from a pack.md\n (--publish then publishes it, see below)\n codiedev pack publish <slug> [--channel stable|beta|alpha]\n Publish the pack's draft to a channel (default\n stable). Nothing happens when it hasn't changed.\n\nFiles (scripts, PDFs, a runner folder): list them under \"## Files\" in pack.md,\none \"- <path in pack> <- <local path>\" per line (local paths are relative to\nthe pack.md; \".\" is the pack root):\n\n ## Files\n\n - runner <- ~/.claude/runner\n - skills/healthcare-scan <- ~/.claude/skills/healthcare-scan\n\n`pack apply` uploads them (admins and team managers; 15MB per file, 50MB per\npack; caches, .git and hidden files are skipped). Without a \"## Files\"\nsection the pack's files are left alone. In skills, point at files relative to\nthe skill's folder, or use ${CLAUDE_PLUGIN_ROOT}/runner/...: Codiedev swaps in the\nreal path for Codex, Copilot, Cursor, pi and Codie.\n\nCursor: packs are copied to ~/.cursor/plugins/local/codiedev-<slug>/. A Cursor\nteam admin can disable \"user local plugin imports\"; then Cursor ignores them.\n\nAuto-update: session starts run `codiedev pack install --quiet` in the background\nabout once an hour. Opt out with CODIEDEV_PACK_AUTOSYNC=0.\n\nHooks for specific skills only: codiedev hook-gate --skills a,b --cmd-b64 <base64url of the command>\n(the pack editor writes this; the command runs via /bin/sh, or cmd.exe on Windows)\n\nCI: set CODIEDEV_TOKEN to a pack CI key (cdvci_\u2026, from the pack's page in the portal).\nNo `codiedev connect` or config file is needed. CI mode (a cdvci_ key, or CI=true)\nnever auto-syncs, reports or prunes, installs the one pack the key can see, defaults\n--harness to claude when it's on PATH, and exits non-zero unless every requested tool\ngot the pack. Skills from a pack are /<pack-slug>:<skill> in Claude Code.\n\n GitLab CI (.gitlab-ci.yml; add CODIEDEV_TOKEN and ANTHROPIC_API_KEY as masked\n CI/CD variables):\n pack-scan:\n image: node:22\n script:\n - npm i -g codiedev @anthropic-ai/claude-code\n - codiedev pack install --harness claude\n - claude -p \"/platform-starter:healthcare-scan\" --output-format text\n\n GitHub Actions (repository secrets CODIEDEV_TOKEN and ANTHROPIC_API_KEY):\n - uses: actions/setup-node@v4\n with: { node-version: 22 }\n - run: npm i -g codiedev @anthropic-ai/claude-code\n - run: codiedev pack install --harness claude\n env:\n CODIEDEV_TOKEN: ${{ secrets.CODIEDEV_TOKEN }}\n - run: claude -p \"/platform-starter:healthcare-scan\" --output-format text\n env:\n ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n\n Keep a pack up to date from its repo (GitLab; on merges to main). Use a\n personal Codiedev token of a pack owner (portal \u2192 Integrations \u2192 CLI tokens) as a\n masked CODIEDEV_TOKEN: pack CI keys can only install, not publish.\n pack-release:\n image: node:22\n rules: [{ if: '$CI_COMMIT_BRANCH == \"main\"' }]\n script:\n - npm i -g codiedev\n - codiedev pack apply packs/platform-starter.pack.md --publish\n
|
|
70
|
+
export declare const PACK_HELP = "Usage:\n codiedev pack list Packs assigned to your team\n codiedev pack install [slug] [--harness claude,codex,copilot,cursor,codie,pi] [--dry-run] [--json] [--quiet]\n Install one pack, or every pack that applies\n codiedev pack status [--json] Installed packs and whether they're up to date\n codiedev pack export <slug> --out <dir> [--git] [--manifest]\n Write the pack as a Claude-format plugin folder plus\n .claude-plugin/marketplace.json (commit it for CI).\n --git inits the folder and commits; --manifest writes\n an editable <slug>.pack.md instead\n codiedev pack apply <pack.md> [--publish] [--channel stable|beta|alpha] [--dry-run]\n Create or update a pack from a pack.md\n (--publish then publishes it, see below)\n codiedev pack publish <slug> [--channel stable|beta|alpha]\n Publish the pack's draft to a channel (default\n stable). Nothing happens when it hasn't changed.\n\nFiles (scripts, PDFs, a runner folder): list them under \"## Files\" in pack.md,\none \"- <path in pack> <- <local path>\" per line (local paths are relative to\nthe pack.md; \".\" is the pack root):\n\n ## Files\n\n - runner <- ~/.claude/runner\n - skills/healthcare-scan <- ~/.claude/skills/healthcare-scan\n\n`pack apply` uploads them (admins and team managers; 15MB per file, 50MB per\npack; caches, .git and hidden files are skipped). Without a \"## Files\"\nsection the pack's files are left alone. In skills, point at files relative to\nthe skill's folder, or use ${CLAUDE_PLUGIN_ROOT}/runner/...: Codiedev swaps in the\nreal path for Codex, Copilot, Cursor, pi and Codie.\n\nCursor: packs are copied to ~/.cursor/plugins/local/codiedev-<slug>/. A Cursor\nteam admin can disable \"user local plugin imports\"; then Cursor ignores them.\n\nAuto-update: session starts run `codiedev pack install --quiet` in the background\nabout once an hour. Opt out with CODIEDEV_PACK_AUTOSYNC=0.\n\nHooks for specific skills only: codiedev hook-gate --skills a,b --cmd-b64 <base64url of the command>\n(the pack editor writes this; the command runs via /bin/sh, or cmd.exe on Windows)\n\nCI: set CODIEDEV_TOKEN to a pack CI key (cdvci_\u2026, from the pack's page in the portal).\nNo `codiedev connect` or config file is needed. CI mode (a cdvci_ key, or CI=true)\nnever auto-syncs, reports or prunes, installs the one pack the key can see, defaults\n--harness to claude when it's on PATH, and exits non-zero unless every requested tool\ngot the pack. Skills from a pack are /<pack-slug>:<skill> in Claude Code.\n\n GitLab CI (.gitlab-ci.yml; add CODIEDEV_TOKEN and ANTHROPIC_API_KEY as masked\n CI/CD variables):\n pack-scan:\n image: node:22\n script:\n - npm i -g codiedev @anthropic-ai/claude-code\n - codiedev pack install --harness claude\n - claude -p \"/platform-starter:healthcare-scan\" --output-format text\n\n GitHub Actions (repository secrets CODIEDEV_TOKEN and ANTHROPIC_API_KEY):\n - uses: actions/setup-node@v4\n with: { node-version: 22 }\n - run: npm i -g codiedev @anthropic-ai/claude-code\n - run: codiedev pack install --harness claude\n env:\n CODIEDEV_TOKEN: ${{ secrets.CODIEDEV_TOKEN }}\n - run: claude -p \"/platform-starter:healthcare-scan\" --output-format text\n env:\n ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}\n\n Keep a pack up to date from its repo (GitLab; on merges to main). Use a\n personal Codiedev token of a pack owner (portal \u2192 Integrations \u2192 CLI tokens) as a\n masked CODIEDEV_TOKEN: pack CI keys can only install, not publish.\n pack-release:\n image: node:22\n rules: [{ if: '$CI_COMMIT_BRANCH == \"main\"' }]\n script:\n - npm i -g codiedev\n - codiedev pack apply packs/platform-starter.pack.md --publish\n Skills listed in pack.md as local folders (\"- ./skills/healthcare-scan\") are\n pushed when their SKILL.md changed, and the rest of each folder ships with it.\n\n Or vendor the plugin into the repo instead of installing at build time:\n codiedev pack export <slug> --out .codiedev/packs";
|
package/dist/commands/pack.js
CHANGED
|
@@ -60,6 +60,9 @@ const sync_1 = require("../packs/sync");
|
|
|
60
60
|
const harnesses_2 = require("../packs/harnesses");
|
|
61
61
|
const os = __importStar(require("os"));
|
|
62
62
|
const utils_1 = require("../utils");
|
|
63
|
+
const push_1 = require("./push");
|
|
64
|
+
const skillMarker_1 = require("../skillMarker");
|
|
65
|
+
const localSkills_1 = require("../packs/localSkills");
|
|
63
66
|
const shared_1 = require("./shared");
|
|
64
67
|
const files_1 = require("../packs/files");
|
|
65
68
|
// --- CI (pack-scoped `cdvci_` keys) ------------------------------------------
|
|
@@ -170,8 +173,8 @@ got the pack. Skills from a pack are /<pack-slug>:<skill> in Claude Code.
|
|
|
170
173
|
script:
|
|
171
174
|
- npm i -g codiedev
|
|
172
175
|
- codiedev pack apply packs/platform-starter.pack.md --publish
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
Skills listed in pack.md as local folders ("- ./skills/healthcare-scan") are
|
|
177
|
+
pushed when their SKILL.md changed, and the rest of each folder ships with it.
|
|
175
178
|
|
|
176
179
|
Or vendor the plugin into the repo instead of installing at build time:
|
|
177
180
|
codiedev pack export <slug> --out .codiedev/packs`;
|
|
@@ -667,19 +670,44 @@ async function runApply(config, args) {
|
|
|
667
670
|
}
|
|
668
671
|
if (!markdown.trim())
|
|
669
672
|
throw new Error(`${file} is empty`);
|
|
673
|
+
const baseDir = path.dirname(file);
|
|
674
|
+
// SIG-128: local skills under `## Skills` are pushed, and a skill folder's
|
|
675
|
+
// other contents ship as that skill's files.
|
|
676
|
+
const skills = (0, localSkills_1.findLocalSkills)(markdown, baseDir);
|
|
670
677
|
// `## Files` (SIG-127): local folders/files to ship in the plugin dir.
|
|
671
|
-
//
|
|
678
|
+
// Neither a Files section nor a local skill folder ⇒ the pack's files are
|
|
679
|
+
// left as they are; otherwise this list replaces them.
|
|
672
680
|
const entries = (0, files_1.parseFilesSection)(markdown);
|
|
673
|
-
const
|
|
674
|
-
|
|
681
|
+
const listed = new Set((entries ?? []).map((e) => e.dest.replace(/^\.\/+/, "").replace(/\/+$/, "").toLowerCase()));
|
|
682
|
+
const folderEntries = (0, localSkills_1.skillFolderEntries)(skills).filter((e) => !listed.has(e.dest.toLowerCase()));
|
|
683
|
+
const allEntries = entries || folderEntries.length ? [...(entries ?? []), ...folderEntries] : null;
|
|
684
|
+
const local = allEntries ? (0, files_1.collectLocalFiles)(allEntries, baseDir) : null;
|
|
685
|
+
const ownSkillMd = new Set(skills.map((s) => `${s.pluginDir}/SKILL.md`.toLowerCase()));
|
|
686
|
+
for (const note of local?.notes ?? []) {
|
|
687
|
+
// A local skill's own SKILL.md is pushed as the skill, not skipped.
|
|
688
|
+
if ([...ownSkillMd].some((p) => note.toLowerCase().includes(p)))
|
|
689
|
+
continue;
|
|
675
690
|
console.log(` · ${note}`);
|
|
691
|
+
}
|
|
676
692
|
if (args.dryRun) {
|
|
677
693
|
const extra = local ? `, ${local.files.length} file${local.files.length === 1 ? "" : "s"} (${formatBytes(local.files.reduce((n, f) => n + f.size, 0))})` : "";
|
|
678
694
|
console.log(`Dry run — would apply ${file} (${Buffer.byteLength(markdown)} bytes${extra}).`);
|
|
695
|
+
for (const skill of skills)
|
|
696
|
+
console.log(` skill ${skill.name} ← ${path.relative(baseDir, skill.skillFile) || skill.skillFile} (pushed if changed)`);
|
|
679
697
|
for (const f of local?.files ?? [])
|
|
680
698
|
console.log(` ${f.path}`);
|
|
681
699
|
return {};
|
|
682
700
|
}
|
|
701
|
+
const keys = new Map();
|
|
702
|
+
let pushedSkills = 0;
|
|
703
|
+
for (const skill of skills) {
|
|
704
|
+
const { key, pushed } = await pushLocalSkill(config, skill);
|
|
705
|
+
keys.set(skill.line, key);
|
|
706
|
+
if (pushed)
|
|
707
|
+
pushedSkills += 1;
|
|
708
|
+
}
|
|
709
|
+
if (keys.size)
|
|
710
|
+
markdown = (0, localSkills_1.rewriteLocalSkills)(markdown, keys);
|
|
683
711
|
let uploaded = 0;
|
|
684
712
|
if (local?.files.length)
|
|
685
713
|
uploaded = await uploadPackFiles(config, local.files);
|
|
@@ -708,6 +736,8 @@ async function runApply(config, args) {
|
|
|
708
736
|
const verb = res.created === true ? "Created" : res.changed === false ? "No changes to" : "Updated";
|
|
709
737
|
const version = typeof res.version === "number" ? ` v${res.version}` : "";
|
|
710
738
|
console.log(`✓ ${verb} ${slug}${version} from ${path.basename(file)}`);
|
|
739
|
+
if (skills.length)
|
|
740
|
+
console.log(` skills: ${skills.length} local (${pushedSkills} pushed, ${skills.length - pushedSkills} unchanged)`);
|
|
711
741
|
if (local)
|
|
712
742
|
console.log(` files: ${local.files.length} (${uploaded} uploaded, ${local.files.length - uploaded} already on Codiedev)`);
|
|
713
743
|
if (Array.isArray(res.warnings)) {
|
|
@@ -762,6 +792,29 @@ async function runPublish(config, args) {
|
|
|
762
792
|
console.log(`✓ Published ${out.slug} v${out.version} to ${channel}. Teams on ${channel} get it at their next sync.`);
|
|
763
793
|
return out;
|
|
764
794
|
}
|
|
795
|
+
/** Push a local skill unless the library already has this exact text (so CI
|
|
796
|
+
* doesn't add a version on every merge). Team-visible: packs ship to teams. */
|
|
797
|
+
async function pushLocalSkill(config, skill) {
|
|
798
|
+
const local = (0, skillMarker_1.stripSkillMarker)(fs.readFileSync(skill.skillFile, "utf8"));
|
|
799
|
+
try {
|
|
800
|
+
const current = await (0, shared_1.apiRequest)("GET", "/api/cli/pull", { config, query: { key: skill.name } });
|
|
801
|
+
const remote = current.artifact?.markdown;
|
|
802
|
+
if (current.artifact?.kind === "skill" && typeof remote === "string" && (0, skillMarker_1.stripSkillMarker)(remote).trimEnd() === local.trimEnd()) {
|
|
803
|
+
return { key: skill.name, pushed: false };
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
catch (error) {
|
|
807
|
+
if (error.status !== 404)
|
|
808
|
+
throw new Error(`couldn't check skill ${skill.name} (${error.message})`);
|
|
809
|
+
}
|
|
810
|
+
try {
|
|
811
|
+
const res = await (0, push_1.pushFile)(config, { absPath: skill.skillFile, key: path.basename(skill.skillFile), kind: "skill", visibility: "team" });
|
|
812
|
+
return { key: res.key ?? skill.name, pushed: true };
|
|
813
|
+
}
|
|
814
|
+
catch (error) {
|
|
815
|
+
throw new Error(`couldn't push skill ${skill.name} (${error.message})`);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
765
818
|
function formatBytes(n) {
|
|
766
819
|
return n >= 1024 * 1024 ? `${(n / (1024 * 1024)).toFixed(1)}MB` : n >= 1024 ? `${Math.round(n / 1024)}KB` : `${n}B`;
|
|
767
820
|
}
|
package/dist/managedPi.js
CHANGED
|
@@ -230,6 +230,9 @@ function prepareManagedPiDir(opts) {
|
|
|
230
230
|
// extensions dropped into the dir go away on every launch.
|
|
231
231
|
fs.rmSync(path.join(agentDir, "auth.json"), { force: true });
|
|
232
232
|
fs.rmSync(path.join(agentDir, "extensions"), { recursive: true, force: true });
|
|
233
|
+
// pi reads <agentDir>/AGENTS.md as global context; the managed dir is ours,
|
|
234
|
+
// so the Codiedev instructions are written fresh on every launch.
|
|
235
|
+
fs.writeFileSync(path.join(agentDir, "AGENTS.md"), (0, utils_1.codiedevInstructionsText)(), { mode: 0o600 });
|
|
233
236
|
const guard = path.join(agentDir, exports.GUARD_FILE);
|
|
234
237
|
fs.writeFileSync(guard, exports.GUARD_SOURCE, { mode: 0o600 });
|
|
235
238
|
const capture = path.join(agentDir, exports.CAPTURE_FILE);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FilesEntry } from "./files";
|
|
2
|
+
export interface LocalSkill {
|
|
3
|
+
/** 1-based line in pack.md. */
|
|
4
|
+
line: number;
|
|
5
|
+
source: string;
|
|
6
|
+
skillFile: string;
|
|
7
|
+
/** The skill folder, when the entry named one (its files ship with the skill). */
|
|
8
|
+
dir: string | null;
|
|
9
|
+
name: string;
|
|
10
|
+
/** `skills/<dir>/` in the plugin, matching the server's skillDirName. */
|
|
11
|
+
pluginDir: string;
|
|
12
|
+
}
|
|
13
|
+
/** Local-path lines under `## Skills` (fenced blocks are skipped). */
|
|
14
|
+
export declare function findLocalSkills(markdown: string, baseDir: string, home?: string): LocalSkill[];
|
|
15
|
+
/** pack.md with each local skill line replaced by `- <key> @me`. */
|
|
16
|
+
export declare function rewriteLocalSkills(markdown: string, keys: Map<number, string>): string;
|
|
17
|
+
/** Files entries for skill folders, so their scripts/docs ship with them. */
|
|
18
|
+
export declare function skillFolderEntries(skills: LocalSkill[]): FilesEntry[];
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.findLocalSkills = findLocalSkills;
|
|
37
|
+
exports.rewriteLocalSkills = rewriteLocalSkills;
|
|
38
|
+
exports.skillFolderEntries = skillFolderEntries;
|
|
39
|
+
// SIG-128: local skills in a pack.md. Under `## Skills`, a line naming a local
|
|
40
|
+
// path (`./…`, `../…`, `~/…`, `/…`) instead of `<key> @<author email>` is a
|
|
41
|
+
// skill on this machine: `pack apply` pushes it to the library (only when it
|
|
42
|
+
// changed) and rewrites the line to `<key> @me`. A skill FOLDER also ships
|
|
43
|
+
// the rest of its contents (scripts/, docs/…) as the skill's pack files.
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const os = __importStar(require("os"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const files_1 = require("./files");
|
|
48
|
+
const manifest_1 = require("./manifest");
|
|
49
|
+
const LOCAL = /^(\.{1,2}\/|~\/|~$|\/)/;
|
|
50
|
+
/** Same rule as the server's skillDirName: the frontmatter name when it's a
|
|
51
|
+
* safe folder name, else a slug of it. */
|
|
52
|
+
function pluginDirName(name) {
|
|
53
|
+
if (/^[A-Za-z0-9][A-Za-z0-9._ -]{0,127}$/.test(name) && !name.includes(".."))
|
|
54
|
+
return name;
|
|
55
|
+
const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48).replace(/-+$/g, "");
|
|
56
|
+
return slug || "pack";
|
|
57
|
+
}
|
|
58
|
+
/** Local-path lines under `## Skills` (fenced blocks are skipped). */
|
|
59
|
+
function findLocalSkills(markdown, baseDir, home = os.homedir()) {
|
|
60
|
+
const lines = markdown.replace(/^/, "").split("\n").map((l) => l.replace(/\r$/, ""));
|
|
61
|
+
const out = [];
|
|
62
|
+
let fence = null;
|
|
63
|
+
let inSkills = false;
|
|
64
|
+
for (let i = 0; i < lines.length; i++) {
|
|
65
|
+
const line = lines[i];
|
|
66
|
+
const f = line.match(/^(`{3,})/);
|
|
67
|
+
if (f) {
|
|
68
|
+
if (!fence)
|
|
69
|
+
fence = f[1];
|
|
70
|
+
else if (f[1].length >= fence.length && /^`+\s*$/.test(line))
|
|
71
|
+
fence = null;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (fence)
|
|
75
|
+
continue;
|
|
76
|
+
const h2 = line.match(/^##\s+(.+?)\s*$/);
|
|
77
|
+
if (h2 && !line.startsWith("###")) {
|
|
78
|
+
inSkills = h2[1].toLowerCase() === "skills";
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (!inSkills)
|
|
82
|
+
continue;
|
|
83
|
+
const m = line.match(/^\s*[-*]\s+(.+?)\s*$/);
|
|
84
|
+
if (!m)
|
|
85
|
+
continue;
|
|
86
|
+
const raw = m[1].replace(/^["']|["']$/g, "");
|
|
87
|
+
if (!LOCAL.test(raw))
|
|
88
|
+
continue;
|
|
89
|
+
const abs = path.resolve(baseDir, (0, files_1.expandHome)(raw, home));
|
|
90
|
+
let stat;
|
|
91
|
+
try {
|
|
92
|
+
stat = fs.statSync(abs);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
throw new Error(`pack.md line ${i + 1}: ${raw} doesn't exist`);
|
|
96
|
+
}
|
|
97
|
+
const dir = stat.isDirectory() ? abs : null;
|
|
98
|
+
const skillFile = dir ? path.join(dir, "SKILL.md") : abs;
|
|
99
|
+
if (!fs.existsSync(skillFile))
|
|
100
|
+
throw new Error(`pack.md line ${i + 1}: no SKILL.md in ${raw}`);
|
|
101
|
+
const { data } = (0, manifest_1.parseFrontmatter)(fs.readFileSync(skillFile, "utf8"));
|
|
102
|
+
const name = (data.name ?? "").trim();
|
|
103
|
+
if (!name || !(data.description ?? "").trim()) {
|
|
104
|
+
throw new Error(`pack.md line ${i + 1}: ${path.relative(baseDir, skillFile) || skillFile} needs SKILL.md frontmatter with name: and description:`);
|
|
105
|
+
}
|
|
106
|
+
out.push({ line: i + 1, source: raw, skillFile, dir, name, pluginDir: `skills/${pluginDirName(name)}` });
|
|
107
|
+
}
|
|
108
|
+
const seen = new Map();
|
|
109
|
+
for (const skill of out) {
|
|
110
|
+
const prior = seen.get(skill.name.toLowerCase());
|
|
111
|
+
if (prior)
|
|
112
|
+
throw new Error(`pack.md lines ${prior.line} and ${skill.line} both add a skill named "${skill.name}"`);
|
|
113
|
+
seen.set(skill.name.toLowerCase(), skill);
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
/** pack.md with each local skill line replaced by `- <key> @me`. */
|
|
118
|
+
function rewriteLocalSkills(markdown, keys) {
|
|
119
|
+
const lines = markdown.split("\n");
|
|
120
|
+
for (const [line, key] of keys) {
|
|
121
|
+
const cr = lines[line - 1].endsWith("\r") ? "\r" : "";
|
|
122
|
+
const indent = lines[line - 1].match(/^\s*/)?.[0] ?? "";
|
|
123
|
+
lines[line - 1] = `${indent}- ${key} @me${cr}`;
|
|
124
|
+
}
|
|
125
|
+
return lines.join("\n");
|
|
126
|
+
}
|
|
127
|
+
/** Files entries for skill folders, so their scripts/docs ship with them. */
|
|
128
|
+
function skillFolderEntries(skills) {
|
|
129
|
+
return skills.filter((s) => s.dir).map((s) => ({ dest: s.pluginDir, source: s.dir, line: s.line }));
|
|
130
|
+
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -143,6 +143,11 @@ export declare function ensureAllCodiedevHooksInstalled(): void;
|
|
|
143
143
|
export declare function hasDirectHookPath(configText: string): boolean;
|
|
144
144
|
export declare function migrateHooksToLauncher(): string[];
|
|
145
145
|
export declare function ensureSessionStartHookInstalled(): void;
|
|
146
|
+
export declare const CODIEDEV_INSTRUCTIONS_BODY = "## Codiedev \u2014 team artifact layer\n\nThis machine is connected to Codiedev. Teammates share specs, reviews,\ndecisions, and messages via a CLI on every dev's machine.\n\n**When the user asks to share, push, ping, check messages, or capture a\nthought, use the `codiedev` CLI via Bash:**\n\n| Intent | Command |\n|---|---|\n| \"push this spec\" / \"save this as a skill\" | `codiedev push <file.md>` |\n| \"pull X\" / \"grab the latest spec-X\" / \"what did a teammate push?\" | `codiedev pull <key>` |\n| \"delete X\" / \"remove that test push\" / \"rm spec-old\" | `codiedev delete <key>` (always confirm with the user first) |\n| \"ping a teammate about this\" / \"ask someone for their take\" / \"send them this file\" | `codiedev ping <name> \"<msg>\" [--with <key>] [--file <path>]` |\n| \"any messages?\" / \"check my inbox\" / \"what did a teammate say?\" | `codiedev inbox` |\n| \"read that reply\" / \"mark that ping read\" | `codiedev read <ping-id>` |\n| \"reply to that\" / \"tell them X\" (answering a message from `codiedev inbox`) | `codiedev reply <ping-id> \"<msg>\" [--file <path>]` (not a new ping: this threads it and marks theirs answered) |\n| \"note that X is a follow-up\" / \"remember X\" | `codiedev note \"<text>\"` |\n| \"share with a teammate\" / \"give someone access\" (no notification) | `codiedev share <key> <name> [--role read\\|edit]` |\n| \"send this to a teammate\" / \"ask someone to look at this\" | `codiedev send <key> <name> [\"<msg>\"]` |\n| \"find something about X\" / \"has anyone solved Y?\" | `codiedev search \"<query>\" [--limit N]` |\n| \"show my library\" / \"what artifacts exist?\" | `codiedev library [--scope mine\\|shared\\|all] [--kind doc\\|skill]` |\n| \"run my agent's test cases\" / \"check the dataset on model Y\" / \"run v2 of the dataset\" | `codiedev traces cases <agent> [--dataset <name> [--version <n>]] [--model <id>]` (writes cases + RUN_CASES.md + results.json; follow it, then `codiedev traces report <results.json>`) |\n| \"how are my agents doing?\" / \"what's failing this week?\" / \"show the booking agent's failed runs\" / \"why did run X fail?\" | `codiedev traces overview`; `codiedev traces runs <agent> [--failed] [--flag <issue>] [--days n]`; `codiedev traces run <run> --agent <name>` (add `--json` to read the data yourself) |\n| \"add a helpfulness 1\u20135 score\" / \"make a review queue for tone\" | `codiedev traces score-kinds add <name> --type number --min 1 --max 5`; `codiedev traces queue create <name> --scores <a,b>` |\n| \"score that run 4 for helpfulness\" / \"how is my agent scoring?\" | `codiedev traces score <run> <score> <value> [--agent <name>] [--comment <why>]`; `codiedev traces scores <agent>` |\n| \"put this week's failed runs in the review queue\" | `codiedev traces queue list`; `codiedev traces queue add <queue> --agent <name> [--failed] [--days n]` |\n| \"have a judge score 10% of my agent's runs\" / \"turn off automatic scoring\" | `codiedev traces judge <agent> --on --scores <a,b> --sample 10 [--budget 25]`; `--off`; no flags shows it |\n| \"import these test cases from a CSV\" / \"add an example to the dataset\" / \"save the dataset as a version\" | `codiedev traces import <agent> <file> --dataset <name>`; `codiedev traces add-example <agent> --dataset <name> --input \"\u2026\" [--expected \"\u2026\"]`; `codiedev traces save-version <dataset>`; `codiedev traces versions <dataset>` |\n| \"make a starter pack\" / \"add this to our pack\" / \"package these skills for my team\" | write a `<slug>.pack.md` (start from `codiedev pack export <slug> --manifest --out .` for an existing pack), then `codiedev pack apply <file> [--publish]` \u2014 see **Starter packs** below |\n| \"publish the pack\" / \"ship the pack to my team\" | `codiedev pack publish <slug> [--channel stable\\|beta\\|alpha]` |\n| \"what was the last eval on X?\" / \"file these eval results\" | `codiedev evals last <subject>` before starting a related eval; `codiedev evals report <run.json>` after each variant runs (scores only \u2014 `codiedev evals help` for the shape) |\n\n**Starter packs** (team managers and admins): a pack.md is frontmatter\n(`name:`, `slug:`, optional `description:`) then sections. Ask the user\nwhat to include, write the file, run `codiedev pack apply <file> --dry-run`\nto show them, then apply for real:\n\n```\n---\nname: \"Healthcare scan\"\nslug: \"healthcare-scan\"\n---\n\n# Healthcare scan\n\n## Skills\n\n- ./skills/healthcare-scan\n- lint.md @teammate@example.com\n\n## Files\n\n- runner <- ~/.claude/runner\n```\n\nUnder **Skills**, a local path (`./\u2026`, `~/\u2026` or `/\u2026`) to a skill folder\nor SKILL.md is pushed to the library and added, with the rest of its folder\nshipped as the skill's files; `<key> @<author email>` adds a teammate's\nlibrary skill. **Files** maps local folders to paths in the pack\n(`.` is the pack root). In skills, point at shipped files relative to the\nskill's folder or with `${CLAUDE_PLUGIN_ROOT}/\u2026`. Applying changes the\ndraft; `--publish` (or `codiedev pack publish`) sends it to the team.\n\n**Just push the file \u2014 we'll figure out where it goes.** Every artifact\nis classified into one of two kinds at upload time:\n\n- **skill** \u2014 the file has SKILL.md frontmatter (`name:` + `description:`\n inside a `---` block). Shows on the Skills page in the portal and is\n invokable as a slash command (`/<name>`).\n- **doc** \u2014 everything else. Lives in the library: list it with\n `codiedev library`, fetch it with `codiedev pull <key>`.\n\nDetection is content-based, not filename-based. The filename prefix\n(`spec-` / `decision-` / `proposal-` / `bugfix-` / `review-` /\n`note-`) is preserved as a *tag* you can filter by, but it never gates\nvisibility. A SKILL-frontmatter file named `note-foo.md` still becomes\na skill.\n\nThe `codiedev push` response always says where the artifact landed \u2014\nread it back to the user so they can confirm.\n\n**Resolving \"the spec we just worked on\":**\n- If a file was recently edited in this session matching the conventions\n above, push that file.\n- If content was drafted inline in the conversation, write it to a file\n first (e.g., `/tmp/spec-xxx.md`) then push.\n\n**Teammate names:** first name usually works (`codiedev ping <name> ...`).\nIf ambiguous, the CLI returns candidates \u2014 retry with the full email.\n\n**Search before pushing.** For any \"save this as \u2026\" request, run\n`codiedev search \"<query>\"` first. If prior art exists, pull it and\niterate rather than duplicating.\n\n**Sharing vs sending:** `codiedev share` is silent (access only, no\nnotification). `codiedev send` both grants access AND pings the\nrecipient. Use send when the user is actively looping someone in.\n\n**Errors:**\n- \"not connected\" \u2192 user needs to run `npx codiedev connect` with their\n API token from https://codiedev.com/portal/integrations/claude-code\n- \"ambiguous recipient\" \u2192 surface candidates to the user\n";
|
|
147
|
+
/** The full Codiedev instructions (team-skill context + command table), for
|
|
148
|
+
* harnesses Codiedev launches itself (Codie, Codie's pi) rather than a
|
|
149
|
+
* user-owned instructions file. */
|
|
150
|
+
export declare function codiedevInstructionsText(): string;
|
|
146
151
|
export declare function installClaudeCodeInstructions(): void;
|
|
147
152
|
export declare function installCodexInstructions(): void;
|
|
148
153
|
export declare function copilotInstructionsPath(): string;
|
package/dist/utils.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.DIRECT_UPLOAD_THRESHOLD_CHARS = exports.SWEEP_MIN_AGE_MS = exports.CAPTURE_THROTTLE_MS = exports.FINISH_ORPHAN_AGE_MS = exports.CLAIM_STALE_MS = exports.UPLOAD_TTL_MS = exports.MAX_UPLOAD_ATTEMPTS = exports.PI_EXTENSION_SUBCOMMANDS = exports.CONFIG_PATH = exports.codiedevStateDir = exports.piExtensionPath = exports.inspectPiExtension = void 0;
|
|
36
|
+
exports.DIRECT_UPLOAD_THRESHOLD_CHARS = exports.SWEEP_MIN_AGE_MS = exports.CAPTURE_THROTTLE_MS = exports.FINISH_ORPHAN_AGE_MS = exports.CLAIM_STALE_MS = exports.UPLOAD_TTL_MS = exports.MAX_UPLOAD_ATTEMPTS = exports.CODIEDEV_INSTRUCTIONS_BODY = exports.PI_EXTENSION_SUBCOMMANDS = exports.CONFIG_PATH = exports.codiedevStateDir = exports.piExtensionPath = exports.inspectPiExtension = void 0;
|
|
37
37
|
exports.readConfig = readConfig;
|
|
38
38
|
exports.writeConfig = writeConfig;
|
|
39
39
|
exports.writeConfigAtPath = writeConfigAtPath;
|
|
@@ -78,6 +78,7 @@ exports.ensureAllCodiedevHooksInstalled = ensureAllCodiedevHooksInstalled;
|
|
|
78
78
|
exports.hasDirectHookPath = hasDirectHookPath;
|
|
79
79
|
exports.migrateHooksToLauncher = migrateHooksToLauncher;
|
|
80
80
|
exports.ensureSessionStartHookInstalled = ensureSessionStartHookInstalled;
|
|
81
|
+
exports.codiedevInstructionsText = codiedevInstructionsText;
|
|
81
82
|
exports.installClaudeCodeInstructions = installClaudeCodeInstructions;
|
|
82
83
|
exports.installCodexInstructions = installCodexInstructions;
|
|
83
84
|
exports.copilotInstructionsPath = copilotInstructionsPath;
|
|
@@ -1660,7 +1661,7 @@ const CODEX_USER_INSTRUCTIONS_PATH = path.join((0, harnessDirs_1.codexHome)(), "
|
|
|
1660
1661
|
const CODEX_CONFIG_PATH = path.join((0, harnessDirs_1.codexHome)(), "config.toml");
|
|
1661
1662
|
const CODIEDEV_INSTRUCTIONS_BEGIN = "<!-- codiedev-cli:begin -->";
|
|
1662
1663
|
const CODIEDEV_INSTRUCTIONS_END = "<!-- codiedev-cli:end -->";
|
|
1663
|
-
|
|
1664
|
+
exports.CODIEDEV_INSTRUCTIONS_BODY = `## Codiedev — team artifact layer
|
|
1664
1665
|
|
|
1665
1666
|
This machine is connected to Codiedev. Teammates share specs, reviews,
|
|
1666
1667
|
decisions, and messages via a CLI on every dev's machine.
|
|
@@ -1689,8 +1690,41 @@ thought, use the \`codiedev\` CLI via Bash:**
|
|
|
1689
1690
|
| "put this week's failed runs in the review queue" | \`codiedev traces queue list\`; \`codiedev traces queue add <queue> --agent <name> [--failed] [--days n]\` |
|
|
1690
1691
|
| "have a judge score 10% of my agent's runs" / "turn off automatic scoring" | \`codiedev traces judge <agent> --on --scores <a,b> --sample 10 [--budget 25]\`; \`--off\`; no flags shows it |
|
|
1691
1692
|
| "import these test cases from a CSV" / "add an example to the dataset" / "save the dataset as a version" | \`codiedev traces import <agent> <file> --dataset <name>\`; \`codiedev traces add-example <agent> --dataset <name> --input "…" [--expected "…"]\`; \`codiedev traces save-version <dataset>\`; \`codiedev traces versions <dataset>\` |
|
|
1693
|
+
| "make a starter pack" / "add this to our pack" / "package these skills for my team" | write a \`<slug>.pack.md\` (start from \`codiedev pack export <slug> --manifest --out .\` for an existing pack), then \`codiedev pack apply <file> [--publish]\` — see **Starter packs** below |
|
|
1694
|
+
| "publish the pack" / "ship the pack to my team" | \`codiedev pack publish <slug> [--channel stable\\|beta\\|alpha]\` |
|
|
1692
1695
|
| "what was the last eval on X?" / "file these eval results" | \`codiedev evals last <subject>\` before starting a related eval; \`codiedev evals report <run.json>\` after each variant runs (scores only — \`codiedev evals help\` for the shape) |
|
|
1693
1696
|
|
|
1697
|
+
**Starter packs** (team managers and admins): a pack.md is frontmatter
|
|
1698
|
+
(\`name:\`, \`slug:\`, optional \`description:\`) then sections. Ask the user
|
|
1699
|
+
what to include, write the file, run \`codiedev pack apply <file> --dry-run\`
|
|
1700
|
+
to show them, then apply for real:
|
|
1701
|
+
|
|
1702
|
+
\`\`\`
|
|
1703
|
+
---
|
|
1704
|
+
name: "Healthcare scan"
|
|
1705
|
+
slug: "healthcare-scan"
|
|
1706
|
+
---
|
|
1707
|
+
|
|
1708
|
+
# Healthcare scan
|
|
1709
|
+
|
|
1710
|
+
## Skills
|
|
1711
|
+
|
|
1712
|
+
- ./skills/healthcare-scan
|
|
1713
|
+
- lint.md @teammate@example.com
|
|
1714
|
+
|
|
1715
|
+
## Files
|
|
1716
|
+
|
|
1717
|
+
- runner <- ~/.claude/runner
|
|
1718
|
+
\`\`\`
|
|
1719
|
+
|
|
1720
|
+
Under **Skills**, a local path (\`./…\`, \`~/…\` or \`/…\`) to a skill folder
|
|
1721
|
+
or SKILL.md is pushed to the library and added, with the rest of its folder
|
|
1722
|
+
shipped as the skill's files; \`<key> @<author email>\` adds a teammate's
|
|
1723
|
+
library skill. **Files** maps local folders to paths in the pack
|
|
1724
|
+
(\`.\` is the pack root). In skills, point at shipped files relative to the
|
|
1725
|
+
skill's folder or with \`\${CLAUDE_PLUGIN_ROOT}/…\`. Applying changes the
|
|
1726
|
+
draft; \`--publish\` (or \`codiedev pack publish\`) sends it to the team.
|
|
1727
|
+
|
|
1694
1728
|
**Just push the file — we'll figure out where it goes.** Every artifact
|
|
1695
1729
|
is classified into one of two kinds at upload time:
|
|
1696
1730
|
|
|
@@ -1731,13 +1765,19 @@ recipient. Use send when the user is actively looping someone in.
|
|
|
1731
1765
|
API token from https://codiedev.com/portal/integrations/claude-code
|
|
1732
1766
|
- "ambiguous recipient" → surface candidates to the user
|
|
1733
1767
|
`;
|
|
1768
|
+
/** The full Codiedev instructions (team-skill context + command table), for
|
|
1769
|
+
* harnesses Codiedev launches itself (Codie, Codie's pi) rather than a
|
|
1770
|
+
* user-owned instructions file. */
|
|
1771
|
+
function codiedevInstructionsText() {
|
|
1772
|
+
return `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${exports.CODIEDEV_INSTRUCTIONS_BODY}\n`;
|
|
1773
|
+
}
|
|
1734
1774
|
/**
|
|
1735
1775
|
* Write the codiedev agent-facing docs block to the user-level Claude
|
|
1736
1776
|
* instructions file so Claude Code picks up the commands in every session
|
|
1737
1777
|
* (no per-repo CLAUDE.md needed). Idempotent — replaces the existing block
|
|
1738
1778
|
* between its begin/end markers on re-run.
|
|
1739
1779
|
*/
|
|
1740
|
-
function writeInstructionsBlock(targetPath, body = CODIEDEV_INSTRUCTIONS_BODY) {
|
|
1780
|
+
function writeInstructionsBlock(targetPath, body = exports.CODIEDEV_INSTRUCTIONS_BODY) {
|
|
1741
1781
|
const dir = path.dirname(targetPath);
|
|
1742
1782
|
if (!fs.existsSync(dir)) {
|
|
1743
1783
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -1784,10 +1824,10 @@ function piInstructionsPath() {
|
|
|
1784
1824
|
/** pi has no session-start output channel, so team skill context rides in
|
|
1785
1825
|
* AGENTS.md the way it does for Copilot. */
|
|
1786
1826
|
function installPiInstructions() {
|
|
1787
|
-
writeInstructionsBlock(piInstructionsPath(), `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}`);
|
|
1827
|
+
writeInstructionsBlock(piInstructionsPath(), `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${exports.CODIEDEV_INSTRUCTIONS_BODY}`);
|
|
1788
1828
|
}
|
|
1789
1829
|
function installCopilotInstructions() {
|
|
1790
|
-
writeInstructionsBlock(copilotInstructionsPath(), `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}`);
|
|
1830
|
+
writeInstructionsBlock(copilotInstructionsPath(), `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${exports.CODIEDEV_INSTRUCTIONS_BODY}`);
|
|
1791
1831
|
}
|
|
1792
1832
|
// Cursor uses .mdc rule files with YAML frontmatter (description, alwaysApply,
|
|
1793
1833
|
// globs). `.cursorrules` is deprecated and ignored by Agent mode as of 2026.
|
|
@@ -1804,7 +1844,7 @@ function installCursorInstructions() {
|
|
|
1804
1844
|
const block = CURSOR_INSTRUCTIONS_FRONTMATTER +
|
|
1805
1845
|
CODIEDEV_INSTRUCTIONS_BEGIN +
|
|
1806
1846
|
"\n" +
|
|
1807
|
-
`${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}` +
|
|
1847
|
+
`${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${exports.CODIEDEV_INSTRUCTIONS_BODY}` +
|
|
1808
1848
|
"\n" +
|
|
1809
1849
|
CODIEDEV_INSTRUCTIONS_END +
|
|
1810
1850
|
"\n";
|
|
@@ -1822,7 +1862,7 @@ function installCursorInstructions() {
|
|
|
1822
1862
|
existing.slice(0, beginIdx) +
|
|
1823
1863
|
CODIEDEV_INSTRUCTIONS_BEGIN +
|
|
1824
1864
|
"\n" +
|
|
1825
|
-
`${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}` +
|
|
1865
|
+
`${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${exports.CODIEDEV_INSTRUCTIONS_BODY}` +
|
|
1826
1866
|
"\n" +
|
|
1827
1867
|
CODIEDEV_INSTRUCTIONS_END +
|
|
1828
1868
|
existing.slice(endIdx + CODIEDEV_INSTRUCTIONS_END.length);
|
|
@@ -1833,10 +1873,10 @@ function installCursorInstructions() {
|
|
|
1833
1873
|
fs.writeFileSync(CURSOR_RULES_PATH, next, "utf8");
|
|
1834
1874
|
}
|
|
1835
1875
|
function installedInstructionsTargets() {
|
|
1836
|
-
const withTeamContext = `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}`;
|
|
1876
|
+
const withTeamContext = `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${exports.CODIEDEV_INSTRUCTIONS_BODY}`;
|
|
1837
1877
|
return [
|
|
1838
|
-
{ path: CLAUDE_USER_INSTRUCTIONS_PATH, body: CODIEDEV_INSTRUCTIONS_BODY },
|
|
1839
|
-
{ path: CODEX_USER_INSTRUCTIONS_PATH, body: CODIEDEV_INSTRUCTIONS_BODY },
|
|
1878
|
+
{ path: CLAUDE_USER_INSTRUCTIONS_PATH, body: exports.CODIEDEV_INSTRUCTIONS_BODY },
|
|
1879
|
+
{ path: CODEX_USER_INSTRUCTIONS_PATH, body: exports.CODIEDEV_INSTRUCTIONS_BODY },
|
|
1840
1880
|
{ path: copilotInstructionsPath(), body: withTeamContext },
|
|
1841
1881
|
{ path: CURSOR_RULES_PATH, body: withTeamContext },
|
|
1842
1882
|
{ path: piInstructionsPath(), body: withTeamContext },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codiedev",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.87",
|
|
4
4
|
"description": "Connect Claude Code, Codex, Cursor, OpenCode, or VS Code Copilot to Codiedev for team session capture and artifact collaboration — and run the governed Codie harness",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codiedev": "dist/cli.js",
|