@agimon-ai/po-major-mode 0.0.0-alpha.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/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/apiContracts.cjs +17 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +13 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +26 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +21 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/server.cjs +81 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +76 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/index.cjs +28 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +19 -0
- package/dist/index.mjs.map +1 -0
- package/dist/majorModeText-DCFGufYS.cjs +89 -0
- package/dist/majorModeText-DCFGufYS.cjs.map +1 -0
- package/dist/majorModeText-DuWMOhxX.mjs +54 -0
- package/dist/majorModeText-DuWMOhxX.mjs.map +1 -0
- package/llms.txt +12 -0
- package/package.json +119 -0
- package/src/prompts/po-author-major-mode/SKILL.md +30 -0
- package/src/prompts/po-author-major-mode/references/modes-contract.md +152 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vuong Ngo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# @agimon-ai/po-major-mode
|
|
2
|
+
|
|
3
|
+
Named major-mode selection for [Po](https://www.npmjs.com/package/@agimon-ai/po) sessions.
|
|
4
|
+
|
|
5
|
+
A **major mode** is one of the four axes of a Po selection, alongside domains, the profile,
|
|
6
|
+
and the minor modes. It names an ordered list of layers, and each layer names the packages it
|
|
7
|
+
activates:
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
# .po/modes.yaml
|
|
11
|
+
layers:
|
|
12
|
+
team:
|
|
13
|
+
packages: ['@agimon-ai/po-team']
|
|
14
|
+
ask-user:
|
|
15
|
+
packages: ['@agimon-ai/po-user-feedback']
|
|
16
|
+
task:
|
|
17
|
+
packages: ['@agimon-ai/po-task']
|
|
18
|
+
|
|
19
|
+
majorMode:
|
|
20
|
+
minimal:
|
|
21
|
+
description: Lean mode with Team delegation and persistent tasks.
|
|
22
|
+
layers: [team, task]
|
|
23
|
+
copilot:
|
|
24
|
+
description: General coding with delegation, persistent tasks, and structured user feedback.
|
|
25
|
+
layers: [team, ask-user, task]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Default packages load before these layers. The `layers` array is authored activation order, not a
|
|
29
|
+
set.
|
|
30
|
+
|
|
31
|
+
## What it registers
|
|
32
|
+
|
|
33
|
+
| Surface | Behavior |
|
|
34
|
+
| ----------------------- | -------------------------------------------------------------------------- |
|
|
35
|
+
| `/mode` | picks a major mode, applies it, and reloads |
|
|
36
|
+
| `major_mode` voice tool | `list` returns every mode with its purpose and layers; `switch` queues one |
|
|
37
|
+
| status line | `*profile*:[major-mode]:domains`, amber while a switch is pending |
|
|
38
|
+
| Help contribution | exposes focused `modes.yaml` guidance while Po Help is active |
|
|
39
|
+
|
|
40
|
+
## Help guidance
|
|
41
|
+
|
|
42
|
+
This package registers `po-author-major-mode` with the session-local `doom/help` Cordis
|
|
43
|
+
service. Registration is inert until `@agimon-ai/po-help` is active. Once active, the Help
|
|
44
|
+
skill routes the AI through this package's validated [`llms.txt`](./llms.txt) index.
|
|
45
|
+
|
|
46
|
+
The package owns both the concise [major-mode authoring prompt](./src/prompts/po-author-major-mode/SKILL.md)
|
|
47
|
+
and the detailed [`modes.yaml` contract](./src/prompts/po-author-major-mode/references/modes-contract.md),
|
|
48
|
+
so the guidance is versioned with the parser and runtime that consume it.
|
|
49
|
+
|
|
50
|
+
## Switching, and why it is not always a reload
|
|
51
|
+
|
|
52
|
+
A major-mode change alters which extensions load, and Pi freezes the CLI `--extension` list at
|
|
53
|
+
construction. So the disposition depends on how the session started:
|
|
54
|
+
|
|
55
|
+
- **synchronized** (`dpi`, or regular `pi` after `po sync`): the session composes its own
|
|
56
|
+
extension set on every load, so the new layers arrive with a `pi-reload`. If the target
|
|
57
|
+
composition has no synchronized bundle yet, the transition reports `sync-required` and asks for
|
|
58
|
+
`po sync`.
|
|
59
|
+
- **launcher**: the extension closure is fixed, so a mode whose layers differ needs a new process.
|
|
60
|
+
The switch is journaled as pending and the command prints the relaunch line rather than
|
|
61
|
+
pretending it applied.
|
|
62
|
+
|
|
63
|
+
Either way the change is planned through the session's transition coordinator first, and active
|
|
64
|
+
minor modes are captured before the reload and restored after it. A failed apply rolls the harness
|
|
65
|
+
state back from a snapshot and journals the transition as aborted.
|
|
66
|
+
|
|
67
|
+
The voice tool never applies a switch itself. It mints an opaque handoff token and sends
|
|
68
|
+
`/mode --voice-switch-token=…` back as a follow-up, so the reload happens inside a command handler
|
|
69
|
+
where it can be the terminal action.
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
Po depends on this package and activates it as fixed host core, so a Po install already has
|
|
74
|
+
it. It is not selectable from `.po/modes.yaml`. It is what reads that file.
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
79
|
+
|
|
80
|
+
Pi and server declarations live in `src/extensions` and build directly to `/extensions/pi`
|
|
81
|
+
and `/extensions/server`. Flat root exports expose selection, status, telemetry, and schema helpers.
|
|
82
|
+
Controllers own host integration; text and telemetry services live in named folders.
|
|
83
|
+
|
|
84
|
+
The Pi declaration installs optional Config, Transition, and Voice service bindings before its
|
|
85
|
+
command and event declarations. Session startup awaits the runtime binding before publishing status.
|
|
86
|
+
The shared helper owns teardown of those bindings. Picker, selection-switch, and journal modules
|
|
87
|
+
remain lazy imports, so registering `/mode` does not load them eagerly.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
//#region src/schemas/apiContracts.ts
|
|
6
|
+
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
7
|
+
const apiContracts = (0, require("@agimon-ai/po-core/apiContracts").defineApiContract)({
|
|
8
|
+
version: 1,
|
|
9
|
+
http: [],
|
|
10
|
+
sockets: [],
|
|
11
|
+
dynamic: []
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
exports.apiContracts = apiContracts;
|
|
15
|
+
exports.default = apiContracts;
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=apiContracts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;;;;AAGA,MAAa,gBAAA,4CAAeA,CAAAA,CAAAA,kBAAAA,CAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/schemas/apiContracts.d.ts
|
|
2
|
+
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
3
|
+
export declare const apiContracts: {
|
|
4
|
+
version: 1;
|
|
5
|
+
protocols?: Record<string, string> | undefined;
|
|
6
|
+
schemas?: Record<string, boolean | object> | undefined;
|
|
7
|
+
http: {
|
|
8
|
+
id: string;
|
|
9
|
+
scope: "global" | "session" | "workspace";
|
|
10
|
+
basePath?: string | undefined;
|
|
11
|
+
path: string;
|
|
12
|
+
method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
|
|
13
|
+
description: string;
|
|
14
|
+
availability?: string | undefined;
|
|
15
|
+
authentication: "device" | "none" | "owner";
|
|
16
|
+
parameters?: {
|
|
17
|
+
name: string;
|
|
18
|
+
in: "header" | "path" | "query";
|
|
19
|
+
required: boolean;
|
|
20
|
+
schema: boolean | object;
|
|
21
|
+
}[] | undefined;
|
|
22
|
+
body?: {
|
|
23
|
+
contentType: string;
|
|
24
|
+
contentTypes?: string[] | undefined;
|
|
25
|
+
required: boolean;
|
|
26
|
+
schema: boolean | object;
|
|
27
|
+
} | undefined;
|
|
28
|
+
responses: Record<string, {
|
|
29
|
+
description: string;
|
|
30
|
+
contentType?: string | undefined;
|
|
31
|
+
schema?: boolean | object | undefined;
|
|
32
|
+
events?: Record<string, boolean | object> | undefined;
|
|
33
|
+
}>;
|
|
34
|
+
}[];
|
|
35
|
+
sockets: {
|
|
36
|
+
id: string;
|
|
37
|
+
scope: "global" | "session" | "workspace";
|
|
38
|
+
description: string;
|
|
39
|
+
availability?: string | undefined;
|
|
40
|
+
service: string;
|
|
41
|
+
member: string;
|
|
42
|
+
direction: "client-to-server" | "server-to-client";
|
|
43
|
+
kind: "channel" | "method" | "state";
|
|
44
|
+
input: boolean | object;
|
|
45
|
+
output?: boolean | object | undefined;
|
|
46
|
+
errors?: boolean | object | undefined;
|
|
47
|
+
}[];
|
|
48
|
+
dynamic: string[];
|
|
49
|
+
gaps?: string[] | undefined;
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
export { apiContracts as default };
|
|
53
|
+
//# sourceMappingURL=apiContracts.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineApiContract } from "@agimon-ai/po-core/apiContracts";
|
|
2
|
+
//#region src/schemas/apiContracts.ts
|
|
3
|
+
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
4
|
+
const apiContracts = defineApiContract({
|
|
5
|
+
version: 1,
|
|
6
|
+
http: [],
|
|
7
|
+
sockets: [],
|
|
8
|
+
dynamic: []
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { apiContracts, apiContracts as default };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=apiContracts.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAa,eAAe,kBAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
let _agimon_ai_po_core_mcpFacet = require("@agimon-ai/po-core/mcpFacet");
|
|
6
|
+
let _agimon_ai_po_core_serverFacet = require("@agimon-ai/po-core/serverFacet");
|
|
7
|
+
//#region src/extensions/workspaces/sessions/(backend)/skill/po-author-major-mode.mcp.ts
|
|
8
|
+
var po_author_major_mode_mcp_default = (0, _agimon_ai_po_core_mcpFacet.defineMcpSkill)({
|
|
9
|
+
name: "po-author-major-mode",
|
|
10
|
+
description: "Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.",
|
|
11
|
+
read: () => (0, _agimon_ai_po_core_serverFacet.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/po-author-major-mode/SKILL.md")
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region generated/mcp.ts
|
|
15
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
16
|
+
const mcp = (0, _agimon_ai_po_core_mcpFacet.defineMcpPlugin)({
|
|
17
|
+
name: "@agimon-ai/po-major-mode",
|
|
18
|
+
session: (context) => ({ get skills() {
|
|
19
|
+
return [at(po_author_major_mode_mcp_default, context)];
|
|
20
|
+
} })
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
exports.default = mcp;
|
|
24
|
+
exports.mcp = mcp;
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=mcp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.cjs","names":["defineMcpSkill","readPackageResource","defineMcpPlugin","skillPoAuthorMajorMode"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-author-major-mode.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineMcpSkill({\n name: 'po-author-major-mode',\n description:\n \"Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.\",\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-author-major-mode/SKILL.md'),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type DoomMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoAuthorMajorMode from '../src/extensions/workspaces/sessions/(backend)/skill/po-author-major-mode.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-major-mode',\n session: (context) => ({\n get skills(): DoomMcpSessionPlugin['skills'] { return [at(skillPoAuthorMajorMode, context)]; },\n }) satisfies DoomMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":";;;;;;;AAGA,IAAA,oCAAA,GAAeA,4BAAAA,eAAAA,CAAe;CAC5B,MAAM;CACN,aACE;CACF,aAAA,GAAYC,+BAAAA,oBAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,MAAqC,2CAA2C;AAC9F,CAAC;;;ACFD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAa,OAAA,GAAMC,4BAAAA,gBAAAA,CAAgB;CACjC,MAAM;CACN,UAAU,aAAa,EACrB,IAAI,SAAyC;EAAE,OAAO,CAAC,GAAGC,kCAAwB,OAAO,CAAC;CAAG,EAC/F;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.mts","names":[],"sources":["../../generated/mcp.ts"],"mappings":";qBASa,2CAAG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineMcpPlugin, defineMcpSkill } from "@agimon-ai/po-core/mcpFacet";
|
|
2
|
+
import { readPackageResource } from "@agimon-ai/po-core/serverFacet";
|
|
3
|
+
//#region src/extensions/workspaces/sessions/(backend)/skill/po-author-major-mode.mcp.ts
|
|
4
|
+
var po_author_major_mode_mcp_default = defineMcpSkill({
|
|
5
|
+
name: "po-author-major-mode",
|
|
6
|
+
description: "Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.",
|
|
7
|
+
read: () => readPackageResource(import.meta.url, "src/prompts/po-author-major-mode/SKILL.md")
|
|
8
|
+
});
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region generated/mcp.ts
|
|
11
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
12
|
+
const mcp = defineMcpPlugin({
|
|
13
|
+
name: "@agimon-ai/po-major-mode",
|
|
14
|
+
session: (context) => ({ get skills() {
|
|
15
|
+
return [at(po_author_major_mode_mcp_default, context)];
|
|
16
|
+
} })
|
|
17
|
+
});
|
|
18
|
+
//#endregion
|
|
19
|
+
export { mcp as default, mcp };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=mcp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.mjs","names":["skillPoAuthorMajorMode"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-author-major-mode.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineMcpSkill({\n name: 'po-author-major-mode',\n description:\n \"Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.\",\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-author-major-mode/SKILL.md'),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type DoomMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoAuthorMajorMode from '../src/extensions/workspaces/sessions/(backend)/skill/po-author-major-mode.mcp';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-major-mode',\n session: (context) => ({\n get skills(): DoomMcpSessionPlugin['skills'] { return [at(skillPoAuthorMajorMode, context)]; },\n }) satisfies DoomMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":";;;AAGA,IAAA,mCAAe,eAAe;CAC5B,MAAM;CACN,aACE;CACF,YAAY,oBAAoB,YAAY,KAAK,2CAA2C;AAC9F,CAAC;;;ACFD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAa,MAAM,gBAAgB;CACjC,MAAM;CACN,UAAU,aAAa,EACrB,IAAI,SAAyC;EAAE,OAAO,CAAC,GAAGA,kCAAwB,OAAO,CAAC;CAAG,EAC/F;AACF,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_majorModeText = require("../majorModeText-DCFGufYS.cjs");
|
|
6
|
+
let _agimon_ai_po_core_serverFacet = require("@agimon-ai/po-core/serverFacet");
|
|
7
|
+
let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
|
|
8
|
+
let _agimon_ai_po_config_majorModes = require("@agimon-ai/po-config/majorModes");
|
|
9
|
+
//#region src/extensions/workspaces/sessions/(backend)/_lib/majorModeServerCommand.ts
|
|
10
|
+
function createMajorModeServerCommand(host) {
|
|
11
|
+
return {
|
|
12
|
+
name: require_majorModeText.MAJOR_MODE_COMMAND,
|
|
13
|
+
description: "Show or change the active Po major mode.",
|
|
14
|
+
async execute(args, execution) {
|
|
15
|
+
const config = (0, _agimon_ai_po_config_majorModes.loadMajorModesConfig)(execution.repoRoot);
|
|
16
|
+
let requested = args.trim();
|
|
17
|
+
if (!requested) {
|
|
18
|
+
const selected = await execution.client.request({
|
|
19
|
+
kind: "select",
|
|
20
|
+
title: `Major mode (current: ${execution.selection.majorMode})`,
|
|
21
|
+
options: Object.keys(config.majorMode).map((name) => ({
|
|
22
|
+
label: require_majorModeText.majorModeOptionLabel(name, config.majorMode[name]?.layers ?? [], execution.selection.majorMode),
|
|
23
|
+
value: name
|
|
24
|
+
}))
|
|
25
|
+
});
|
|
26
|
+
if (typeof selected !== "string" || !selected) return;
|
|
27
|
+
requested = selected;
|
|
28
|
+
}
|
|
29
|
+
(0, _agimon_ai_po_config_majorModes.resolveLayers)(config, requested);
|
|
30
|
+
if (requested === execution.selection.majorMode) return;
|
|
31
|
+
await host.changeSelection({
|
|
32
|
+
axis: "majorMode",
|
|
33
|
+
majorMode: requested
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/extensions/workspaces/sessions/(backend)/command/majorMode.server.ts
|
|
40
|
+
var majorMode_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoutedContribution)(({ agent }) => agent ? createMajorModeServerCommand(agent) : void 0, { cardinality: "optional" });
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/extensions/workspaces/sessions/(backend)/resource/poAuthorMajorMode.server.ts
|
|
43
|
+
var poAuthorMajorMode_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)({
|
|
44
|
+
name: "po-author-major-mode",
|
|
45
|
+
description: "Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.",
|
|
46
|
+
when: {
|
|
47
|
+
state: { "minor-mode": "help" },
|
|
48
|
+
attribution: {
|
|
49
|
+
kind: "minor",
|
|
50
|
+
mode: "help"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
kind: "skill",
|
|
54
|
+
path: (0, _agimon_ai_po_core_serverFacet.packageResourcePath)(require("url").pathToFileURL(__filename).href, "src/prompts/po-author-major-mode/SKILL.md"),
|
|
55
|
+
read: () => (0, _agimon_ai_po_core_serverFacet.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/po-author-major-mode/SKILL.md")
|
|
56
|
+
});
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region generated/server.ts
|
|
59
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
60
|
+
/* v8 ignore next -- generated normalization branch */
|
|
61
|
+
const defined = (values) => values.filter((value) => value !== void 0);
|
|
62
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
63
|
+
...identity,
|
|
64
|
+
...value
|
|
65
|
+
};
|
|
66
|
+
const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
|
|
67
|
+
name: "@agimon-ai/po-major-mode",
|
|
68
|
+
session: (context) => ({
|
|
69
|
+
get commands() {
|
|
70
|
+
return defined([via({ name: "major-mode" }, at(majorMode_server_default, context))]);
|
|
71
|
+
},
|
|
72
|
+
get resources() {
|
|
73
|
+
return [at(poAuthorMajorMode_server_default, context)];
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
//#endregion
|
|
78
|
+
exports.default = facet;
|
|
79
|
+
exports.facet = facet;
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=server.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["MAJOR_MODE_COMMAND","loadMajorModesConfig","majorModeOptionLabel","defineRoutedContribution","defineResource","packageResourcePath","readPackageResource","defineServerPlugin","commandMajorMode","resourcePoAuthorMajorMode"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/majorModeServerCommand.ts","../../src/extensions/workspaces/sessions/(backend)/command/majorMode.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/poAuthorMajorMode.server.ts","../../generated/server.ts"],"sourcesContent":["import { loadMajorModesConfig, resolveLayers } from '@agimon-ai/po-config/majorModes';\nimport { type DoomHeadlessCommand, type DoomHeadlessHostService } from '@agimon-ai/po-core/headless';\n\nimport { MAJOR_MODE_COMMAND, majorModeOptionLabel } from '../../../../../services/majorModeText';\n\nexport function createMajorModeServerCommand(host: DoomHeadlessHostService): DoomHeadlessCommand {\n return {\n name: MAJOR_MODE_COMMAND,\n description: 'Show or change the active Po major mode.',\n async execute(args, execution) {\n const config = loadMajorModesConfig(execution.repoRoot);\n let requested = args.trim();\n if (!requested) {\n const selected = await execution.client.request({\n kind: 'select',\n title: `Major mode (current: ${execution.selection.majorMode})`,\n options: Object.keys(config.majorMode).map((name) => ({\n label: majorModeOptionLabel(name, config.majorMode[name]?.layers ?? [], execution.selection.majorMode),\n value: name,\n })),\n });\n if (typeof selected !== 'string' || !selected) return;\n requested = selected;\n }\n // Reject invalid command input before requesting a capability transition.\n resolveLayers(config, requested);\n if (requested === execution.selection.majorMode) return;\n await host.changeSelection({ axis: 'majorMode', majorMode: requested });\n },\n };\n}\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport { createMajorModeServerCommand } from '../_lib/majorModeServerCommand';\nexport default defineRoutedContribution(\n ({ agent }: DoomServerPluginContext) => (agent ? createMajorModeServerCommand(agent) : undefined),\n { cardinality: 'optional' },\n);\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineResource({\n name: 'po-author-major-mode',\n description:\n \"Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.\",\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor' as const, mode: 'help' } },\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/po-author-major-mode/SKILL.md'),\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-author-major-mode/SKILL.md'),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\n\nimport commandMajorMode from '../src/extensions/workspaces/sessions/(backend)/command/majorMode.server';\nimport resourcePoAuthorMajorMode from '../src/extensions/workspaces/sessions/(backend)/resource/poAuthorMajorMode.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/po-major-mode',\n session: (context) => ({\n get commands(): DoomServerSessionPlugin['commands'] { return defined([via({ name: 'major-mode' }, at(commandMajorMode, context))]); },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourcePoAuthorMajorMode, context)]; },\n }),\n});\n\nexport default facet;\n"],"mappings":";;;;;;;;;AAKA,SAAgB,6BAA6B,MAAoD;CAC/F,OAAO;EACL,MAAMA,sBAAAA;EACN,aAAa;EACb,MAAM,QAAQ,MAAM,WAAW;GAC7B,MAAM,UAAA,GAASC,gCAAAA,qBAAAA,CAAqB,UAAU,QAAQ;GACtD,IAAI,YAAY,KAAK,KAAK;GAC1B,IAAI,CAAC,WAAW;IACd,MAAM,WAAW,MAAM,UAAU,OAAO,QAAQ;KAC9C,MAAM;KACN,OAAO,wBAAwB,UAAU,UAAU,UAAU;KAC7D,SAAS,OAAO,KAAK,OAAO,SAAS,CAAC,CAAC,KAAK,UAAU;MACpD,OAAOC,sBAAAA,qBAAqB,MAAM,OAAO,UAAU,KAAK,EAAE,UAAU,CAAC,GAAG,UAAU,UAAU,SAAS;MACrG,OAAO;KACT,EAAE;IACJ,CAAC;IACD,IAAI,OAAO,aAAa,YAAY,CAAC,UAAU;IAC/C,YAAY;GACd;GAEA,CAAA,GAAA,gCAAA,cAAA,CAAc,QAAQ,SAAS;GAC/B,IAAI,cAAc,UAAU,UAAU,WAAW;GACjD,MAAM,KAAK,gBAAgB;IAAE,MAAM;IAAa,WAAW;GAAU,CAAC;EACxE;CACF;AACF;;;AC1BA,IAAA,4BAAA,GAAeC,iCAAAA,yBAAAA,EACZ,EAAE,YAAsC,QAAQ,6BAA6B,KAAK,IAAI,KAAA,GACvF,EAAE,aAAa,WAAW,CAC5B;;;ACJA,IAAA,oCAAA,GAAeC,iCAAAA,eAAAA,CAAe;CAC5B,MAAM;CACN,aACE;CACF,MAAM;EAAE,OAAO,EAAE,cAAc,OAAO;EAAG,aAAa;GAAE,MAAM;GAAkB,MAAM;EAAO;CAAE;CAC/F,MAAM;CACN,OAAA,GAAMC,+BAAAA,oBAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,MAAqC,2CAA2C;CACtF,aAAA,GAAYC,+BAAAA,oBAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,MAAqC,2CAA2C;AAC9F,CAAC;;;ACJD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;;AAEpE,MAAM,WAAc,WAClB,OAAO,QAAQ,UAAsB,UAAU,KAAA,CAAS;AAC1D,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,SAAA,GAAQC,+BAAAA,mBAAAA,CAAmB;CACtC,MAAM;CACN,UAAU,aAAa;EACrB,IAAI,WAAgD;GAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,aAAa,GAAG,GAAGC,0BAAkB,OAAO,CAAC,CAAC,CAAC;EAAG;EACpI,IAAI,YAAkD;GAAE,OAAO,CAAC,GAAGC,kCAA2B,OAAO,CAAC;EAAG;CAC3G;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";qBAea,gDAAK"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { i as majorModeOptionLabel, t as MAJOR_MODE_COMMAND } from "../majorModeText-DuWMOhxX.mjs";
|
|
2
|
+
import { defineServerPlugin, packageResourcePath, readPackageResource } from "@agimon-ai/po-core/serverFacet";
|
|
3
|
+
import { defineResource, defineRoutedContribution } from "@agimon-ai/po-core/extensionFile";
|
|
4
|
+
import { loadMajorModesConfig, resolveLayers } from "@agimon-ai/po-config/majorModes";
|
|
5
|
+
//#region src/extensions/workspaces/sessions/(backend)/_lib/majorModeServerCommand.ts
|
|
6
|
+
function createMajorModeServerCommand(host) {
|
|
7
|
+
return {
|
|
8
|
+
name: MAJOR_MODE_COMMAND,
|
|
9
|
+
description: "Show or change the active Po major mode.",
|
|
10
|
+
async execute(args, execution) {
|
|
11
|
+
const config = loadMajorModesConfig(execution.repoRoot);
|
|
12
|
+
let requested = args.trim();
|
|
13
|
+
if (!requested) {
|
|
14
|
+
const selected = await execution.client.request({
|
|
15
|
+
kind: "select",
|
|
16
|
+
title: `Major mode (current: ${execution.selection.majorMode})`,
|
|
17
|
+
options: Object.keys(config.majorMode).map((name) => ({
|
|
18
|
+
label: majorModeOptionLabel(name, config.majorMode[name]?.layers ?? [], execution.selection.majorMode),
|
|
19
|
+
value: name
|
|
20
|
+
}))
|
|
21
|
+
});
|
|
22
|
+
if (typeof selected !== "string" || !selected) return;
|
|
23
|
+
requested = selected;
|
|
24
|
+
}
|
|
25
|
+
resolveLayers(config, requested);
|
|
26
|
+
if (requested === execution.selection.majorMode) return;
|
|
27
|
+
await host.changeSelection({
|
|
28
|
+
axis: "majorMode",
|
|
29
|
+
majorMode: requested
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/extensions/workspaces/sessions/(backend)/command/majorMode.server.ts
|
|
36
|
+
var majorMode_server_default = defineRoutedContribution(({ agent }) => agent ? createMajorModeServerCommand(agent) : void 0, { cardinality: "optional" });
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/extensions/workspaces/sessions/(backend)/resource/poAuthorMajorMode.server.ts
|
|
39
|
+
var poAuthorMajorMode_server_default = defineResource({
|
|
40
|
+
name: "po-author-major-mode",
|
|
41
|
+
description: "Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.",
|
|
42
|
+
when: {
|
|
43
|
+
state: { "minor-mode": "help" },
|
|
44
|
+
attribution: {
|
|
45
|
+
kind: "minor",
|
|
46
|
+
mode: "help"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
kind: "skill",
|
|
50
|
+
path: packageResourcePath(import.meta.url, "src/prompts/po-author-major-mode/SKILL.md"),
|
|
51
|
+
read: () => readPackageResource(import.meta.url, "src/prompts/po-author-major-mode/SKILL.md")
|
|
52
|
+
});
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region generated/server.ts
|
|
55
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
56
|
+
/* v8 ignore next -- generated normalization branch */
|
|
57
|
+
const defined = (values) => values.filter((value) => value !== void 0);
|
|
58
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
59
|
+
...identity,
|
|
60
|
+
...value
|
|
61
|
+
};
|
|
62
|
+
const facet = defineServerPlugin({
|
|
63
|
+
name: "@agimon-ai/po-major-mode",
|
|
64
|
+
session: (context) => ({
|
|
65
|
+
get commands() {
|
|
66
|
+
return defined([via({ name: "major-mode" }, at(majorMode_server_default, context))]);
|
|
67
|
+
},
|
|
68
|
+
get resources() {
|
|
69
|
+
return [at(poAuthorMajorMode_server_default, context)];
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
//#endregion
|
|
74
|
+
export { facet as default, facet };
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["commandMajorMode","resourcePoAuthorMajorMode"],"sources":["../../src/extensions/workspaces/sessions/(backend)/_lib/majorModeServerCommand.ts","../../src/extensions/workspaces/sessions/(backend)/command/majorMode.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/poAuthorMajorMode.server.ts","../../generated/server.ts"],"sourcesContent":["import { loadMajorModesConfig, resolveLayers } from '@agimon-ai/po-config/majorModes';\nimport { type DoomHeadlessCommand, type DoomHeadlessHostService } from '@agimon-ai/po-core/headless';\n\nimport { MAJOR_MODE_COMMAND, majorModeOptionLabel } from '../../../../../services/majorModeText';\n\nexport function createMajorModeServerCommand(host: DoomHeadlessHostService): DoomHeadlessCommand {\n return {\n name: MAJOR_MODE_COMMAND,\n description: 'Show or change the active Po major mode.',\n async execute(args, execution) {\n const config = loadMajorModesConfig(execution.repoRoot);\n let requested = args.trim();\n if (!requested) {\n const selected = await execution.client.request({\n kind: 'select',\n title: `Major mode (current: ${execution.selection.majorMode})`,\n options: Object.keys(config.majorMode).map((name) => ({\n label: majorModeOptionLabel(name, config.majorMode[name]?.layers ?? [], execution.selection.majorMode),\n value: name,\n })),\n });\n if (typeof selected !== 'string' || !selected) return;\n requested = selected;\n }\n // Reject invalid command input before requesting a capability transition.\n resolveLayers(config, requested);\n if (requested === execution.selection.majorMode) return;\n await host.changeSelection({ axis: 'majorMode', majorMode: requested });\n },\n };\n}\n","import { defineRoutedContribution } from '@agimon-ai/po-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/po-core/serverFacet';\n\nimport { createMajorModeServerCommand } from '../_lib/majorModeServerCommand';\nexport default defineRoutedContribution(\n ({ agent }: DoomServerPluginContext) => (agent ? createMajorModeServerCommand(agent) : undefined),\n { cardinality: 'optional' },\n);\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineResource({\n name: 'po-author-major-mode',\n description:\n \"Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.\",\n when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor' as const, mode: 'help' } },\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/po-author-major-mode/SKILL.md'),\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-author-major-mode/SKILL.md'),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\n\nimport commandMajorMode from '../src/extensions/workspaces/sessions/(backend)/command/majorMode.server';\nimport resourcePoAuthorMajorMode from '../src/extensions/workspaces/sessions/(backend)/resource/poAuthorMajorMode.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n name: '@agimon-ai/po-major-mode',\n session: (context) => ({\n get commands(): DoomServerSessionPlugin['commands'] { return defined([via({ name: 'major-mode' }, at(commandMajorMode, context))]); },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourcePoAuthorMajorMode, context)]; },\n }),\n});\n\nexport default facet;\n"],"mappings":";;;;;AAKA,SAAgB,6BAA6B,MAAoD;CAC/F,OAAO;EACL,MAAM;EACN,aAAa;EACb,MAAM,QAAQ,MAAM,WAAW;GAC7B,MAAM,SAAS,qBAAqB,UAAU,QAAQ;GACtD,IAAI,YAAY,KAAK,KAAK;GAC1B,IAAI,CAAC,WAAW;IACd,MAAM,WAAW,MAAM,UAAU,OAAO,QAAQ;KAC9C,MAAM;KACN,OAAO,wBAAwB,UAAU,UAAU,UAAU;KAC7D,SAAS,OAAO,KAAK,OAAO,SAAS,CAAC,CAAC,KAAK,UAAU;MACpD,OAAO,qBAAqB,MAAM,OAAO,UAAU,KAAK,EAAE,UAAU,CAAC,GAAG,UAAU,UAAU,SAAS;MACrG,OAAO;KACT,EAAE;IACJ,CAAC;IACD,IAAI,OAAO,aAAa,YAAY,CAAC,UAAU;IAC/C,YAAY;GACd;GAEA,cAAc,QAAQ,SAAS;GAC/B,IAAI,cAAc,UAAU,UAAU,WAAW;GACjD,MAAM,KAAK,gBAAgB;IAAE,MAAM;IAAa,WAAW;GAAU,CAAC;EACxE;CACF;AACF;;;AC1BA,IAAA,2BAAe,0BACZ,EAAE,YAAsC,QAAQ,6BAA6B,KAAK,IAAI,KAAA,GACvF,EAAE,aAAa,WAAW,CAC5B;;;ACJA,IAAA,mCAAe,eAAe;CAC5B,MAAM;CACN,aACE;CACF,MAAM;EAAE,OAAO,EAAE,cAAc,OAAO;EAAG,aAAa;GAAE,MAAM;GAAkB,MAAM;EAAO;CAAE;CAC/F,MAAM;CACN,MAAM,oBAAoB,YAAY,KAAK,2CAA2C;CACtF,YAAY,oBAAoB,YAAY,KAAK,2CAA2C;AAC9F,CAAC;;;ACJD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;;AAEpE,MAAM,WAAc,WAClB,OAAO,QAAQ,UAAsB,UAAU,KAAA,CAAS;AAC1D,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,QAAQ,mBAAmB;CACtC,MAAM;CACN,UAAU,aAAa;EACrB,IAAI,WAAgD;GAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,MAAM,aAAa,GAAG,GAAGA,0BAAkB,OAAO,CAAC,CAAC,CAAC;EAAG;EACpI,IAAI,YAAkD;GAAE,OAAO,CAAC,GAAGC,kCAA2B,OAAO,CAAC;EAAG;CAC3G;AACF,CAAC"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_majorModeText = require("./majorModeText-DCFGufYS.cjs");
|
|
3
|
+
//#region src/services/statusLine/index.ts
|
|
4
|
+
const STATUS_KEY = "doom-major-mode";
|
|
5
|
+
/** Compact footer text for the selected major mode, domains, and profile. */
|
|
6
|
+
function statusText(majorMode, domains, profile) {
|
|
7
|
+
return [
|
|
8
|
+
profile ? `*${profile}*` : void 0,
|
|
9
|
+
`[${majorMode}]`,
|
|
10
|
+
domains.join(",")
|
|
11
|
+
].filter((part) => Boolean(part)).join(":");
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/types/majorMode.ts
|
|
15
|
+
/** The npm name this package registers its voice tool and contributions under. */
|
|
16
|
+
const MAJOR_MODE_SOURCE = "@agimon-ai/po-major-mode";
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.MAJOR_MODE_COMMAND = require_majorModeText.MAJOR_MODE_COMMAND;
|
|
19
|
+
exports.MAJOR_MODE_SOURCE = MAJOR_MODE_SOURCE;
|
|
20
|
+
exports.STATUS_KEY = STATUS_KEY;
|
|
21
|
+
exports.applySummary = require_majorModeText.applySummary;
|
|
22
|
+
exports.majorModeItems = require_majorModeText.majorModeItems;
|
|
23
|
+
exports.majorModeOptionLabel = require_majorModeText.majorModeOptionLabel;
|
|
24
|
+
exports.majorModeSummary = require_majorModeText.majorModeSummary;
|
|
25
|
+
exports.optionName = require_majorModeText.optionName;
|
|
26
|
+
exports.statusText = statusText;
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/services/statusLine/index.ts","../src/types/majorMode.ts"],"sourcesContent":["export const STATUS_KEY = 'doom-major-mode';\n\n/** Compact footer text for the selected major mode, domains, and profile. */\nexport function statusText(majorMode: string, domains: readonly string[], profile?: string): string {\n return [profile ? `*${profile}*` : undefined, `[${majorMode}]`, domains.join(',')]\n .filter((part) => Boolean(part))\n .join(':');\n}\n","import type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\n\n/** The npm name this package registers its voice tool and contributions under. */\nexport const MAJOR_MODE_SOURCE = '@agimon-ai/po-major-mode';\n\n/** The selection as both the command and the voice tool need to see it. */\nexport interface MajorModeView {\n config: MajorModesConfig;\n majorMode: string;\n domains: readonly string[];\n profile?: string;\n}\n"],"mappings":";;;AAAA,MAAa,aAAa;;AAG1B,SAAgB,WAAW,WAAmB,SAA4B,SAA0B;CAClG,OAAO;EAAC,UAAU,IAAI,QAAQ,KAAK,KAAA;EAAW,IAAI,UAAU;EAAI,QAAQ,KAAK,GAAG;CAAC,CAAC,CAC/E,QAAQ,SAAS,QAAQ,IAAI,CAAC,CAAC,CAC/B,KAAK,GAAG;AACb;;;;ACJA,MAAa,oBAAoB"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { MajorModesConfig } from "@agimon-ai/po-config/majorModes";
|
|
2
|
+
import { TransitionExecutionStrategy } from "@agimon-ai/po-core/transition";
|
|
3
|
+
//#region src/services/majorModeText/index.d.ts
|
|
4
|
+
interface SelectItem {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const MAJOR_MODE_COMMAND = "mode";
|
|
10
|
+
/** Picker rows show the resolved layers while retaining bare major mode values. */
|
|
11
|
+
export declare function majorModeItems(config: MajorModesConfig, names: string[]): SelectItem[];
|
|
12
|
+
export declare function majorModeOptionLabel(name: string, layers: string[], current: string): string;
|
|
13
|
+
export declare function optionName(option: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* What a switch actually applied.
|
|
16
|
+
*
|
|
17
|
+
* A synced session composes its extension set on every load, so a reload picks
|
|
18
|
+
* up the new layers outright. A launcher session cannot: Pi freezes the CLI
|
|
19
|
+
* `--extension` list at construction, so a layer that contributes extensions
|
|
20
|
+
* needs a relaunch there and only the hooks change in place.
|
|
21
|
+
*/
|
|
22
|
+
export declare function applySummary(picked: string, layers: string[], stale: boolean, composed?: boolean, strategy?: TransitionExecutionStrategy, supervised?: boolean): string;
|
|
23
|
+
export declare function majorModeSummary(picked: string, layers: string[], current: string, composed?: boolean): string;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/services/statusLine/index.d.ts
|
|
26
|
+
export declare const STATUS_KEY = "doom-major-mode";
|
|
27
|
+
/** Compact footer text for the selected major mode, domains, and profile. */
|
|
28
|
+
export declare function statusText(majorMode: string, domains: readonly string[], profile?: string): string;
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/types/majorMode.d.ts
|
|
31
|
+
/** The npm name this package registers its voice tool and contributions under. */
|
|
32
|
+
export declare const MAJOR_MODE_SOURCE = "@agimon-ai/po-major-mode";
|
|
33
|
+
/** The selection as both the command and the voice tool need to see it. */
|
|
34
|
+
interface MajorModeView {
|
|
35
|
+
config: MajorModesConfig;
|
|
36
|
+
majorMode: string;
|
|
37
|
+
domains: readonly string[];
|
|
38
|
+
profile?: string;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export type { MajorModeView };
|
|
42
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/majorModeText/index.ts","../src/services/statusLine/index.ts","../src/types/majorMode.ts"],"mappings":";;;UASU;EACR;EACA;EACA;;qBAGW;;wBAGG,eAAe,QAAQ,kBAAkB,kBAAkB;wBAQ3D,qBAAqB,cAAc,kBAAkB;wBAIrD,WAAW;;;;;;;;;wBAYX,aACd,gBACA,kBACA,gBACA,oBACA,WAAW,6BACX;wBAqBc,iBAAiB,gBAAgB,kBAAkB,iBAAiB;;;qBCrEvE;;wBAGG,WAAW,mBAAmB,4BAA4B;;;;qBCA7D;;UAGI;EACf,QAAQ;EACR;EACA;EACA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { a as majorModeSummary, i as majorModeOptionLabel, n as applySummary, o as optionName, r as majorModeItems, t as MAJOR_MODE_COMMAND } from "./majorModeText-DuWMOhxX.mjs";
|
|
2
|
+
//#region src/services/statusLine/index.ts
|
|
3
|
+
const STATUS_KEY = "doom-major-mode";
|
|
4
|
+
/** Compact footer text for the selected major mode, domains, and profile. */
|
|
5
|
+
function statusText(majorMode, domains, profile) {
|
|
6
|
+
return [
|
|
7
|
+
profile ? `*${profile}*` : void 0,
|
|
8
|
+
`[${majorMode}]`,
|
|
9
|
+
domains.join(",")
|
|
10
|
+
].filter((part) => Boolean(part)).join(":");
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/types/majorMode.ts
|
|
14
|
+
/** The npm name this package registers its voice tool and contributions under. */
|
|
15
|
+
const MAJOR_MODE_SOURCE = "@agimon-ai/po-major-mode";
|
|
16
|
+
//#endregion
|
|
17
|
+
export { MAJOR_MODE_COMMAND, MAJOR_MODE_SOURCE, STATUS_KEY, applySummary, majorModeItems, majorModeOptionLabel, majorModeSummary, optionName, statusText };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/services/statusLine/index.ts","../src/types/majorMode.ts"],"sourcesContent":["export const STATUS_KEY = 'doom-major-mode';\n\n/** Compact footer text for the selected major mode, domains, and profile. */\nexport function statusText(majorMode: string, domains: readonly string[], profile?: string): string {\n return [profile ? `*${profile}*` : undefined, `[${majorMode}]`, domains.join(',')]\n .filter((part) => Boolean(part))\n .join(':');\n}\n","import type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\n\n/** The npm name this package registers its voice tool and contributions under. */\nexport const MAJOR_MODE_SOURCE = '@agimon-ai/po-major-mode';\n\n/** The selection as both the command and the voice tool need to see it. */\nexport interface MajorModeView {\n config: MajorModesConfig;\n majorMode: string;\n domains: readonly string[];\n profile?: string;\n}\n"],"mappings":";;AAAA,MAAa,aAAa;;AAG1B,SAAgB,WAAW,WAAmB,SAA4B,SAA0B;CAClG,OAAO;EAAC,UAAU,IAAI,QAAQ,KAAK,KAAA;EAAW,IAAI,UAAU;EAAI,QAAQ,KAAK,GAAG;CAAC,CAAC,CAC/E,QAAQ,SAAS,QAAQ,IAAI,CAAC,CAAC,CAC/B,KAAK,GAAG;AACb;;;;ACJA,MAAa,oBAAoB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
//#region src/services/majorModeText/index.ts
|
|
2
|
+
const OPTION_PREFIX = /^\[[ x]\] /;
|
|
3
|
+
const CORE_ONLY = "core only";
|
|
4
|
+
const MARK_ON = "[x]";
|
|
5
|
+
const MARK_OFF = "[ ]";
|
|
6
|
+
const RELAUNCH = "Relaunch with:";
|
|
7
|
+
const MAJOR_MODE_OPTION = "--major-mode";
|
|
8
|
+
const MAJOR_MODE_COMMAND = "mode";
|
|
9
|
+
/** Picker rows show the resolved layers while retaining bare major mode values. */
|
|
10
|
+
function majorModeItems(config, names) {
|
|
11
|
+
return names.map((name) => ({
|
|
12
|
+
value: name,
|
|
13
|
+
label: name,
|
|
14
|
+
description: config.majorMode[name]?.description ?? CORE_ONLY
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
function majorModeOptionLabel(name, layers, current) {
|
|
18
|
+
return `${name === current ? MARK_ON : MARK_OFF} ${name}: ${layers.join(", ") || CORE_ONLY}`;
|
|
19
|
+
}
|
|
20
|
+
function optionName(option) {
|
|
21
|
+
return option.replace(OPTION_PREFIX, "").split(":")[0] ?? option;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* What a switch actually applied.
|
|
25
|
+
*
|
|
26
|
+
* A synced session composes its extension set on every load, so a reload picks
|
|
27
|
+
* up the new layers outright. A launcher session cannot: Pi freezes the CLI
|
|
28
|
+
* `--extension` list at construction, so a layer that contributes extensions
|
|
29
|
+
* needs a relaunch there and only the hooks change in place.
|
|
30
|
+
*/
|
|
31
|
+
function applySummary(picked, layers, stale, composed = false, strategy, supervised = false) {
|
|
32
|
+
const head = `Switched to ${picked}: ${layers.join(", ") || CORE_ONLY}`;
|
|
33
|
+
if (strategy === "process-relaunch") {
|
|
34
|
+
if (supervised) return `Major mode ${picked} is pending; the supervisor is restarting the agent with it.`;
|
|
35
|
+
return [`Major mode ${picked} is pending; the current process remains active.`, ` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`].join("\n");
|
|
36
|
+
}
|
|
37
|
+
if (strategy === "pi-reload") return [head, "Pi reloaded."].join("\n");
|
|
38
|
+
if (!stale || composed) return [head, "Hooks reloaded."].join("\n");
|
|
39
|
+
return [
|
|
40
|
+
head,
|
|
41
|
+
"Hooks reloaded. Extensions are fixed at launch, so for those:",
|
|
42
|
+
` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`
|
|
43
|
+
].join("\n");
|
|
44
|
+
}
|
|
45
|
+
function majorModeSummary(picked, layers, current, composed = false) {
|
|
46
|
+
const contents = `Major mode ${picked}: ${layers.join(", ") || CORE_ONLY}`;
|
|
47
|
+
if (picked !== current && !composed) return [contents, `${RELAUNCH}\n ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`].join("\n");
|
|
48
|
+
if (picked !== current) return contents;
|
|
49
|
+
return [contents, "Already using this major mode."].join("\n");
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
Object.defineProperty(exports, "MAJOR_MODE_COMMAND", {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
get: function() {
|
|
55
|
+
return MAJOR_MODE_COMMAND;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
Object.defineProperty(exports, "applySummary", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
get: function() {
|
|
61
|
+
return applySummary;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(exports, "majorModeItems", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
get: function() {
|
|
67
|
+
return majorModeItems;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
Object.defineProperty(exports, "majorModeOptionLabel", {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
get: function() {
|
|
73
|
+
return majorModeOptionLabel;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(exports, "majorModeSummary", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function() {
|
|
79
|
+
return majorModeSummary;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
Object.defineProperty(exports, "optionName", {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
get: function() {
|
|
85
|
+
return optionName;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=majorModeText-DCFGufYS.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"majorModeText-DCFGufYS.cjs","names":[],"sources":["../src/services/majorModeText/index.ts"],"sourcesContent":["import type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport type { TransitionExecutionStrategy } from '@agimon-ai/po-core/transition';\n\nconst OPTION_PREFIX = /^\\[[ x]\\] /;\nconst CORE_ONLY = 'core only';\nconst MARK_ON = '[x]';\nconst MARK_OFF = '[ ]';\nconst RELAUNCH = 'Relaunch with:';\nconst MAJOR_MODE_OPTION = '--major-mode';\ninterface SelectItem {\n value: string;\n label: string;\n description?: string;\n}\n\nexport const MAJOR_MODE_COMMAND = 'mode';\n\n/** Picker rows show the resolved layers while retaining bare major mode values. */\nexport function majorModeItems(config: MajorModesConfig, names: string[]): SelectItem[] {\n return names.map((name) => ({\n value: name,\n label: name,\n description: config.majorMode[name]?.description ?? CORE_ONLY,\n }));\n}\n\nexport function majorModeOptionLabel(name: string, layers: string[], current: string): string {\n return `${name === current ? MARK_ON : MARK_OFF} ${name}: ${layers.join(', ') || CORE_ONLY}`;\n}\n\nexport function optionName(option: string): string {\n return option.replace(OPTION_PREFIX, '').split(':')[0] ?? option;\n}\n\n/**\n * What a switch actually applied.\n *\n * A synced session composes its extension set on every load, so a reload picks\n * up the new layers outright. A launcher session cannot: Pi freezes the CLI\n * `--extension` list at construction, so a layer that contributes extensions\n * needs a relaunch there and only the hooks change in place.\n */\nexport function applySummary(\n picked: string,\n layers: string[],\n stale: boolean,\n composed = false,\n strategy?: TransitionExecutionStrategy,\n supervised = false,\n): string {\n const head = `Switched to ${picked}: ${layers.join(', ') || CORE_ONLY}`;\n if (strategy === 'process-relaunch') {\n if (supervised) {\n return `Major mode ${picked} is pending; the supervisor is restarting the agent with it.`;\n }\n return [\n `Major mode ${picked} is pending; the current process remains active.`,\n ` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`,\n ].join('\\n');\n }\n if (strategy === 'pi-reload') return [head, 'Pi reloaded.'].join('\\n');\n if (!stale || composed) return [head, 'Hooks reloaded.'].join('\\n');\n return [\n head,\n 'Hooks reloaded. Extensions are fixed at launch, so for those:',\n ` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`,\n ].join('\\n');\n}\n\nexport function majorModeSummary(picked: string, layers: string[], current: string, composed = false): string {\n const contents = `Major mode ${picked}: ${layers.join(', ') || CORE_ONLY}`;\n if (picked !== current && !composed) {\n return [contents, `${RELAUNCH}\\n ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`].join('\\n');\n }\n if (picked !== current) return contents;\n return [contents, 'Already using this major mode.'].join('\\n');\n}\n\nexport function errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":";AAGA,MAAM,gBAAgB;AACtB,MAAM,YAAY;AAClB,MAAM,UAAU;AAChB,MAAM,WAAW;AACjB,MAAM,WAAW;AACjB,MAAM,oBAAoB;AAO1B,MAAa,qBAAqB;;AAGlC,SAAgB,eAAe,QAA0B,OAA+B;CACtF,OAAO,MAAM,KAAK,UAAU;EAC1B,OAAO;EACP,OAAO;EACP,aAAa,OAAO,UAAU,KAAK,EAAE,eAAe;CACtD,EAAE;AACJ;AAEA,SAAgB,qBAAqB,MAAc,QAAkB,SAAyB;CAC5F,OAAO,GAAG,SAAS,UAAU,UAAU,SAAS,GAAG,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK;AACnF;AAEA,SAAgB,WAAW,QAAwB;CACjD,OAAO,OAAO,QAAQ,eAAe,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;AAC5D;;;;;;;;;AAUA,SAAgB,aACd,QACA,QACA,OACA,WAAW,OACX,UACA,aAAa,OACL;CACR,MAAM,OAAO,eAAe,OAAO,IAAI,OAAO,KAAK,IAAI,KAAK;CAC5D,IAAI,aAAa,oBAAoB;EACnC,IAAI,YACF,OAAO,cAAc,OAAO;EAE9B,OAAO,CACL,cAAc,OAAO,mDACrB,aAAa,kBAAkB,GAAG,QACpC,CAAC,CAAC,KAAK,IAAI;CACb;CACA,IAAI,aAAa,aAAa,OAAO,CAAC,MAAM,cAAc,CAAC,CAAC,KAAK,IAAI;CACrE,IAAI,CAAC,SAAS,UAAU,OAAO,CAAC,MAAM,iBAAiB,CAAC,CAAC,KAAK,IAAI;CAClE,OAAO;EACL;EACA;EACA,aAAa,kBAAkB,GAAG;CACpC,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAgB,iBAAiB,QAAgB,QAAkB,SAAiB,WAAW,OAAe;CAC5G,MAAM,WAAW,cAAc,OAAO,IAAI,OAAO,KAAK,IAAI,KAAK;CAC/D,IAAI,WAAW,WAAW,CAAC,UACzB,OAAO,CAAC,UAAU,GAAG,SAAS,cAAc,kBAAkB,GAAG,QAAQ,CAAC,CAAC,KAAK,IAAI;CAEtF,IAAI,WAAW,SAAS,OAAO;CAC/B,OAAO,CAAC,UAAU,gCAAgC,CAAC,CAAC,KAAK,IAAI;AAC/D"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/services/majorModeText/index.ts
|
|
2
|
+
const OPTION_PREFIX = /^\[[ x]\] /;
|
|
3
|
+
const CORE_ONLY = "core only";
|
|
4
|
+
const MARK_ON = "[x]";
|
|
5
|
+
const MARK_OFF = "[ ]";
|
|
6
|
+
const RELAUNCH = "Relaunch with:";
|
|
7
|
+
const MAJOR_MODE_OPTION = "--major-mode";
|
|
8
|
+
const MAJOR_MODE_COMMAND = "mode";
|
|
9
|
+
/** Picker rows show the resolved layers while retaining bare major mode values. */
|
|
10
|
+
function majorModeItems(config, names) {
|
|
11
|
+
return names.map((name) => ({
|
|
12
|
+
value: name,
|
|
13
|
+
label: name,
|
|
14
|
+
description: config.majorMode[name]?.description ?? CORE_ONLY
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
function majorModeOptionLabel(name, layers, current) {
|
|
18
|
+
return `${name === current ? MARK_ON : MARK_OFF} ${name}: ${layers.join(", ") || CORE_ONLY}`;
|
|
19
|
+
}
|
|
20
|
+
function optionName(option) {
|
|
21
|
+
return option.replace(OPTION_PREFIX, "").split(":")[0] ?? option;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* What a switch actually applied.
|
|
25
|
+
*
|
|
26
|
+
* A synced session composes its extension set on every load, so a reload picks
|
|
27
|
+
* up the new layers outright. A launcher session cannot: Pi freezes the CLI
|
|
28
|
+
* `--extension` list at construction, so a layer that contributes extensions
|
|
29
|
+
* needs a relaunch there and only the hooks change in place.
|
|
30
|
+
*/
|
|
31
|
+
function applySummary(picked, layers, stale, composed = false, strategy, supervised = false) {
|
|
32
|
+
const head = `Switched to ${picked}: ${layers.join(", ") || CORE_ONLY}`;
|
|
33
|
+
if (strategy === "process-relaunch") {
|
|
34
|
+
if (supervised) return `Major mode ${picked} is pending; the supervisor is restarting the agent with it.`;
|
|
35
|
+
return [`Major mode ${picked} is pending; the current process remains active.`, ` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`].join("\n");
|
|
36
|
+
}
|
|
37
|
+
if (strategy === "pi-reload") return [head, "Pi reloaded."].join("\n");
|
|
38
|
+
if (!stale || composed) return [head, "Hooks reloaded."].join("\n");
|
|
39
|
+
return [
|
|
40
|
+
head,
|
|
41
|
+
"Hooks reloaded. Extensions are fixed at launch, so for those:",
|
|
42
|
+
` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`
|
|
43
|
+
].join("\n");
|
|
44
|
+
}
|
|
45
|
+
function majorModeSummary(picked, layers, current, composed = false) {
|
|
46
|
+
const contents = `Major mode ${picked}: ${layers.join(", ") || CORE_ONLY}`;
|
|
47
|
+
if (picked !== current && !composed) return [contents, `${RELAUNCH}\n ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`].join("\n");
|
|
48
|
+
if (picked !== current) return contents;
|
|
49
|
+
return [contents, "Already using this major mode."].join("\n");
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { majorModeSummary as a, majorModeOptionLabel as i, applySummary as n, optionName as o, majorModeItems as r, MAJOR_MODE_COMMAND as t };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=majorModeText-DuWMOhxX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"majorModeText-DuWMOhxX.mjs","names":[],"sources":["../src/services/majorModeText/index.ts"],"sourcesContent":["import type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport type { TransitionExecutionStrategy } from '@agimon-ai/po-core/transition';\n\nconst OPTION_PREFIX = /^\\[[ x]\\] /;\nconst CORE_ONLY = 'core only';\nconst MARK_ON = '[x]';\nconst MARK_OFF = '[ ]';\nconst RELAUNCH = 'Relaunch with:';\nconst MAJOR_MODE_OPTION = '--major-mode';\ninterface SelectItem {\n value: string;\n label: string;\n description?: string;\n}\n\nexport const MAJOR_MODE_COMMAND = 'mode';\n\n/** Picker rows show the resolved layers while retaining bare major mode values. */\nexport function majorModeItems(config: MajorModesConfig, names: string[]): SelectItem[] {\n return names.map((name) => ({\n value: name,\n label: name,\n description: config.majorMode[name]?.description ?? CORE_ONLY,\n }));\n}\n\nexport function majorModeOptionLabel(name: string, layers: string[], current: string): string {\n return `${name === current ? MARK_ON : MARK_OFF} ${name}: ${layers.join(', ') || CORE_ONLY}`;\n}\n\nexport function optionName(option: string): string {\n return option.replace(OPTION_PREFIX, '').split(':')[0] ?? option;\n}\n\n/**\n * What a switch actually applied.\n *\n * A synced session composes its extension set on every load, so a reload picks\n * up the new layers outright. A launcher session cannot: Pi freezes the CLI\n * `--extension` list at construction, so a layer that contributes extensions\n * needs a relaunch there and only the hooks change in place.\n */\nexport function applySummary(\n picked: string,\n layers: string[],\n stale: boolean,\n composed = false,\n strategy?: TransitionExecutionStrategy,\n supervised = false,\n): string {\n const head = `Switched to ${picked}: ${layers.join(', ') || CORE_ONLY}`;\n if (strategy === 'process-relaunch') {\n if (supervised) {\n return `Major mode ${picked} is pending; the supervisor is restarting the agent with it.`;\n }\n return [\n `Major mode ${picked} is pending; the current process remains active.`,\n ` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`,\n ].join('\\n');\n }\n if (strategy === 'pi-reload') return [head, 'Pi reloaded.'].join('\\n');\n if (!stale || composed) return [head, 'Hooks reloaded.'].join('\\n');\n return [\n head,\n 'Hooks reloaded. Extensions are fixed at launch, so for those:',\n ` ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`,\n ].join('\\n');\n}\n\nexport function majorModeSummary(picked: string, layers: string[], current: string, composed = false): string {\n const contents = `Major mode ${picked}: ${layers.join(', ') || CORE_ONLY}`;\n if (picked !== current && !composed) {\n return [contents, `${RELAUNCH}\\n ./pi.sh ${MAJOR_MODE_OPTION} ${picked}`].join('\\n');\n }\n if (picked !== current) return contents;\n return [contents, 'Already using this major mode.'].join('\\n');\n}\n\nexport function errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":";AAGA,MAAM,gBAAgB;AACtB,MAAM,YAAY;AAClB,MAAM,UAAU;AAChB,MAAM,WAAW;AACjB,MAAM,WAAW;AACjB,MAAM,oBAAoB;AAO1B,MAAa,qBAAqB;;AAGlC,SAAgB,eAAe,QAA0B,OAA+B;CACtF,OAAO,MAAM,KAAK,UAAU;EAC1B,OAAO;EACP,OAAO;EACP,aAAa,OAAO,UAAU,KAAK,EAAE,eAAe;CACtD,EAAE;AACJ;AAEA,SAAgB,qBAAqB,MAAc,QAAkB,SAAyB;CAC5F,OAAO,GAAG,SAAS,UAAU,UAAU,SAAS,GAAG,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK;AACnF;AAEA,SAAgB,WAAW,QAAwB;CACjD,OAAO,OAAO,QAAQ,eAAe,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;AAC5D;;;;;;;;;AAUA,SAAgB,aACd,QACA,QACA,OACA,WAAW,OACX,UACA,aAAa,OACL;CACR,MAAM,OAAO,eAAe,OAAO,IAAI,OAAO,KAAK,IAAI,KAAK;CAC5D,IAAI,aAAa,oBAAoB;EACnC,IAAI,YACF,OAAO,cAAc,OAAO;EAE9B,OAAO,CACL,cAAc,OAAO,mDACrB,aAAa,kBAAkB,GAAG,QACpC,CAAC,CAAC,KAAK,IAAI;CACb;CACA,IAAI,aAAa,aAAa,OAAO,CAAC,MAAM,cAAc,CAAC,CAAC,KAAK,IAAI;CACrE,IAAI,CAAC,SAAS,UAAU,OAAO,CAAC,MAAM,iBAAiB,CAAC,CAAC,KAAK,IAAI;CAClE,OAAO;EACL;EACA;EACA,aAAa,kBAAkB,GAAG;CACpC,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAgB,iBAAiB,QAAgB,QAAkB,SAAiB,WAAW,OAAe;CAC5G,MAAM,WAAW,cAAc,OAAO,IAAI,OAAO,KAAK,IAAI,KAAK;CAC/D,IAAI,WAAW,WAAW,CAAC,UACzB,OAAO,CAAC,UAAU,GAAG,SAAS,cAAc,kBAAkB,GAAG,QAAQ,CAAC,CAAC,KAAK,IAAI;CAEtF,IAAI,WAAW,SAAS,OAAO;CAC/B,OAAO,CAAC,UAAU,gCAAgC,CAAC,CAAC,KAAK,IAAI;AAC/D"}
|
package/llms.txt
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Doom Pi Major Mode
|
|
2
|
+
|
|
3
|
+
Named major-mode selection for Doom Pi sessions.
|
|
4
|
+
|
|
5
|
+
## How to author
|
|
6
|
+
|
|
7
|
+
- [Author Po major modes](./src/prompts/po-author-major-mode/SKILL.md): Edit `modes.yaml` safely.
|
|
8
|
+
- [`modes.yaml` authoring contract](./src/prompts/po-author-major-mode/references/modes-contract.md): Source precedence, schema, resolution, and verification details.
|
|
9
|
+
|
|
10
|
+
## Package reference
|
|
11
|
+
|
|
12
|
+
- [Package README](./README.md): The `/mode` command, the `major_mode` voice tool, and how a mode resolves to layers.
|
package/package.json
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agimon-ai/po-major-mode",
|
|
3
|
+
"version": "0.0.0-alpha.0",
|
|
4
|
+
"description": "Named major-mode selection and layer composition switching for Po sessions.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"coding-agent",
|
|
8
|
+
"developer-tools",
|
|
9
|
+
"layer-composition",
|
|
10
|
+
"major-mode",
|
|
11
|
+
"pi-coding-agent",
|
|
12
|
+
"pi-extension",
|
|
13
|
+
"pi-package",
|
|
14
|
+
"po",
|
|
15
|
+
"session-reload"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://agimon.ai",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/AgiFlow/po/issues"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": "Vuong Ngo",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/AgiFlow/po.git",
|
|
26
|
+
"directory": "packages/foundations/po-major-mode"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"llms.txt",
|
|
31
|
+
"src/prompts",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"package.json"
|
|
35
|
+
],
|
|
36
|
+
"type": "module",
|
|
37
|
+
"main": "./dist/index.cjs",
|
|
38
|
+
"module": "./dist/index.mjs",
|
|
39
|
+
"types": "./dist/index.d.mts",
|
|
40
|
+
"jsnext:main": "./dist/index.mjs",
|
|
41
|
+
"exports": {
|
|
42
|
+
".": {
|
|
43
|
+
"types": "./dist/index.d.mts",
|
|
44
|
+
"import": "./dist/index.mjs",
|
|
45
|
+
"require": "./dist/index.cjs"
|
|
46
|
+
},
|
|
47
|
+
"./apiContracts": {
|
|
48
|
+
"types": "./dist/apiContracts.d.mts",
|
|
49
|
+
"import": "./dist/apiContracts.mjs",
|
|
50
|
+
"require": "./dist/apiContracts.cjs"
|
|
51
|
+
},
|
|
52
|
+
"./extensions/server": {
|
|
53
|
+
"types": "./dist/extensions/server.d.mts",
|
|
54
|
+
"import": "./dist/extensions/server.mjs",
|
|
55
|
+
"require": "./dist/extensions/server.cjs"
|
|
56
|
+
},
|
|
57
|
+
"./package.json": "./package.json"
|
|
58
|
+
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@agimon-ai/po-config": "0.0.0-alpha.0",
|
|
64
|
+
"@agimon-ai/po-core": "0.0.0-alpha.0",
|
|
65
|
+
"@agimon-ai/po-minor-mode": "0.0.0-alpha.0",
|
|
66
|
+
"@agimon-ai/po-telemetry": "0.0.0-alpha.0",
|
|
67
|
+
"@deepseek-ai/cordis": "4.0.4",
|
|
68
|
+
"typebox": "1.3.34"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@agimon-ai/po-build": "0.0.0-alpha.0",
|
|
72
|
+
"@agimon-ai/po-voice": "0.0.0-alpha.0",
|
|
73
|
+
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.0-alpha.0",
|
|
74
|
+
"@deepseek-ai/cordis": "4.0.4",
|
|
75
|
+
"@earendil-works/pi-coding-agent": "1.0.2",
|
|
76
|
+
"@types/node": "26.6.4",
|
|
77
|
+
"@vitest/coverage-v8": "5.0.3",
|
|
78
|
+
"tsdown": "0.23.0",
|
|
79
|
+
"typescript": "7.0.2",
|
|
80
|
+
"vitest": "5.0.3"
|
|
81
|
+
},
|
|
82
|
+
"peerDependencies": {
|
|
83
|
+
"@earendil-works/pi-coding-agent": "1.0.2"
|
|
84
|
+
},
|
|
85
|
+
"peerDependenciesMeta": {
|
|
86
|
+
"@earendil-works/pi-coding-agent": {
|
|
87
|
+
"optional": true
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"engines": {
|
|
91
|
+
"node": ">=24"
|
|
92
|
+
},
|
|
93
|
+
"poMcp": {
|
|
94
|
+
"entry": "./generated/mcp.ts",
|
|
95
|
+
"dist": "./dist/extensions/mcp.mjs",
|
|
96
|
+
"scopes": [
|
|
97
|
+
"session"
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"poServer": {
|
|
101
|
+
"entry": "./generated/server.ts",
|
|
102
|
+
"dist": "./dist/extensions/server.mjs",
|
|
103
|
+
"scopes": [
|
|
104
|
+
"session"
|
|
105
|
+
],
|
|
106
|
+
"contracts": {
|
|
107
|
+
"entry": "./src/exports/apiContracts.ts",
|
|
108
|
+
"dist": "./dist/apiContracts.mjs"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"scripts": {
|
|
112
|
+
"build": "tsdown && pnpm build:mcp",
|
|
113
|
+
"build:mcp": "tsdown --config tsdown.mcp.config.ts",
|
|
114
|
+
"test": "vitest --run",
|
|
115
|
+
"typecheck": "tsc --noEmit",
|
|
116
|
+
"lint": "oxlint . && oxfmt . --check",
|
|
117
|
+
"fixcode": "oxlint . --fix && oxfmt ."
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: po-author-major-mode
|
|
3
|
+
description: Configure Po default packages, layers, extensions, hook groups, and named major modes. Use when creating or editing ~/.po/modes.yaml or a repository's .po/modes.yaml, choosing a default mode, or diagnosing which behavior a mode activates.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Author Po major modes
|
|
7
|
+
|
|
8
|
+
Use `modes.yaml` only for runtime composition. Major modes choose ordered layers, and layers choose
|
|
9
|
+
Pi extensions, extension packages, and hook groups. Domains configure plugin content and MCP access;
|
|
10
|
+
profiles configure personas and environment defaults.
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
1. Read both `~/.po/modes.yaml` and the repository's `.po/modes.yaml` when they exist.
|
|
15
|
+
2. Decide whether the change belongs in the personal defaults or only in the current repository.
|
|
16
|
+
3. Preserve unrelated definitions and authored array order.
|
|
17
|
+
4. Put unconditional packages in `default.packages`, reusable behavior in `layers`, and selections
|
|
18
|
+
under `majorMode`.
|
|
19
|
+
5. Write new modes as mappings with a useful `description` and an ordered `layers` array.
|
|
20
|
+
6. Put package-owned settings under that package's `config` mapping. Do not add layer-level `config`
|
|
21
|
+
or the removed `targets` field.
|
|
22
|
+
7. Check the result with `po --major-mode <name> --explain`. Use `po sync --check` when the
|
|
23
|
+
change affects installed packages or the synchronized matrix.
|
|
24
|
+
|
|
25
|
+
Relative local paths resolve from the repository root for repository configuration and from
|
|
26
|
+
`~/.po` for personal configuration. A repository definition replaces a personal definition
|
|
27
|
+
of the same name as a whole value, so never assume nested fields merge.
|
|
28
|
+
|
|
29
|
+
Read [references/modes-contract.md](references/modes-contract.md) before editing package entries,
|
|
30
|
+
local extension paths, hook-only layers, inherited definitions, or tombstones.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Po `modes.yaml` authoring contract
|
|
2
|
+
|
|
3
|
+
## Purpose and sources
|
|
4
|
+
|
|
5
|
+
`modes.yaml` controls the behavior axis of a Po session:
|
|
6
|
+
|
|
7
|
+
- `default.packages` is the unconditional package baseline.
|
|
8
|
+
- `layers` are reusable ordered bundles of extensions, packages, and hook groups.
|
|
9
|
+
- `majorMode` maps a session mode to an ordered list of layer names.
|
|
10
|
+
- `defaultMajorMode` selects the starting mode when no flag or inherited environment value wins.
|
|
11
|
+
|
|
12
|
+
Po reads `~/.po/modes.yaml` first and `<repoRoot>/.po/modes.yaml` second. Either file may
|
|
13
|
+
stand alone. A missing or empty file contributes nothing.
|
|
14
|
+
|
|
15
|
+
Named `layers` and `majorMode` entries merge by name. A repository entry replaces the complete
|
|
16
|
+
personal entry with the same name. Setting an inherited layer or mode to `null` removes it. The
|
|
17
|
+
top-level `default` block is also replaced as a whole when the repository declares it. An omitted
|
|
18
|
+
repository `default` keeps the personal definition. `defaultMajorMode` uses the last declared value.
|
|
19
|
+
|
|
20
|
+
Relative paths retain the source that declared them:
|
|
21
|
+
|
|
22
|
+
- Personal paths resolve from `~/.po`.
|
|
23
|
+
- Repository paths resolve from the repository root, not from `<repoRoot>/.po`.
|
|
24
|
+
|
|
25
|
+
## Supported shape
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
# Optional package baseline loaded before every selected named layer.
|
|
29
|
+
default:
|
|
30
|
+
packages:
|
|
31
|
+
- '@agimon-ai/po-help'
|
|
32
|
+
- name: '@scope/optional-extension'
|
|
33
|
+
optional: true
|
|
34
|
+
config:
|
|
35
|
+
policy: concise
|
|
36
|
+
|
|
37
|
+
layers:
|
|
38
|
+
local-review:
|
|
39
|
+
extensions:
|
|
40
|
+
- './extensions/review.ts'
|
|
41
|
+
packages:
|
|
42
|
+
- '@scope/review-extension'
|
|
43
|
+
hookGroups: [repository]
|
|
44
|
+
team:
|
|
45
|
+
packages:
|
|
46
|
+
- name: '@agimon-ai/po-team'
|
|
47
|
+
config:
|
|
48
|
+
models:
|
|
49
|
+
- model: provider/model-id
|
|
50
|
+
thinking: high
|
|
51
|
+
|
|
52
|
+
defaultMajorMode: copilot
|
|
53
|
+
majorMode:
|
|
54
|
+
minimal:
|
|
55
|
+
description: Small sessions with delegation only.
|
|
56
|
+
layers: [team]
|
|
57
|
+
copilot:
|
|
58
|
+
description: General coding with delegation and local review policy.
|
|
59
|
+
layers: [team, local-review]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Treat the `default` example as a shape, not as the current distribution package list. Preserve the
|
|
63
|
+
baseline emitted by `po init` unless the user explicitly wants to replace it. If neither source
|
|
64
|
+
declares `default`, Po adds no fallback feature package set. `default.packages: []` deliberately
|
|
65
|
+
selects an empty baseline. Fixed core packages remain active independently.
|
|
66
|
+
|
|
67
|
+
### `default`
|
|
68
|
+
|
|
69
|
+
`default` accepts exactly one field, `packages`, and `packages` must be an array. It does not accept
|
|
70
|
+
`extensions` or `hookGroups`. Its packages activate before packages from selected named layers.
|
|
71
|
+
|
|
72
|
+
### `layers`
|
|
73
|
+
|
|
74
|
+
Each layer is a mapping with these supported fields:
|
|
75
|
+
|
|
76
|
+
- `extensions`: an array of non-empty strings. A bare name selects a Po built-in extension.
|
|
77
|
+
A `./` or `../` path, or an absolute path, selects a Pi-compatible script or extension directory.
|
|
78
|
+
- `packages`: an array of package strings or package mappings. A normal npm package activates its
|
|
79
|
+
ordered `package.json` `pi.extensions` entries. An exported subpath can select one adapter.
|
|
80
|
+
Path-like packages are supported for local unpublished Pi packages.
|
|
81
|
+
- `hookGroups`: an array of hook group IDs contributed by the layer. Duplicate group IDs are
|
|
82
|
+
removed while retaining first-seen order.
|
|
83
|
+
|
|
84
|
+
A package mapping accepts only:
|
|
85
|
+
|
|
86
|
+
- `name`: required non-empty package specifier or local path.
|
|
87
|
+
- `optional`: optional boolean. A missing optional package is skipped and is not installed.
|
|
88
|
+
- `config`: optional mapping owned and interpreted by that package. Its contents stay opaque to the
|
|
89
|
+
major-mode parser.
|
|
90
|
+
|
|
91
|
+
Required npm packages missing from the active baseline or selected layers can be installed during
|
|
92
|
+
launch. `po sync` considers required packages from the baseline and every declared layer.
|
|
93
|
+
Optional packages and local paths are not installed automatically.
|
|
94
|
+
|
|
95
|
+
Package configuration belongs inside its package mapping. Layer-level `config` is rejected because
|
|
96
|
+
there is no unambiguous owner. The removed `targets` field is also rejected. Select a layer by naming
|
|
97
|
+
it from the appropriate major modes.
|
|
98
|
+
|
|
99
|
+
When hooks are disabled for a run, any selected layer with one or more `hookGroups` is suppressed as
|
|
100
|
+
a whole. Its extension and package entries are suppressed too. Keep unrelated packages out of a
|
|
101
|
+
hook-only layer if they must remain active when hooks are off.
|
|
102
|
+
|
|
103
|
+
### `majorMode` and `defaultMajorMode`
|
|
104
|
+
|
|
105
|
+
New major modes use this mapping form:
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
majorMode:
|
|
109
|
+
review:
|
|
110
|
+
description: Focused review with repository policy and Team delegation.
|
|
111
|
+
layers: [team, local-review]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`description` must be a non-empty string and `layers` must be an array of non-empty layer names.
|
|
115
|
+
Every referenced layer must survive source merging. Layer order and repeated entries are preserved.
|
|
116
|
+
The array-only compatibility form, such as `review: [team, local-review]`, is accepted and receives a
|
|
117
|
+
generated description, but new configuration should use the mapping form.
|
|
118
|
+
|
|
119
|
+
When `defaultMajorMode` is explicitly configured, it must name a surviving mode. If no source
|
|
120
|
+
declares it, Po uses the compatible `copilot` fallback. Declare an explicit default when the
|
|
121
|
+
available modes do not include `copilot`.
|
|
122
|
+
|
|
123
|
+
## Safe changes
|
|
124
|
+
|
|
125
|
+
- Add a package to an existing layer when it should follow that layer's activation and ownership.
|
|
126
|
+
- Add a new layer when the behavior should be reusable across multiple modes or independently
|
|
127
|
+
ordered.
|
|
128
|
+
- Add a new mode by composing existing layers, then add new layers only for missing behavior.
|
|
129
|
+
- Use a repository replacement when a shared personal definition is unsuitable for one repository.
|
|
130
|
+
- Use `null` only to remove an inherited named layer or named mode. Do not use it as a package entry
|
|
131
|
+
or as a partial-field deletion mechanism.
|
|
132
|
+
- Keep local paths within trusted, reviewable locations and confirm they resolve from the declaring
|
|
133
|
+
source's base directory.
|
|
134
|
+
|
|
135
|
+
## Verification
|
|
136
|
+
|
|
137
|
+
Run a read-only resolution before launching:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
po --major-mode review --explain
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Confirm the reported major mode, ordered layers, hook groups, and resulting resources. If packages
|
|
144
|
+
or synchronized composition changed, check drift and missing packages without updating artifacts:
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
po sync --check
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Run `po sync` only when the user intends to install packages or refresh synchronized artifacts.
|
|
151
|
+
For repository changes to the parser or templates themselves, run the affected Doom Config and
|
|
152
|
+
Po lint, typecheck, build, and test targets.
|