@aiwg/cli 2026.9.2 → 2026.9.4
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/README.md +21 -0
- package/agentic/code/providers/antigravity/provider-contract.v1.json +121 -0
- package/agentic/code/providers/capability-matrix.yaml +87 -1
- package/agentic/code/providers/model-capabilities.v1.json +31 -0
- package/agentic/code/providers/model-catalog.v1.json +29 -0
- package/agentic/code/providers/omp/README.md +58 -0
- package/agentic/code/providers/omp/aiwg-bridge.ts +52 -0
- package/dist/src/agents/agent-deployer.js +18 -0
- package/dist/src/agents/agent-packager.js +25 -0
- package/dist/src/artifacts/backends/sqlite-backend.js +18 -10
- package/dist/src/artifacts/query-engine.js +30 -0
- package/dist/src/cli/agent-spawn.js +13 -2
- package/dist/src/cli/handlers/help.js +3 -1
- package/dist/src/cli/handlers/init.js +2 -0
- package/dist/src/cli/handlers/models.js +1 -1
- package/dist/src/cli/handlers/runtime-info.js +8 -1
- package/dist/src/cli/handlers/session.js +5 -4
- package/dist/src/cli/handlers/sessions.js +26 -9
- package/dist/src/cli/handlers/setup.js +9 -2
- package/dist/src/cli/handlers/steward.js +13 -2
- package/dist/src/cli/handlers/subcommands.js +11 -0
- package/dist/src/cli/handlers/team.js +68 -7
- package/dist/src/cli/handlers/use.js +158 -9
- package/dist/src/cli/scope-resolver.js +7 -0
- package/dist/src/config/aiwg-config.js +1 -0
- package/dist/src/dataset/fortemi-live-qualification.d.ts +53 -0
- package/dist/src/dataset/fortemi-live-qualification.js +297 -0
- package/dist/src/dataset/index.d.ts +1 -0
- package/dist/src/dataset/index.js +1 -0
- package/dist/src/mcp/cli.mjs +30 -1
- package/dist/src/mcp/omp-config.mjs +128 -0
- package/dist/src/mcp/registry.js +45 -5
- package/dist/src/mcp/registry.mjs +29 -6
- package/dist/src/models/model-capabilities.v1.json +31 -0
- package/dist/src/models/model-catalog.v1.json +29 -0
- package/dist/src/models/model-discovery.js +46 -5
- package/dist/src/models/provider-policy.js +5 -3
- package/dist/src/plugin/skill-command-translator.js +2 -0
- package/dist/src/providers/capability-matrix.yaml +87 -1
- package/dist/src/providers/omp-agent.mjs +40 -0
- package/dist/src/providers/omp-diagnostics.mjs +15 -0
- package/dist/src/providers/omp-paths.mjs +38 -0
- package/dist/src/providers/provider-definitions.js +83 -0
- package/dist/src/providers/provider-definitions.mjs +25 -1
- package/dist/src/providers/provider-inventory.js +2 -0
- package/dist/src/sessions/adapters/omp.js +203 -0
- package/dist/src/sessions/batch-import.js +7 -0
- package/dist/src/sessions/contracts.js +1 -1
- package/dist/src/sessions/importer.js +4 -3
- package/dist/src/sessions/index.js +1 -0
- package/dist/src/sessions/readers.js +4 -3
- package/dist/src/sessions/workspace-discovery.js +12 -2
- package/dist/src/skills/deployer.js +21 -1
- package/dist/src/smiths/agentsmith/generator.js +1 -0
- package/dist/src/smiths/context-pipeline/parallelism-section.js +2 -0
- package/dist/src/smiths/context-pipeline/provider-policy.js +2 -2
- package/dist/src/smiths/context-pipeline/workspace-context.js +2 -2
- package/dist/src/storage/backends/fortemi.js +142 -17
- package/dist/src/storage/fortemi-qualification-receipt.js +206 -0
- package/dist/src/storage/fortemi-qualification.js +67 -6
- package/dist/src/storage/index.js +1 -0
- package/package.json +2 -1
- package/schemas/dataset/fortemi-live-qualification-receipt.v1.schema.json +132 -0
- package/tools/agents/deploy-agents.mjs +6 -3
- package/tools/agents/providers/antigravity.mjs +147 -0
- package/tools/agents/providers/omp.d.mts +4 -0
- package/tools/agents/providers/omp.mjs +256 -0
- package/tools/providers/antigravity-transport.mjs +124 -0
package/README.md
CHANGED
|
@@ -961,6 +961,27 @@ If both `aiwg` and `@aiwg/cli` were installed into the same prefix, the most
|
|
|
961
961
|
recent install owns the shared executable link. Remove both, then install the
|
|
962
962
|
distribution you intend to use.
|
|
963
963
|
|
|
964
|
+
### Bundled setup requires the full package
|
|
965
|
+
|
|
966
|
+
`aiwg use all` and named framework setup such as `aiwg use sdlc` need the
|
|
967
|
+
framework and addon sources included in `aiwg`. The lightweight `@aiwg/cli`
|
|
968
|
+
package supports signed web lookup and external project-local bundle deployment;
|
|
969
|
+
web lookup does not download a complete source tree for bundled setup.
|
|
970
|
+
|
|
971
|
+
If setup reports that the full package is required, replace the lightweight
|
|
972
|
+
global installation and rerun setup with your provider:
|
|
973
|
+
|
|
974
|
+
```bash
|
|
975
|
+
npm uninstall -g @aiwg/cli
|
|
976
|
+
npm install -g aiwg
|
|
977
|
+
aiwg use all --provider pi
|
|
978
|
+
```
|
|
979
|
+
|
|
980
|
+
Older CLI versions can instead report `ENOENT` while scanning
|
|
981
|
+
`@aiwg/cli/agentic/code/addons`. The same recovery applies. Existing project
|
|
982
|
+
files are retained; the prerequisite check now stops before deployment or
|
|
983
|
+
project initialization, including in dry-run mode.
|
|
984
|
+
|
|
964
985
|
## Migrating Between Distributions
|
|
965
986
|
|
|
966
987
|
From full AIWG to the lightweight package:
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"contractVersion": "1.0.0",
|
|
4
|
+
"provider": "antigravity",
|
|
5
|
+
"aliases": ["agy"],
|
|
6
|
+
"displayName": "Google Antigravity CLI",
|
|
7
|
+
"status": "experimental",
|
|
8
|
+
"qualifiedCli": {
|
|
9
|
+
"executable": "agy",
|
|
10
|
+
"version": "1.1.26",
|
|
11
|
+
"platform": "linux-x64",
|
|
12
|
+
"observedOn": "2026-09-04",
|
|
13
|
+
"authenticatedExecution": false
|
|
14
|
+
},
|
|
15
|
+
"evidence": [
|
|
16
|
+
{
|
|
17
|
+
"id": "official-transition",
|
|
18
|
+
"url": "https://developers.googleblog.com/an-important-update-transitioning-gemini-cli-to-antigravity-cli/",
|
|
19
|
+
"retrieved": "2026-09-04",
|
|
20
|
+
"confidence": "high"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "official-install",
|
|
24
|
+
"url": "https://antigravity.google/docs/cli/install/",
|
|
25
|
+
"retrieved": "2026-09-04",
|
|
26
|
+
"confidence": "high"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "official-headless",
|
|
30
|
+
"url": "https://antigravity.google/docs/cli/headless/",
|
|
31
|
+
"retrieved": "2026-09-04",
|
|
32
|
+
"confidence": "high"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "official-mcp",
|
|
36
|
+
"url": "https://antigravity.google/docs/cli/mcp/",
|
|
37
|
+
"retrieved": "2026-09-04",
|
|
38
|
+
"confidence": "high"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "official-skills",
|
|
42
|
+
"url": "https://antigravity.google/docs/cli/plugins/",
|
|
43
|
+
"retrieved": "2026-09-04",
|
|
44
|
+
"confidence": "medium",
|
|
45
|
+
"notes": "Official pages disagree about the global skills directory and flat versus nested project layouts."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "official-subagents",
|
|
49
|
+
"url": "https://antigravity.google/docs/cli/subagents/",
|
|
50
|
+
"retrieved": "2026-09-04",
|
|
51
|
+
"confidence": "high"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "local-cli-help",
|
|
55
|
+
"path": "test/fixtures/providers/antigravity-conformance/help-1.1.26.json",
|
|
56
|
+
"retrieved": "2026-09-04",
|
|
57
|
+
"confidence": "high",
|
|
58
|
+
"sanitized": true
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"surfaces": {
|
|
62
|
+
"selection": { "classification": "native", "canonical": "antigravity", "aliases": ["agy"] },
|
|
63
|
+
"context": {
|
|
64
|
+
"classification": "native",
|
|
65
|
+
"projectFiles": ["AGENTS.md", "GEMINI.md"],
|
|
66
|
+
"precedence": "provider-defined; no undocumented include syntax assumed"
|
|
67
|
+
},
|
|
68
|
+
"workspaceSkills": {
|
|
69
|
+
"classification": "native",
|
|
70
|
+
"path": ".agents/skills",
|
|
71
|
+
"layout": "nested-skill-md",
|
|
72
|
+
"notes": "AIWG deploys directories containing SKILL.md and preserves unrelated children."
|
|
73
|
+
},
|
|
74
|
+
"globalSkills": {
|
|
75
|
+
"classification": "unknown",
|
|
76
|
+
"enabled": false,
|
|
77
|
+
"candidates": ["~/.gemini/antigravity-cli/skills", "~/.gemini/config/skills"],
|
|
78
|
+
"reason": "Conflicting official documentation; deferred pending a safe version-pinned probe."
|
|
79
|
+
},
|
|
80
|
+
"customAgents": {
|
|
81
|
+
"classification": "native",
|
|
82
|
+
"projectPaths": [".agents/agents/<name>.md", ".agents/agents/<name>/agent.md"],
|
|
83
|
+
"selectedLayout": "flat-markdown",
|
|
84
|
+
"projection": "degraded",
|
|
85
|
+
"reason": "Only AIWG tool names with documented Antigravity equivalents are projected; provider-specific model policy remains runtime-scoped."
|
|
86
|
+
},
|
|
87
|
+
"mcp": {
|
|
88
|
+
"classification": "native",
|
|
89
|
+
"projectPath": ".agents/mcp_config.json",
|
|
90
|
+
"userPath": "~/.gemini/config/mcp_config.json",
|
|
91
|
+
"serversKey": "mcpServers",
|
|
92
|
+
"remoteUrlKey": "serverUrl",
|
|
93
|
+
"merge": "preserve unrelated top-level keys and operator-owned server names"
|
|
94
|
+
},
|
|
95
|
+
"headless": {
|
|
96
|
+
"classification": "native",
|
|
97
|
+
"baseArgs": ["-p"],
|
|
98
|
+
"jsonArgs": ["--output-format", "json"],
|
|
99
|
+
"streamArgs": ["--output-format", "stream-json"],
|
|
100
|
+
"interactiveStreamArgs": ["--input-format", "stream-json", "--output-format", "stream-json"],
|
|
101
|
+
"continueFlags": ["--continue", "--conversation"],
|
|
102
|
+
"dangerousFlag": "--dangerously-skip-permissions",
|
|
103
|
+
"defaultPermissionMode": "request-review",
|
|
104
|
+
"stdout": "protocol",
|
|
105
|
+
"stderr": "diagnostics"
|
|
106
|
+
},
|
|
107
|
+
"teams": { "classification": "emulated", "adapter": "aiwg-mc" },
|
|
108
|
+
"cron": { "classification": "external", "adapter": "operator-owned scheduler invoking the bounded headless adapter" },
|
|
109
|
+
"tasks": { "classification": "emulated", "adapter": "aiwg-mc" },
|
|
110
|
+
"behaviors": { "classification": "unsupported" },
|
|
111
|
+
"missionControl": { "classification": "emulated", "adapter": "aiwg-mc" },
|
|
112
|
+
"daemon": { "classification": "unsupported" },
|
|
113
|
+
"plugins": { "classification": "unknown", "enabled": false }
|
|
114
|
+
},
|
|
115
|
+
"safety": {
|
|
116
|
+
"normalCi": "offline-only",
|
|
117
|
+
"readsUserConfiguration": false,
|
|
118
|
+
"writesAuthOrPermissionSettings": false,
|
|
119
|
+
"liveSmoke": "opt-in-only"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -361,7 +361,7 @@ providers:
|
|
|
361
361
|
|
|
362
362
|
hermes:
|
|
363
363
|
display_name: Hermes
|
|
364
|
-
status:
|
|
364
|
+
status: stable
|
|
365
365
|
daemon_tier: unsupported
|
|
366
366
|
daemon_pty_adapter: false
|
|
367
367
|
artifact_paths:
|
|
@@ -470,6 +470,51 @@ providers:
|
|
|
470
470
|
deploy_target: mixed
|
|
471
471
|
aggregated_output: true
|
|
472
472
|
|
|
473
|
+
antigravity:
|
|
474
|
+
display_name: Google Antigravity CLI
|
|
475
|
+
aliases:
|
|
476
|
+
- agy
|
|
477
|
+
status: experimental
|
|
478
|
+
executable: agy
|
|
479
|
+
qualified_version: 1.1.26
|
|
480
|
+
qualification_evidence: agentic/code/providers/antigravity/provider-contract.v1.json
|
|
481
|
+
daemon_tier: unsupported
|
|
482
|
+
daemon_pty_adapter: false
|
|
483
|
+
artifact_paths:
|
|
484
|
+
agents: .agents/agents/
|
|
485
|
+
commands: "(not deployed; no qualified native command surface)"
|
|
486
|
+
skills: .agents/skills/
|
|
487
|
+
rules: AGENTS.md
|
|
488
|
+
behaviors: "(not supported)"
|
|
489
|
+
mcp_project: .agents/mcp_config.json
|
|
490
|
+
mcp_user: "~/.gemini/config/mcp_config.json"
|
|
491
|
+
native_features:
|
|
492
|
+
cron: false
|
|
493
|
+
agent_teams: false
|
|
494
|
+
tasks: false
|
|
495
|
+
mcp: true
|
|
496
|
+
behaviors: false
|
|
497
|
+
mission_control: false
|
|
498
|
+
daemon: false
|
|
499
|
+
emulation:
|
|
500
|
+
cron: external-trigger
|
|
501
|
+
agent_teams: aiwg-mc
|
|
502
|
+
tasks: aiwg-mc
|
|
503
|
+
mcp: native
|
|
504
|
+
behaviors: null
|
|
505
|
+
mission_control: aiwg-mc
|
|
506
|
+
daemon: null
|
|
507
|
+
hook_wiring:
|
|
508
|
+
at_link_support: false
|
|
509
|
+
fallback: full-inject
|
|
510
|
+
context_file: AGENTS.md
|
|
511
|
+
interaction:
|
|
512
|
+
structured_questions: none
|
|
513
|
+
fallback: markdown
|
|
514
|
+
notes: No stable structured-question tool contract was qualified for CLI 1.1.26.
|
|
515
|
+
deploy_target: project
|
|
516
|
+
aggregated_output: false
|
|
517
|
+
|
|
473
518
|
pi:
|
|
474
519
|
display_name: Pi Coding Agent
|
|
475
520
|
aliases:
|
|
@@ -511,6 +556,47 @@ providers:
|
|
|
511
556
|
deploy_target: project
|
|
512
557
|
aggregated_output: false
|
|
513
558
|
|
|
559
|
+
omp:
|
|
560
|
+
display_name: Oh My Pi
|
|
561
|
+
aliases:
|
|
562
|
+
- oh-my-pi
|
|
563
|
+
status: experimental
|
|
564
|
+
daemon_tier: unsupported
|
|
565
|
+
daemon_pty_adapter: false
|
|
566
|
+
artifact_paths:
|
|
567
|
+
agents: .omp/agents/
|
|
568
|
+
commands: .omp/prompts/
|
|
569
|
+
skills: .agents/skills/
|
|
570
|
+
skills_cross_agent: .agents/skills/
|
|
571
|
+
rules: .omp/rules/
|
|
572
|
+
behaviors: .omp/extensions/
|
|
573
|
+
native_features:
|
|
574
|
+
cron: false
|
|
575
|
+
agent_teams: true
|
|
576
|
+
tasks: true
|
|
577
|
+
mcp: true
|
|
578
|
+
behaviors: true
|
|
579
|
+
mission_control: false
|
|
580
|
+
daemon: false
|
|
581
|
+
emulation:
|
|
582
|
+
cron: external-trigger
|
|
583
|
+
agent_teams: null
|
|
584
|
+
tasks: null
|
|
585
|
+
mcp: null
|
|
586
|
+
behaviors: null
|
|
587
|
+
mission_control: aiwg-mc
|
|
588
|
+
daemon: null
|
|
589
|
+
hook_wiring:
|
|
590
|
+
at_link_support: true
|
|
591
|
+
fallback: full-inject
|
|
592
|
+
context_file: .omp/AGENTS.md
|
|
593
|
+
interaction:
|
|
594
|
+
structured_questions: none
|
|
595
|
+
fallback: markdown
|
|
596
|
+
notes: OMP integration uses Markdown questions; native UI questions require an interactive runtime.
|
|
597
|
+
deploy_target: project
|
|
598
|
+
aggregated_output: false
|
|
599
|
+
|
|
514
600
|
# Feature definitions — documents what each feature key means and
|
|
515
601
|
# what emulation strategies are available when native support is absent.
|
|
516
602
|
features:
|
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"verifiedAt": "2026-07-20",
|
|
5
5
|
"providers": {
|
|
6
|
+
"antigravity": {
|
|
7
|
+
"agent": "native", "skill": "native", "globalChild": "inherited",
|
|
8
|
+
"identifierSyntax": "model identifier accepted by Antigravity CLI 1.1.26 --model",
|
|
9
|
+
"effortValues": ["low", "medium", "high"],
|
|
10
|
+
"inheritance": "Omitted model and effort inherit the invoking Antigravity session",
|
|
11
|
+
"invalidPinFallback": "Provider validation/error; never assume fallback",
|
|
12
|
+
"configTarget": "agy launch arguments; custom-agent model tiers are not projected from generic AIWG model ids",
|
|
13
|
+
"artifactFormat": "YAML frontmatter plus Markdown; runtime --model and --effort flags",
|
|
14
|
+
"verification": "Pinned offline contract; authenticated model selection was not executed",
|
|
15
|
+
"sourceUrl": "https://antigravity.google/docs/cli/subagents/", "verifiedAt": "2026-09-04"
|
|
16
|
+
},
|
|
6
17
|
"claude": {
|
|
7
18
|
"agent": "native", "skill": "native", "globalChild": "inherited",
|
|
8
19
|
"identifierSyntax": "Claude alias or accepted Anthropic model ID",
|
|
@@ -76,6 +87,26 @@
|
|
|
76
87
|
"verification": "Inspect active profile and run metadata",
|
|
77
88
|
"sourceUrl": "https://docs.warp.dev/agent-platform/capabilities/agent-profiles-permissions", "verifiedAt": "2026-07-20"
|
|
78
89
|
},
|
|
90
|
+
"omp": {
|
|
91
|
+
"agent": "native",
|
|
92
|
+
"skill": "inherited",
|
|
93
|
+
"globalChild": "native",
|
|
94
|
+
"identifierSyntax": "provider/model identifier accepted by OMP --model",
|
|
95
|
+
"effortValues": [
|
|
96
|
+
"minimal",
|
|
97
|
+
"low",
|
|
98
|
+
"medium",
|
|
99
|
+
"high",
|
|
100
|
+
"xhigh"
|
|
101
|
+
],
|
|
102
|
+
"inheritance": "Omitted model and thinking level inherit the invoking Pi session",
|
|
103
|
+
"invalidPinFallback": "Pi resolves against its configured catalog and exits on invalid explicit selection",
|
|
104
|
+
"configTarget": "OMP native agent frontmatter and runtime launch arguments",
|
|
105
|
+
"artifactFormat": "model and thinkingLevel frontmatter; --model and --thinking runtime flags",
|
|
106
|
+
"verification": "Pinned OMP 18.1.10 source and live OpenRouter smoke; individual role defaults remain operator configured",
|
|
107
|
+
"sourceUrl": "https://github.com/can1357/oh-my-pi/tree/5964a0f7649275bcde818f20073193fd032451f2/packages/coding-agent",
|
|
108
|
+
"verifiedAt": "2026-09-04"
|
|
109
|
+
},
|
|
79
110
|
"pi": {
|
|
80
111
|
"agent": "native", "skill": "inherited", "globalChild": "native",
|
|
81
112
|
"identifierSyntax": "provider/model identifier accepted by Pi --model",
|
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
"refreshedAt": "2026-07-20",
|
|
5
5
|
"staleAfterDays": 90,
|
|
6
6
|
"providers": {
|
|
7
|
+
"antigravity": {
|
|
8
|
+
"roles": {
|
|
9
|
+
"reasoning": { "id": "configured/reasoning", "status": "unverified", "observed": false },
|
|
10
|
+
"coding": { "id": "configured/coding", "status": "unverified", "observed": false },
|
|
11
|
+
"efficiency": { "id": "configured/efficiency", "status": "unverified", "observed": false }
|
|
12
|
+
},
|
|
13
|
+
"sourceUrl": "https://antigravity.google/docs/cli/overview/", "verifiedAt": "2026-09-04"
|
|
14
|
+
},
|
|
7
15
|
"claude": {
|
|
8
16
|
"roles": {
|
|
9
17
|
"reasoning": { "id": "claude-opus-4-7", "status": "active", "observed": false },
|
|
@@ -52,6 +60,27 @@
|
|
|
52
60
|
},
|
|
53
61
|
"sourceUrl": "https://opencode.ai/docs/models", "verifiedAt": "2026-07-20"
|
|
54
62
|
},
|
|
63
|
+
"omp": {
|
|
64
|
+
"roles": {
|
|
65
|
+
"reasoning": {
|
|
66
|
+
"id": "configured/reasoning",
|
|
67
|
+
"status": "unverified",
|
|
68
|
+
"observed": false
|
|
69
|
+
},
|
|
70
|
+
"coding": {
|
|
71
|
+
"id": "configured/coding",
|
|
72
|
+
"status": "unverified",
|
|
73
|
+
"observed": false
|
|
74
|
+
},
|
|
75
|
+
"efficiency": {
|
|
76
|
+
"id": "configured/efficiency",
|
|
77
|
+
"status": "unverified",
|
|
78
|
+
"observed": false
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"sourceUrl": "https://github.com/can1357/oh-my-pi/tree/5964a0f7649275bcde818f20073193fd032451f2/packages/coding-agent",
|
|
82
|
+
"verifiedAt": "2026-09-04"
|
|
83
|
+
},
|
|
55
84
|
"pi": {
|
|
56
85
|
"roles": {
|
|
57
86
|
"reasoning": { "id": "configured/reasoning", "status": "unverified", "observed": false },
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# OMP native resources
|
|
2
|
+
|
|
3
|
+
The experimental `omp` provider targets Oh My Pi 18.1.10, reviewed at commit
|
|
4
|
+
`5964a0f7649275bcde818f20073193fd032451f2`. It remains separate from `pi`.
|
|
5
|
+
|
|
6
|
+
Project agents, Markdown prompts, rules and extensions use `.omp/agents`,
|
|
7
|
+
`.omp/prompts`, `.omp/rules` and `.omp/extensions`. Kernel skills use
|
|
8
|
+
`.agents/skills/<name>/SKILL.md`; `--copy-all` places standard skills in that
|
|
9
|
+
same one-level native directory. Default standard skills remain in the AIWG
|
|
10
|
+
source corpus for `aiwg discover` and `aiwg show`. Duplicate basenames fail
|
|
11
|
+
with a collision diagnostic before overwriting a different resource.
|
|
12
|
+
|
|
13
|
+
The `.omp/AGENTS.md` managed block uses native relative imports of root
|
|
14
|
+
WORKSPACE.md and AIWG.md. Other Markdown links remain ordinary links.
|
|
15
|
+
OMP's standalone root AGENTS discovery and foreign provider discovery are
|
|
16
|
+
independent: disable/enable those through OMP itself. AIWG does not rewrite
|
|
17
|
+
`disabledProviders`, foreign-user opt-in, extension settings or credentials.
|
|
18
|
+
Nearest native context and root-to-cwd standalone context can coexist. A
|
|
19
|
+
nested `.omp/AGENTS.md` shadows ancestor native context and rules: include
|
|
20
|
+
`@../../WORKSPACE.md` and `@../../AIWG.md` explicitly when the nested native
|
|
21
|
+
configuration is one directory below the repository root, or import the
|
|
22
|
+
ancestor bootstrap. OMP expands imports and deduplicates overlapping prompt blocks. Operator
|
|
23
|
+
content outside the bootstrap markers survives regeneration.
|
|
24
|
+
|
|
25
|
+
Agent descriptions and system prompt bodies retain their source text.
|
|
26
|
+
Explicit model IDs and priority lists pass through; configured model roles
|
|
27
|
+
use `modelsConfig.omp[role]`. Unmapped roles inherit the session model with a
|
|
28
|
+
degraded diagnostic. Unknown tool names are omitted with diagnostics. OMP
|
|
29
|
+
interprets an empty spawn list as absent, then infers wildcard spawns from
|
|
30
|
+
`task`; the adapter therefore removes `task` unless explicit spawn targets
|
|
31
|
+
or an explicit wildcard are supplied. Tool definitions are capability
|
|
32
|
+
selection, not a security sandbox.
|
|
33
|
+
|
|
34
|
+
The bridge registers native session start/shutdown, before-agent-start,
|
|
35
|
+
agent-end, tool-call and tool-result handlers. `/aiwg-bridge-status` reports
|
|
36
|
+
registration counts. No default policy handler is installed. Consumers use
|
|
37
|
+
`registerAiwgHandler` to attach an explicitly selected policy; tool-call
|
|
38
|
+
blocks are returned to the native harness and handler failure blocks that
|
|
39
|
+
call. Permission-request and pre-compaction enforcement are unsupported.
|
|
40
|
+
Native hook installation is distinct from this extension. Markdown prompts
|
|
41
|
+
are never executable custom commands.
|
|
42
|
+
|
|
43
|
+
`registerAiwgTool` accepts OMP's native tool definition together with input
|
|
44
|
+
and output validators. It propagates cancellation and execution errors,
|
|
45
|
+
and rejects invalid input/output. Runtime modules must be reviewed just
|
|
46
|
+
like any other executable OMP extension.
|
|
47
|
+
|
|
48
|
+
Deployment records SHA-256 ownership and transformation receipts beside
|
|
49
|
+
each resource. Refresh preserves operator creations and modifications,
|
|
50
|
+
even with force. The provider uninstall routine removes only unchanged
|
|
51
|
+
OMP-owned receipt entries and its own bootstrap markers. Disabling native
|
|
52
|
+
extension discovery remains an OMP setting; explicit extension paths may
|
|
53
|
+
still load despite `--no-extensions`.
|
|
54
|
+
|
|
55
|
+
Remove a complete OMP deployment with `aiwg remove omp --provider omp`.
|
|
56
|
+
Use `--dry-run` to preview or `--scope user` for the resolved OMP profile.
|
|
57
|
+
This is distinct from removing a single AIWG framework. Modified files and
|
|
58
|
+
unowned files remain, including other extensions and provider resources.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Native OMP bridge. Policy handlers are explicitly registered; no prompt-only enforcement. */
|
|
2
|
+
import type { ExtensionAPI, ToolDefinition } from '@oh-my-pi/pi-coding-agent';
|
|
3
|
+
|
|
4
|
+
export const supportedEvents = ['session_start', 'before_agent_start', 'tool_call', 'tool_result', 'agent_end', 'session_shutdown'] as const;
|
|
5
|
+
export const unsupportedEvents = ['permission_request', 'pre_compact_enforcement', 'native_hook_installation'] as const;
|
|
6
|
+
type Decision = { block: true; reason: string } | undefined;
|
|
7
|
+
type Handler = (event: unknown, context: unknown) => unknown | Promise<unknown>;
|
|
8
|
+
const handlers = new Map<string, Handler[]>();
|
|
9
|
+
export function registerAiwgHandler(event: string, handler: Handler): () => void {
|
|
10
|
+
if (!(supportedEvents as readonly string[]).includes(event)) throw new Error(`Unsupported OMP bridge event: ${event}`);
|
|
11
|
+
const list = handlers.get(event) || []; list.push(handler); handlers.set(event, list);
|
|
12
|
+
return () => { const at = list.indexOf(handler); if (at >= 0) list.splice(at, 1); };
|
|
13
|
+
}
|
|
14
|
+
export async function dispatchAiwgEvent(event: string, payload: unknown, context: unknown): Promise<Decision> {
|
|
15
|
+
for (const handler of handlers.get(event) || []) {
|
|
16
|
+
try {
|
|
17
|
+
const result = await handler(payload, context) as Decision;
|
|
18
|
+
if (event === 'tool_call' && result?.block) return { block: true, reason: String(result.reason || 'Denied by AIWG handler') };
|
|
19
|
+
} catch (error) {
|
|
20
|
+
if (event === 'tool_call') return { block: true, reason: `AIWG handler failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
/** ToolSmith callers provide schemas and validators; unsupported output never reaches OMP. */
|
|
27
|
+
export function registerAiwgTool(api: ExtensionAPI, tool: ToolDefinition, validateInput: (input: unknown) => boolean, validateOutput: (output: unknown) => boolean): void {
|
|
28
|
+
if (!tool.name || !tool.parameters || typeof tool.execute !== 'function') throw new Error('Invalid OMP custom tool contract');
|
|
29
|
+
api.registerTool({ ...tool, async execute(id, params, signal, update, context) {
|
|
30
|
+
if (signal?.aborted) throw new Error('AIWG tool cancelled');
|
|
31
|
+
if (!validateInput(params)) throw new Error('Invalid AIWG tool input');
|
|
32
|
+
const result = await tool.execute(id, params, signal, update, context);
|
|
33
|
+
if (signal?.aborted) throw new Error('AIWG tool cancelled');
|
|
34
|
+
if (!validateOutput(result)) throw new Error('Invalid AIWG tool output');
|
|
35
|
+
return result;
|
|
36
|
+
} });
|
|
37
|
+
}
|
|
38
|
+
export default function aiwgBridge(api: ExtensionAPI): void {
|
|
39
|
+
api.on('session_start', async (event, context) => { await dispatchAiwgEvent('session_start', event, context); });
|
|
40
|
+
api.on('before_agent_start', async (event, context) => { await dispatchAiwgEvent('before_agent_start', event, context); });
|
|
41
|
+
api.on('tool_call', (event, context) => dispatchAiwgEvent('tool_call', event, context));
|
|
42
|
+
api.on('tool_result', async (event, context) => { await dispatchAiwgEvent('tool_result', event, context); });
|
|
43
|
+
api.on('agent_end', async (event, context) => { await dispatchAiwgEvent('agent_end', event, context); });
|
|
44
|
+
api.on('session_shutdown', async (event, context) => { await dispatchAiwgEvent('session_shutdown', event, context); handlers.clear(); });
|
|
45
|
+
api.registerCommand('aiwg-bridge-status', {
|
|
46
|
+
description: 'Show active AIWG OMP lifecycle bridge registrations',
|
|
47
|
+
async handler(args, context) {
|
|
48
|
+
if (args.trim()) throw new Error('aiwg-bridge-status accepts no arguments');
|
|
49
|
+
context.ui.notify(`AIWG OMP bridge: ${supportedEvents.join(', ')}. Registered handlers: ${[...handlers.values()].reduce((n, list) => n + list.length, 0)}.`, 'info');
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import * as fs from 'fs/promises';
|
|
15
15
|
import * as path from 'path';
|
|
16
16
|
import { existsSync } from 'fs';
|
|
17
|
+
import YAML from 'yaml';
|
|
17
18
|
import { AgentValidator } from './agent-validator.js';
|
|
18
19
|
import { AgentPackager } from './agent-packager.js';
|
|
19
20
|
import { getProviderDefinition } from '../providers/provider-definitions.js';
|
|
@@ -244,6 +245,23 @@ export class AgentDeployer {
|
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
247
|
}
|
|
248
|
+
// Preserve provider-native fields consumed by the OMP packager. The
|
|
249
|
+
// historical line parser cannot represent arrays, booleans or objects.
|
|
250
|
+
const native = YAML.parse(frontmatter) || {};
|
|
251
|
+
for (const key of ['thinkingLevel', 'spawns', 'blocking', 'output', 'autoloadSkills', 'readSummarize', 'prewalk', 'advisor']) {
|
|
252
|
+
if (native[key] !== undefined)
|
|
253
|
+
Object.assign(metadata, { [key]: native[key] });
|
|
254
|
+
}
|
|
255
|
+
if (Array.isArray(native.model)) {
|
|
256
|
+
metadata.modelPriority = native.model;
|
|
257
|
+
delete metadata.model;
|
|
258
|
+
}
|
|
259
|
+
if (Array.isArray(native.tools))
|
|
260
|
+
metadata.tools = native.tools;
|
|
261
|
+
if (typeof native.name === 'string')
|
|
262
|
+
metadata.name = native.name;
|
|
263
|
+
if (typeof native.description === 'string')
|
|
264
|
+
metadata.description = native.description;
|
|
247
265
|
return metadata;
|
|
248
266
|
}
|
|
249
267
|
/**
|
|
@@ -4,10 +4,14 @@
|
|
|
4
4
|
* Converts agents to platform-specific formats.
|
|
5
5
|
*/
|
|
6
6
|
import { getProviderDefinition } from '../providers/provider-definitions.js';
|
|
7
|
+
import YAML from 'yaml';
|
|
8
|
+
import { transformAgent as transformOmpAgent } from '../providers/omp-agent.mjs';
|
|
7
9
|
export class AgentPackager {
|
|
8
10
|
getAgentFormatAdapters() {
|
|
9
11
|
return {
|
|
10
12
|
'claude-markdown': (agent) => this.convertToClaudeFormat(agent),
|
|
13
|
+
'antigravity-markdown': (agent) => this.convertToAntigravityFormat(agent),
|
|
14
|
+
'omp-markdown': (agent) => this.convertToOmpFormat(agent),
|
|
11
15
|
'cursor-json': (agent) => this.convertToCursorFormat(agent),
|
|
12
16
|
'codex-markdown': (agent) => this.convertToCodexFormat(agent),
|
|
13
17
|
'copilot-markdown': (agent) => this.convertToGenericFormat(agent),
|
|
@@ -16,6 +20,22 @@ export class AgentPackager {
|
|
|
16
20
|
'windsurf-markdown': (agent) => this.convertToWindsurfFormat(agent),
|
|
17
21
|
};
|
|
18
22
|
}
|
|
23
|
+
/** Antigravity custom agents use Markdown with provider-native tool identifiers. */
|
|
24
|
+
convertToAntigravityFormat(agent) {
|
|
25
|
+
const lines = ['---', `name: ${agent.metadata.name}`, `description: ${agent.metadata.description}`];
|
|
26
|
+
const toolMap = new Map([
|
|
27
|
+
['Read', 'view_file'],
|
|
28
|
+
['Write', 'write_to_file'],
|
|
29
|
+
['Edit', 'replace_file_content'],
|
|
30
|
+
['Grep', 'grep_search'],
|
|
31
|
+
['Bash', 'run_command'],
|
|
32
|
+
]);
|
|
33
|
+
const tools = (agent.metadata.tools ?? []).map(tool => toolMap.get(tool)).filter((tool) => Boolean(tool));
|
|
34
|
+
if (tools.length)
|
|
35
|
+
lines.push('tools:', ...tools.map(tool => ` - ${tool}`));
|
|
36
|
+
lines.push('---', '', agent.content);
|
|
37
|
+
return lines.join('\n');
|
|
38
|
+
}
|
|
19
39
|
/**
|
|
20
40
|
* Package agent for target platform
|
|
21
41
|
*/
|
|
@@ -35,6 +55,11 @@ export class AgentPackager {
|
|
|
35
55
|
format: definition.id,
|
|
36
56
|
};
|
|
37
57
|
}
|
|
58
|
+
/** Preserve native OMP metadata without passing through another provider's serializer. */
|
|
59
|
+
convertToOmpFormat(agent) {
|
|
60
|
+
const metadata = { ...agent.metadata, model: agent.metadata.modelPriority ?? agent.metadata.model };
|
|
61
|
+
return transformOmpAgent(agent.filePath, `---\n${YAML.stringify(metadata)}---\n${agent.content}`);
|
|
62
|
+
}
|
|
38
63
|
/**
|
|
39
64
|
* Convert to Claude Code format (.md with YAML frontmatter)
|
|
40
65
|
*/
|
|
@@ -50,28 +50,36 @@ export class SqliteGraphBackend {
|
|
|
50
50
|
catch {
|
|
51
51
|
throw new Error('sqlite backend is unavailable; run `aiwg features install sqlite`');
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
try {
|
|
54
|
+
// Changing journal mode may return SQLITE_BUSY without invoking SQLite's
|
|
55
|
+
// busy handler during a lock upgrade. Retry initialization as a whole:
|
|
56
|
+
// pragmas are idempotent and failed schema transactions roll back.
|
|
57
|
+
this.withBusyContext('initializing the graph database', () => {
|
|
58
|
+
this.assertSafeSqliteVersion();
|
|
59
|
+
const requestedJournal = dbPath === ':memory:' ? 'memory' : 'wal';
|
|
60
|
+
const actualJournal = String(this.db.pragma(`journal_mode = ${requestedJournal}`, { simple: true })).toLowerCase();
|
|
61
|
+
if (actualJournal !== requestedJournal) {
|
|
62
|
+
throw new Error(`sqlite backend requested journal_mode=${requestedJournal} but received ${actualJournal}`);
|
|
63
|
+
}
|
|
64
|
+
this.db.pragma(`synchronous = ${options.synchronous ?? 'NORMAL'}`);
|
|
65
|
+
this.db.pragma('wal_autocheckpoint = 1000');
|
|
66
|
+
this.migrateSchema();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
57
70
|
this.db.close();
|
|
58
|
-
throw
|
|
71
|
+
throw error;
|
|
59
72
|
}
|
|
60
|
-
this.db.pragma(`synchronous = ${options.synchronous ?? 'NORMAL'}`);
|
|
61
|
-
this.db.pragma('wal_autocheckpoint = 1000');
|
|
62
|
-
this.migrateSchema();
|
|
63
73
|
}
|
|
64
74
|
assertSafeSqliteVersion() {
|
|
65
75
|
const version = String(this.db.prepare('SELECT sqlite_version() AS version').get().version);
|
|
66
76
|
if (!isWalResetSafeVersion(version)) {
|
|
67
|
-
this.db.close();
|
|
68
77
|
throw new Error(`sqlite backend requires a WAL-reset-safe SQLite build (3.44.6, 3.50.7, or >=3.51.3); found ${version}`);
|
|
69
78
|
}
|
|
70
79
|
}
|
|
71
80
|
migrateSchema() {
|
|
72
81
|
const current = Number(this.db.pragma('user_version', { simple: true }));
|
|
73
82
|
if (current > SCHEMA_VERSION) {
|
|
74
|
-
this.db.close();
|
|
75
83
|
throw new Error(`sqlite graph schema ${current} is newer than supported schema ${SCHEMA_VERSION}`);
|
|
76
84
|
}
|
|
77
85
|
if (current === SCHEMA_VERSION)
|
|
@@ -101,6 +101,22 @@ function containsTokenSequence(haystack, needle) {
|
|
|
101
101
|
function withIndexProvenance(entry, graph) {
|
|
102
102
|
return { ...entry, indexGraph: graph, indexScope: graphScope(graph) };
|
|
103
103
|
}
|
|
104
|
+
/** Keep existing project capabilities visible while their derived cache is unavailable. */
|
|
105
|
+
function projectCapabilityFallback(cwd) {
|
|
106
|
+
const index = loadGraphIndexFile(cwd, 'metadata.json', 'project');
|
|
107
|
+
if (index) {
|
|
108
|
+
const entries = Object.values(index.entries).map((entry) => withIndexProvenance(entry, 'project'));
|
|
109
|
+
if (entries.length > 0) {
|
|
110
|
+
// One diagnostic per command, on stderr so JSON and skill bodies stay parseable.
|
|
111
|
+
console.error('Warning: project capability cache is unavailable or stale; using the local project index. Run `aiwg index sync` to repair the cache.');
|
|
112
|
+
return entries;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (['extensions', 'addons', 'frameworks', 'plugins', 'skills'].some((dir) => fs.existsSync(projectAiwgPath(cwd, dir)))) {
|
|
116
|
+
console.error('Warning: project capabilities could not be loaded: the cache is unavailable and the local project index is missing or empty. Run `aiwg index build --graph project` to repair discovery.');
|
|
117
|
+
}
|
|
118
|
+
return index ? [] : null;
|
|
119
|
+
}
|
|
104
120
|
function discoveryIdForEntry(entry) {
|
|
105
121
|
return stableRecordId(recordTypeForEntry(entry, 'v2'), entry.path);
|
|
106
122
|
}
|
|
@@ -919,6 +935,13 @@ export async function discoverCapability(cwd, params) {
|
|
|
919
935
|
let unavailableReason;
|
|
920
936
|
for (const graph of graphs) {
|
|
921
937
|
const loaded = loadFortemiCoreMetadataEntries(cwd, graph, verifiedSourcePaths);
|
|
938
|
+
if (loaded.reason && graph === 'project' && !params.graph) {
|
|
939
|
+
const fallback = projectCapabilityFallback(cwd);
|
|
940
|
+
if (fallback) {
|
|
941
|
+
entries.push(...fallback);
|
|
942
|
+
continue;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
922
945
|
if (loaded.reason)
|
|
923
946
|
unavailableReason ??= loaded.reason;
|
|
924
947
|
entries.push(...loaded.entries.map((entry) => withIndexProvenance(entry, graph)));
|
|
@@ -1373,6 +1396,13 @@ async function loadShowEntries(cwd, params) {
|
|
|
1373
1396
|
let unavailableReason;
|
|
1374
1397
|
for (const graph of graphs) {
|
|
1375
1398
|
const loaded = loadFortemiCoreMetadataEntries(cwd, graph);
|
|
1399
|
+
if (loaded.reason && graph === 'project' && !params.graph) {
|
|
1400
|
+
const fallback = projectCapabilityFallback(cwd);
|
|
1401
|
+
if (fallback) {
|
|
1402
|
+
entries.push(...fallback);
|
|
1403
|
+
continue;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1376
1406
|
if (loaded.reason)
|
|
1377
1407
|
unavailableReason ??= loaded.reason;
|
|
1378
1408
|
entries.push(...loaded.entries.map((entry) => withIndexProvenance(entry, graph)));
|