Merge branch 'feat/wf-fleet-t1-base' into feat/wf-fleet-mvp
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# T1 report: canonical ungated Claude base and lease overlay
|
||||
|
||||
## Changed
|
||||
|
||||
- Replaced `packages/mosaic/framework/runtime/claude/settings.json` with the canonical ungated base. It retains the model, QA hooks, plugins, command allowlist, permissions, and `mcpServers.sequential-thinking`.
|
||||
- Added `packages/mosaic/framework/runtime/claude/lease-overlay.json`. It contains only `hooks` and the six removed lease hook entries.
|
||||
- Added the byte-identical pre-split source fixture at `packages/mosaic/src/runtime/fixtures/claude-settings.gated.pre-split.json`.
|
||||
- Added `packages/mosaic/src/runtime/claude-settings-base.spec.ts`.
|
||||
|
||||
`framework-manifest.txt` already declares `runtime/**`, so the new overlay is framework-owned and shipped without a manifest change.
|
||||
|
||||
## Lease-hook enumeration
|
||||
|
||||
The actual template has six lease hook entries, matching fred's refined boundary:
|
||||
|
||||
1. `PreToolUse` matcher `.*`: `mutator-gate.py`
|
||||
2. `Stop`: one combined command containing `receipt-observer-client.py` then `promote-complete.py`
|
||||
3. `UserPromptSubmit` matcher `^/mosaic-promote$`: `promote-begin.py`
|
||||
4. `PreCompact`: `revoke-lease.py --reason pre-compact`
|
||||
5. `SessionStart` matcher `compact`: `revoke-lease.py --reason session-start-compact`
|
||||
6. `SessionStart` matcher `resume|clear`: `revoke-lease.py --reason session-start-rollover --bump-generation`
|
||||
|
||||
There is no delta from the refined six-entry enumeration. The Stop entry contains the receipt-observer and promote-complete commands together, rather than as two separate hook objects.
|
||||
|
||||
## Tests and checks
|
||||
|
||||
`pnpm install --frozen-lockfile` was run first because `node_modules` was absent. It completed successfully.
|
||||
|
||||
Red-first run before artifacts existed:
|
||||
|
||||
```text
|
||||
RUN v2.1.9 .../packages/mosaic
|
||||
❯ src/runtime/claude-settings-base.spec.ts (4 tests | 4 failed)
|
||||
× keeps every lease command out of the ungated base
|
||||
→ mutator-gate: expected true to be false
|
||||
× reconstructs the pre-split gated hooks while retaining the canonical MCP correction
|
||||
→ ENOENT: .../lease-overlay.json
|
||||
× ships sequential-thinking in the base
|
||||
→ expected undefined to deeply equal { 'sequential-thinking': ... }
|
||||
× limits the overlay to lease hook entries
|
||||
→ ENOENT: .../lease-overlay.json
|
||||
```
|
||||
|
||||
Final focused acceptance run:
|
||||
|
||||
```text
|
||||
RUN v2.1.9 .../packages/mosaic
|
||||
✓ src/runtime/claude-settings-base.spec.ts (4 tests) 19ms
|
||||
Test Files 1 passed (1)
|
||||
Tests 4 passed (4)
|
||||
```
|
||||
|
||||
`pnpm --filter @mosaicstack/mosaic lint` passed:
|
||||
|
||||
```text
|
||||
> @mosaicstack/[email protected] lint
|
||||
> eslint src
|
||||
```
|
||||
|
||||
`pnpm --filter @mosaicstack/mosaic typecheck` failed on pre-existing workspace resolution and unrelated package errors. The new spec no longer appears in the error list. Initial failures include missing `@mosaicstack/{brain,forge,log,macp,memory,queue,storage,quality-rails,db,config,prdy,types}` declarations, followed by existing `fleet-backlog.ts`, `gateway-doctor.ts`, and TUI implicit-`any` errors. Exit status: 2.
|
||||
|
||||
A focused legacy consumer run confirms an existing assumption that `settings.json` itself is gated:
|
||||
|
||||
```text
|
||||
pnpm --filter @mosaicstack/mosaic exec vitest run src/mutator-gate/mutator-gate.acceptance.spec.ts
|
||||
❯ src/mutator-gate/mutator-gate.acceptance.spec.ts (20 tests | 6 failed)
|
||||
× non-dangerous parser residual is denied by the global all-tools hook without a lease
|
||||
→ expected all-tools mutator-gate command in settings.json
|
||||
× Claude and Pi compaction observer wiring is complete and fail-closed
|
||||
→ expected PreCompact/SessionStart revoke-lease hooks in settings.json
|
||||
```
|
||||
|
||||
The other four failures in that focused run reported `STALE_GENERATION` where the test expected `MUTATOR_UNVERIFIED`, plus one successful-gate assertion. I did not redesign this legacy suite because the task explicitly says to report consumers that assume the base is gated.
|
||||
|
||||
## Consumers found
|
||||
|
||||
Direct `runtime/claude/settings.json` path consumers found by the required repository grep:
|
||||
|
||||
- `packages/mosaic/framework/tools/_scripts/mosaic-link-runtime-assets`: copies the base to `~/.claude/settings.json`.
|
||||
- `packages/mosaic/src/commands/install-ordering-guard.ts` and `.spec.ts`: documentation and behavior assume the source embeds enforcement hooks.
|
||||
- `packages/mosaic/framework/tools/_scripts/test-install-ordering-guard.sh`: comments and assertions expect `mutator-gate.py` and `receipt-observer-client.py` in the base.
|
||||
- `packages/mosaic/src/mutator-gate/mutator-gate.acceptance.spec.ts`: reads the base and asserts mutator, promotion, and compaction lease wiring.
|
||||
- `packages/mosaic/src/lease-broker/promotion_trigger_unittest.py`: reads the base and asserts promotion wiring.
|
||||
- `packages/mosaic/src/lease-broker/recovery_runtime_unittest.py`: reads the base.
|
||||
- `packages/mosaic/src/runtime/update-checker.ts` and `.spec.ts`: references the path in settings wiring/update checks.
|
||||
- Documentation-only references: `docs/compaction-refresh/probes/p6_constrained_recovery.py`, `docs/plans/agent-reflection-loop-PRD.md`, `docs/tasks/544-agent-reflection-loop.md`, and the framework QA documentation/scripts found by grep.
|
||||
|
||||
I did not change these consumers. The install/link and lease acceptance consumers must be taught to select and compose `lease-overlay.json` when a gated promotion seat is requested. That composition behavior is outside T1.
|
||||
|
||||
## Ambiguity handled
|
||||
|
||||
The exact pre-split template fixture has no `mcpServers` key (SHA-256 `44e74ea1e9d424fffa020ee666402662ac856b88bf6ae7f3b8931eed29dc75a4`). The task simultaneously requires a byte-for-byte pre-split fixture, `mcpServers.sequential-thinking` in the base, and `deep-merge(base, overlay) == original`. Those three conditions cannot all hold because a merge cannot remove the required MCP key.
|
||||
|
||||
The acceptance test preserves the exact fixture and asserts that the normalized merge equals the pre-split template plus the required canonical `mcpServers.sequential-thinking` correction. It verifies all original hook content is reconstructed and the base carries the required MCP. Production three-layer merge semantics remain W-F1 work.
|
||||
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"hooks": {
|
||||
"PreCompact": [
|
||||
{
|
||||
"matcher": ".*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason pre-compact"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "compact",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason session-start-compact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "resume|clear",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason session-start-rollover --bump-generation"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"UserPromptSubmit": [
|
||||
{
|
||||
"matcher": "^/mosaic-promote$",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/promote-begin.py",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": ".*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/mutator-gate.py --runtime claude --recovery-command ~/.config/mosaic/tools/lease-broker/recover-context.py",
|
||||
"timeout": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Stop": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/receipt-observer-client.py --runtime claude --latest-entry; observer_status=$?; python3 ~/.config/mosaic/tools/lease-broker/promote-complete.py; exit $observer_status",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,60 +1,7 @@
|
||||
{
|
||||
"model": "opus",
|
||||
"hooks": {
|
||||
"PreCompact": [
|
||||
{
|
||||
"matcher": ".*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason pre-compact"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "compact",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason session-start-compact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "resume|clear",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason session-start-rollover --bump-generation"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"UserPromptSubmit": [
|
||||
{
|
||||
"matcher": "^/mosaic-promote$",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/promote-begin.py",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": ".*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/mutator-gate.py --runtime claude --recovery-command ~/.config/mosaic/tools/lease-broker/recover-context.py",
|
||||
"timeout": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write|Edit|MultiEdit",
|
||||
"hooks": [
|
||||
@@ -91,11 +38,6 @@
|
||||
"Stop": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/receipt-observer-client.py --runtime claude --latest-entry; observer_status=$?; python3 ~/.config/mosaic/tools/lease-broker/promote-complete.py; exit $observer_status",
|
||||
"timeout": 15
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"command": "~/.config/mosaic/tools/qa/reflect-stop-hook.sh",
|
||||
@@ -315,5 +257,11 @@
|
||||
"cpan",
|
||||
"nohup"
|
||||
],
|
||||
"enableAllMcpTools": true
|
||||
"enableAllMcpTools": true,
|
||||
"mcpServers": {
|
||||
"sequential-thinking": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
type Json = null | boolean | number | string | Json[] | { [key: string]: Json };
|
||||
type JsonObject = { [key: string]: Json };
|
||||
|
||||
const frameworkRoot = fileURLToPath(new URL('../../framework/', import.meta.url));
|
||||
const basePath = `${frameworkRoot}runtime/claude/settings.json`;
|
||||
const overlayPath = `${frameworkRoot}runtime/claude/lease-overlay.json`;
|
||||
const gatedFixturePath = fileURLToPath(
|
||||
new URL('./fixtures/claude-settings.gated.pre-split.json', import.meta.url),
|
||||
);
|
||||
|
||||
function readJson(path: string): JsonObject {
|
||||
return JSON.parse(readFileSync(path, 'utf8')) as JsonObject;
|
||||
}
|
||||
|
||||
function isObject(value: unknown): value is JsonObject {
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
||||
}
|
||||
|
||||
// This fixture contract composes hook event arrays additively. It is deliberately
|
||||
// limited to verifying that the split is lossless; production launch merge
|
||||
// semantics remain owned by W-F1.
|
||||
function deepMerge(base: Json, overlay: Json): Json {
|
||||
if (Array.isArray(base) && Array.isArray(overlay)) {
|
||||
const merged = [...base];
|
||||
for (const entry of overlay) {
|
||||
if (!isObject(entry) || !Array.isArray(entry['hooks'])) {
|
||||
merged.push(entry);
|
||||
continue;
|
||||
}
|
||||
const matchingIndex = merged.findIndex(
|
||||
(candidate) =>
|
||||
isObject(candidate) &&
|
||||
Array.isArray(candidate['hooks']) &&
|
||||
candidate['matcher'] === entry['matcher'],
|
||||
);
|
||||
if (matchingIndex === -1) merged.push(entry);
|
||||
else merged[matchingIndex] = deepMerge(merged[matchingIndex]!, entry);
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
if (isObject(base) && isObject(overlay)) {
|
||||
const merged: JsonObject = { ...base };
|
||||
for (const [key, value] of Object.entries(overlay)) {
|
||||
merged[key] = key in merged ? deepMerge(merged[key]!, value) : value;
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
return overlay;
|
||||
}
|
||||
|
||||
function normalize(value: Json): Json {
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map(normalize)
|
||||
.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
||||
}
|
||||
if (isObject(value)) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(value)
|
||||
.sort(([left], [right]) => left.localeCompare(right))
|
||||
.map(([key, nested]) => [key, normalize(nested)]),
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function hookCommands(settings: JsonObject): string[] {
|
||||
const hooks = settings['hooks'];
|
||||
if (!isObject(hooks)) return [];
|
||||
|
||||
return Object.values(hooks).flatMap((event) => {
|
||||
if (!Array.isArray(event)) return [];
|
||||
return event.flatMap((entry) => {
|
||||
if (!isObject(entry) || !Array.isArray(entry['hooks'])) return [];
|
||||
return entry['hooks'].flatMap((hook) =>
|
||||
isObject(hook) && typeof hook['command'] === 'string' ? [hook['command']] : [],
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const sequentialThinking: JsonObject = {
|
||||
command: 'npx',
|
||||
args: ['-y', '@modelcontextprotocol/server-sequential-thinking'],
|
||||
};
|
||||
|
||||
describe('canonical Claude base and lease-promotion overlay', () => {
|
||||
it('keeps every lease command out of the ungated base', () => {
|
||||
const base = readJson(basePath);
|
||||
const commands = hookCommands(base);
|
||||
|
||||
for (const marker of ['mutator-gate', 'receipt-observer', 'promote-', 'revoke-lease']) {
|
||||
expect(
|
||||
commands.some((command) => command.includes(marker)),
|
||||
marker,
|
||||
).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it('reconstructs the pre-split gated hooks while retaining the canonical MCP correction', () => {
|
||||
const base = readJson(basePath);
|
||||
const overlay = readJson(overlayPath);
|
||||
const preSplit = readJson(gatedFixturePath);
|
||||
const expected: JsonObject = {
|
||||
...preSplit,
|
||||
mcpServers: { 'sequential-thinking': sequentialThinking },
|
||||
};
|
||||
|
||||
expect(normalize(deepMerge(base, overlay))).toEqual(normalize(expected));
|
||||
});
|
||||
|
||||
it('ships sequential-thinking in the base', () => {
|
||||
const base = readJson(basePath);
|
||||
expect(base['mcpServers']).toEqual({ 'sequential-thinking': sequentialThinking });
|
||||
});
|
||||
|
||||
it('limits the overlay to lease hook entries', () => {
|
||||
const overlay = readJson(overlayPath);
|
||||
expect(Object.keys(overlay)).toEqual(['hooks']);
|
||||
|
||||
const commands = hookCommands(overlay);
|
||||
expect(commands).toHaveLength(6);
|
||||
for (const command of commands) {
|
||||
expect(command).toMatch(/mutator-gate|receipt-observer|promote-|revoke-lease/);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,319 @@
|
||||
{
|
||||
"model": "opus",
|
||||
"hooks": {
|
||||
"PreCompact": [
|
||||
{
|
||||
"matcher": ".*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason pre-compact"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "compact",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason session-start-compact"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "resume|clear",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 \"$HOME/.config/mosaic/tools/lease-broker/revoke-lease.py\" --runtime claude --reason session-start-rollover --bump-generation"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"UserPromptSubmit": [
|
||||
{
|
||||
"matcher": "^/mosaic-promote$",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/promote-begin.py",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": ".*",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/mutator-gate.py --runtime claude --recovery-command ~/.config/mosaic/tools/lease-broker/recover-context.py",
|
||||
"timeout": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Write|Edit|MultiEdit",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "~/.config/mosaic/tools/qa/prevent-memory-write.sh",
|
||||
"timeout": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Edit|MultiEdit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "~/.config/mosaic/tools/qa/qa-hook-stdin.sh",
|
||||
"timeout": 60
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "Edit|MultiEdit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "~/.config/mosaic/tools/qa/typecheck-hook.sh",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Stop": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ~/.config/mosaic/tools/lease-broker/receipt-observer-client.py --runtime claude --latest-entry; observer_status=$?; python3 ~/.config/mosaic/tools/lease-broker/promote-complete.py; exit $observer_status",
|
||||
"timeout": 15
|
||||
},
|
||||
{
|
||||
"type": "command",
|
||||
"command": "~/.config/mosaic/tools/qa/reflect-stop-hook.sh",
|
||||
"timeout": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"enabledPlugins": {
|
||||
"frontend-design@claude-plugins-official": true,
|
||||
"feature-dev@claude-plugins-official": true,
|
||||
"code-review@claude-plugins-official": true,
|
||||
"pr-review-toolkit@claude-plugins-official": true
|
||||
},
|
||||
"skipDangerousModePermissionPrompt": true,
|
||||
"allowedCommands": [
|
||||
"npm",
|
||||
"npm install",
|
||||
"npm run",
|
||||
"npm test",
|
||||
"npm build",
|
||||
"npm start",
|
||||
"npm run dev",
|
||||
"npm run build",
|
||||
"npm run lint",
|
||||
"npm run typecheck",
|
||||
"npm run test:ci",
|
||||
"npm run test:e2e",
|
||||
"npm run test:unit",
|
||||
"npm run test:integration",
|
||||
"npm run test:cov",
|
||||
"npm run test:security",
|
||||
"npm run security:scan",
|
||||
"npm run security:audit",
|
||||
"npm run performance:benchmark",
|
||||
"npm run build:dev",
|
||||
"npm run build:prod",
|
||||
"npm run test",
|
||||
"npm run test:watch",
|
||||
"npm run migrate",
|
||||
"npm run migrate:rollback",
|
||||
"npm run db:seed",
|
||||
"npm run db:reset",
|
||||
"node",
|
||||
"yarn",
|
||||
"pnpm",
|
||||
"npx",
|
||||
"npx tsc",
|
||||
"npx eslint",
|
||||
"npx prettier",
|
||||
"npx jest",
|
||||
"npx vitest",
|
||||
"git",
|
||||
"git add",
|
||||
"git commit",
|
||||
"git push",
|
||||
"git pull",
|
||||
"git status",
|
||||
"git diff",
|
||||
"git log",
|
||||
"git branch",
|
||||
"git checkout",
|
||||
"git merge",
|
||||
"git init",
|
||||
"git remote",
|
||||
"git fetch",
|
||||
"git reset",
|
||||
"git rebase",
|
||||
"git stash",
|
||||
"git tag",
|
||||
"git show",
|
||||
"git config",
|
||||
"gh",
|
||||
"gh issue",
|
||||
"gh pr",
|
||||
"gh repo",
|
||||
"gh api",
|
||||
"docker",
|
||||
"docker build",
|
||||
"docker run",
|
||||
"docker ps",
|
||||
"docker logs",
|
||||
"docker exec",
|
||||
"docker stop",
|
||||
"docker start",
|
||||
"docker pull",
|
||||
"docker push",
|
||||
"docker-compose",
|
||||
"docker-compose up",
|
||||
"docker-compose down",
|
||||
"docker-compose build",
|
||||
"docker-compose logs",
|
||||
"docker-compose ps",
|
||||
"docker-compose exec",
|
||||
"kubectl",
|
||||
"kubectl get",
|
||||
"kubectl describe",
|
||||
"kubectl logs",
|
||||
"kubectl apply",
|
||||
"kubectl delete",
|
||||
"kubectl port-forward",
|
||||
"mkdir",
|
||||
"touch",
|
||||
"chmod",
|
||||
"chown",
|
||||
"ls",
|
||||
"cd",
|
||||
"pwd",
|
||||
"cp",
|
||||
"mv",
|
||||
"rm",
|
||||
"cat",
|
||||
"echo",
|
||||
"head",
|
||||
"tail",
|
||||
"grep",
|
||||
"grep -E",
|
||||
"grep -r",
|
||||
"find",
|
||||
"find -name",
|
||||
"find -type",
|
||||
"find -path",
|
||||
"find -exec",
|
||||
"find . -type f",
|
||||
"find . -type d",
|
||||
"wc",
|
||||
"sort",
|
||||
"uniq",
|
||||
"curl",
|
||||
"wget",
|
||||
"ping",
|
||||
"netstat",
|
||||
"ss",
|
||||
"lsof",
|
||||
"psql",
|
||||
"pg_dump",
|
||||
"pg_restore",
|
||||
"sqlite3",
|
||||
"jest",
|
||||
"vitest",
|
||||
"playwright",
|
||||
"cypress",
|
||||
"artillery",
|
||||
"lighthouse",
|
||||
"tsc",
|
||||
"eslint",
|
||||
"prettier",
|
||||
"snyk",
|
||||
"semgrep",
|
||||
"tar",
|
||||
"gzip",
|
||||
"unzip",
|
||||
"zip",
|
||||
"which",
|
||||
"whoami",
|
||||
"id",
|
||||
"env",
|
||||
"export",
|
||||
"source",
|
||||
"sleep",
|
||||
"date",
|
||||
"uptime",
|
||||
"df",
|
||||
"du",
|
||||
"free",
|
||||
"top",
|
||||
"htop",
|
||||
"ps",
|
||||
"tree",
|
||||
"jq",
|
||||
"sed",
|
||||
"awk",
|
||||
"xargs",
|
||||
"tee",
|
||||
"test",
|
||||
"true",
|
||||
"false",
|
||||
"basename",
|
||||
"dirname",
|
||||
"realpath",
|
||||
"readlink",
|
||||
"stat",
|
||||
"file",
|
||||
"make",
|
||||
"cmake",
|
||||
"gcc",
|
||||
"g++",
|
||||
"clang",
|
||||
"python",
|
||||
"python3",
|
||||
"pip",
|
||||
"pip3",
|
||||
"pip install",
|
||||
"poetry",
|
||||
"pipenv",
|
||||
"go",
|
||||
"go build",
|
||||
"go test",
|
||||
"go run",
|
||||
"go mod",
|
||||
"cargo",
|
||||
"rustc",
|
||||
"ruby",
|
||||
"gem",
|
||||
"bundle",
|
||||
"rake",
|
||||
"java",
|
||||
"javac",
|
||||
"mvn",
|
||||
"gradle",
|
||||
"dotnet",
|
||||
"msbuild",
|
||||
"php",
|
||||
"composer",
|
||||
"perl",
|
||||
"cpan",
|
||||
"nohup"
|
||||
],
|
||||
"enableAllMcpTools": true
|
||||
}
|
||||
Reference in New Issue
Block a user