@cairnkeep/cli 2.25.0 → 2.26.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/CHANGELOG.md +41 -0
- package/docs/README.md +2 -0
- package/docs/harness-compatibility.md +5 -2
- package/docs/learning/CURRICULUM-MAP.md +3 -3
- package/docs/learning/FEATURE-GUIDE.md +7 -1
- package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
- package/docs/learning/lessons/L01-safe-trial.md +3 -3
- package/docs/learning/lessons/L02-installation.md +2 -2
- package/docs/learning/lessons/L03-first-project.md +1 -1
- package/docs/learning/lessons/L19-validated-skill-improvement.md +1 -1
- package/docs/learning/lessons/L20-mcp-tool-profiles.md +1 -1
- package/docs/learning/lessons/L21-context-packs.md +1 -1
- package/docs/learning/lessons/L22-native-windows.md +2 -2
- package/docs/learning/lessons/L23-guided-setup.md +1 -1
- package/docs/learning/lessons/L24-okf-exchange.md +1 -1
- package/docs/learning/lessons/L25-playbooks.md +1 -1
- package/docs/learning/lessons/L26-context-intelligence.md +1 -1
- package/docs/learning/lessons/L27-ecosystem-evidence.md +1 -1
- package/docs/learning/lessons/L28-security-assurance.md +5 -1
- package/docs/learning/lessons/L29-team-continuity.md +33 -1
- package/docs/learning/tracks/operator.md +2 -0
- package/docs/learning/video-scripts/V28-security-assurance.md +4 -0
- package/docs/learning/video-scripts/V29-team-continuity.md +19 -1
- package/docs/operating.md +6 -0
- package/docs/privacy-and-data-flow.md +21 -1
- package/docs/provider-data-flow-review.md +48 -0
- package/docs/security-assurance.md +11 -0
- package/docs/storage.md +14 -0
- package/docs/team-onboarding.md +226 -0
- package/docs/team-pilot.md +2 -0
- package/docs/team.md +11 -0
- package/examples/eval/bundled-fake.json +1 -1
- package/mcp-memory-server/dist/capability-config.js +12 -1
- package/mcp-memory-server/dist/team-cli.js +15 -5
- package/mcp-memory-server/dist/team-client.js +71 -0
- package/mcp-memory-server/dist/team-mcp.js +8 -1
- package/mcp-memory-server/dist/team-store.js +8 -2
- package/mcp-memory-server/package.json +2 -2
- package/package.json +1 -1
- package/scripts/cairn-cli.mjs +6 -1
- package/scripts/completion.sh +11 -3
- package/scripts/lib/team-retention.mjs +1 -1
- package/scripts/team-connect.mjs +366 -0
- package/scripts/test-ci-sharding.sh +1 -1
- package/scripts/test-codeql-cohort.mjs +35 -0
- package/scripts/test-completion.sh +4 -1
- package/scripts/test-package-install.sh +1 -0
- package/scripts/test-phase18-capability-lifecycle.sh +2 -2
- package/scripts/test-security-baseline.sh +1 -0
- package/scripts/test-team-docs.sh +11 -2
- package/scripts/test-team-installed.mjs +51 -0
- package/scripts/test-team-pilot.mjs +43 -1
- package/scripts/verify-security-baseline.mjs +20 -0
- package/scripts/windows-platform.mjs +1 -1
|
@@ -33,6 +33,25 @@ function walk(value, visit, path = "workflow") {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export function validateCodeqlCohort(workflows, dependabot) {
|
|
37
|
+
const references = [];
|
|
38
|
+
for (const workflow of workflows) walk(workflow, (key, value) => {
|
|
39
|
+
if (key === "uses" && typeof value === "string" && value.startsWith("github/codeql-action/")) {
|
|
40
|
+
assert.match(value, /^github\/codeql-action\/[^@\s]+@[a-f0-9]{40}$/, "CodeQL actions must be pinned to a full commit");
|
|
41
|
+
references.push(value);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
assert.ok(references.length > 0, "CodeQL cohort is missing");
|
|
45
|
+
assert.equal(new Set(references.map(value => value.split("@")[1])).size, 1, "CodeQL cohort must use the same commit across workflows");
|
|
46
|
+
for (const action of ["init", "analyze", "upload-sarif"]) {
|
|
47
|
+
assert.ok(references.some(value => value.startsWith(`github/codeql-action/${action}@`)), `CodeQL cohort is missing ${action}`);
|
|
48
|
+
}
|
|
49
|
+
const updates = dependabot?.updates?.filter(update => update["package-ecosystem"] === "github-actions" && update.directory === "/") ?? [];
|
|
50
|
+
assert.equal(updates.length, 1, "CodeQL cohort requires one root GitHub Actions update group");
|
|
51
|
+
const group = updates[0].groups?.["codeql-action"];
|
|
52
|
+
assert.deepEqual(group, { patterns: ["github/codeql-action/*"] }, "CodeQL dependency group must cover the entire cohort without exclusions or update-type restrictions");
|
|
53
|
+
}
|
|
54
|
+
|
|
36
55
|
function validateWorkflow(name, workflow) {
|
|
37
56
|
assert.ok(workflow && typeof workflow === "object" && !Array.isArray(workflow), `${name} is not a workflow mapping`);
|
|
38
57
|
assert.ok(workflow.permissions && typeof workflow.permissions === "object" && !Array.isArray(workflow.permissions), `${name} must have an explicit workflow permission mapping`);
|
|
@@ -123,6 +142,7 @@ for (const [index, [fixture, expected]] of maliciousFixtures.entries()) {
|
|
|
123
142
|
|
|
124
143
|
for (const { name, workflow } of sources) validateWorkflow(name, workflow);
|
|
125
144
|
validatePublicationPermissions(publish);
|
|
145
|
+
validateCodeqlCohort(sources.map(source => source.workflow), parse(readFileSync(join(root, ".github", "dependabot.yml"), "utf8")));
|
|
126
146
|
|
|
127
147
|
const security = sources.find(({ name }) => name === "security.yml")?.text ?? "";
|
|
128
148
|
assert.match(security, /github\/codeql-action\/init@[a-f0-9]{40}/);
|
|
@@ -779,7 +779,7 @@ export function powershellCompletion() {
|
|
|
779
779
|
$pack = 'init','lock','validate','install','import-okf','validate-okf','export-okf','list','show','remove','enable','disable','update','skills','approve-skill','revoke-skill','doctor','--repair','--project','--project-id','--json'
|
|
780
780
|
$proposals = 'create','list','show','apply','doctor','--session','--scope','--model','--category','--project','--json'
|
|
781
781
|
$security = 'doctor','--project','--json'
|
|
782
|
-
$team = 'init','project','member','credential','create','set','remove','issue','revoke','serve','mcp','list','read','search','history','propose','proposals','proposal-show','review','audit','doctor','backup','restore','memory-delete','--organization','--data','--project','--roles','--class','--expires-at','--output','--input','--confirm','--port','--key','--query','--proposal','--decision','--revision','--project-root'
|
|
782
|
+
$team = 'connect','disconnect','init','project','member','credential','create','set','remove','issue','revoke','serve','mcp','list','read','search','history','propose','proposals','proposal-show','review','audit','doctor','backup','restore','memory-delete','--organization','--data','--project','--roles','--class','--expires-at','--output','--input','--confirm','--port','--key','--query','--proposal','--decision','--revision','--project-root','--connection','--client','--url','--token-file','--harness','--access','--apply','--yes'
|
|
783
783
|
$evaluation = 'validate','run','ablate','report','prune','delete','protocol','--task-set','--adapter','--output','--repetitions','--seed','--yes','--json','--disable','--experiment','--older-than-days','--dry-run','--trajectory','--codex-jsonl','--capture-authorized'
|
|
784
784
|
$candidates = if ($commandAst.ToString() -match '^\\s*cairn\\s+setup(?:\\s|$)') { $setup } elseif ($commandAst.ToString() -match '^\\s*cairn\\s+team(?:\\s|$)') { $team } elseif ($commandAst.ToString() -match '^\\s*cairn\\s+playbook(?:\\s|$)') { $playbook } elseif ($commandAst.ToString() -match '^\\s*cairn\\s+pack(?:\\s|$)') { $pack } elseif ($commandAst.ToString() -match '^\\s*cairn\\s+proposals(?:\\s|$)') { $proposals } elseif ($commandAst.ToString() -match '^\\s*cairn\\s+security(?:\\s|$)') { $security } elseif ($commandAst.ToString() -match '^\\s*cairn\\s+eval(?:\\s|$)') { $evaluation } else { $commands }
|
|
785
785
|
$candidates | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|