oris-skills 2.2.1 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +4 -3
- package/docs/adr/README.md +5 -0
- package/docs/distribution.md +1 -2
- package/docs/user-guide.md +1 -1
- package/package.json +1 -1
- package/references/conventions.md +27 -6
- package/references/devops.md +58 -0
- package/references/devops.schema.json +54 -0
- package/references/doc-policy.md +1 -1
- package/references/loop-adapter.schema.json +1 -34
- package/references/repo-map.md +2 -4
- package/references/repo-map.schema.json +0 -26
- package/references/settings.md +8 -20
- package/references/settings.schema.json +30 -80
- package/scripts/flow/oris-flow-devops.mjs +77 -0
- package/scripts/flow/oris-flow-layout.mjs +1 -1
- package/scripts/flow/oris-flow-scan.mjs +3 -9
- package/scripts/install/install-user-skills.mjs +39 -28
- package/scripts/install/oris-mcp.mjs +68 -0
- package/scripts/loop/oris-loop-bootstrap.mjs +0 -5
- package/scripts/loop/oris-loop-chat.mjs +0 -30
- package/scripts/tests/run-all-tests.mjs +3 -0
- package/scripts/tests/test-install-mcp.mjs +66 -0
- package/scripts/tests/test-oris-flow-devops.mjs +64 -0
- package/scripts/tests/test-oris-loop-smoke.mjs +1 -44
- package/scripts/tests/test-schemas.mjs +9 -8
- package/scripts/tests/test-skill-self-contained.mjs +66 -0
- package/skills/oris-flow/SKILL.md +10 -2
- package/skills/oris-flow/references/commit.md +45 -0
- package/skills/oris-flow/references/help.md +1 -1
- package/skills/oris-flow/references/pr.md +44 -0
- package/skills/oris-flow/references/setup.md +12 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- **Settings are per-project and tiny**: moved out of the user-global `~/.oris/settings.json` into `.oris-flow/settings.json`, holding only `orisFlow.responseStyle` (`standard`/`caveman`) and `orisFlow.artifactLanguage` (document language, default `en`). The installer no longer creates a settings file.
|
|
6
|
+
- **Test profiles removed**: the whole profile/secret subsystem is gone — `defaultProfiles`, `profiles`, the adapter `profile` block and its env mappings, and the loop's profile-gating. Every project drives its own e2e/CI tooling; Oris stores no credentials.
|
|
7
|
+
- **No UI-language setting**: chat, menus, and question labels follow the language the user writes (deduced from context); only generated documents use `artifactLanguage`.
|
|
8
|
+
- **No refresh-policy setting**: map freshness is answered by the `headSha` anchor (`flow scan --check`); the advisory `refreshPolicy` field was dropped from the manifest and schema.
|
|
9
|
+
- **Questions & subagents fire reliably**: conventions now bind a platform question call (Claude `AskUserQuestion`) as a tool call rather than optional chat text, and treat entering an Oris route as the explicit request to spawn scan subagents — so gates open their UI and setup fans out by default.
|
|
10
|
+
|
|
3
11
|
## 2.2.1 - 2026-07-07
|
|
4
12
|
|
|
5
13
|
- **Loop roles are invisible to users**: the installer no longer writes `oris-loop-{executor,verifier,doctor,debriefer}` into `~/.cursor/agents/`, `~/.claude/agents/`, or `~/.codex/agents/` — they showed up as manually invocable subagents, but the loop orchestrator never spawns them by name (it passes each loop's `prompts/<role>.md` to a generic subagent). `agents/` stays in the repo as the canonical role definitions for development. Uninstall (and therefore reinstall/upgrade) now also removes adapters left behind by earlier versions.
|
package/README.md
CHANGED
|
@@ -91,9 +91,10 @@ Stop anything, anytime: `npx oris-skills loop chat --action stop`.
|
|
|
91
91
|
|
|
92
92
|
## Tuning
|
|
93
93
|
|
|
94
|
-
Settings live in
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
Settings live in `.oris-flow/settings.json` (`/oris-flow` → Setup): document language
|
|
95
|
+
(`artifactLanguage`, default `en`) and `responseStyle` (`standard`/`caveman`, where
|
|
96
|
+
caveman shrinks chat to maximum token density while documents and safety gates stay
|
|
97
|
+
complete). Chat language is deduced from your messages, not configured.
|
|
97
98
|
|
|
98
99
|
## Repository layout
|
|
99
100
|
|
package/docs/distribution.md
CHANGED
|
@@ -14,13 +14,12 @@ The installer detects Cursor / Claude Code / Codex from `~/.cursor`, `~/.claude`
|
|
|
14
14
|
|
|
15
15
|
```text
|
|
16
16
|
~/.oris/oris-skills/ bundle: scripts, skills, references, agents, docs
|
|
17
|
-
~/.oris/settings.json user settings (created only if missing)
|
|
18
17
|
~/.cursor/skills/<name>/ Cursor skills (marker-managed)
|
|
19
18
|
~/.claude/skills/<name>/ Claude Code skills (marker-managed)
|
|
20
19
|
~/.codex/prompts/<name>.md Codex prompts pointing to the bundled SKILL.md
|
|
21
20
|
```
|
|
22
21
|
|
|
23
|
-
Project assets live only in each repository's `.oris-flow/` (adapter, loops, runtime) plus thin hook wrappers in `.cursor/hooks/` and `.claude/hooks/` written by `npx oris-skills loop bootstrap`.
|
|
22
|
+
Project assets live only in each repository's `.oris-flow/` (adapter, settings, loops, runtime) plus thin hook wrappers in `.cursor/hooks/` and `.claude/hooks/` written by `npx oris-skills loop bootstrap`.
|
|
24
23
|
|
|
25
24
|
## Uninstall / reinstall
|
|
26
25
|
|
package/docs/user-guide.md
CHANGED
|
@@ -42,4 +42,4 @@ npx oris-skills reinstall
|
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Uninstall removes only Oris-owned paths (including legacy locations); preview with `--dry-run`.
|
|
45
|
-
Settings (
|
|
45
|
+
Settings (`artifactLanguage` for document language, `responseStyle: caveman` for ultra-short chat): `.oris-flow/settings.json`, edited via `/oris-flow` → Setup. Chat language is deduced from context, not configured.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oris-skills",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "Oris Skills: one entry point (/oris-flow), guided discovery-to-implementation flow, and self-tuning verified loops for Cursor, Claude Code, and Codex.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Davide Baldassarre",
|
|
@@ -26,9 +26,18 @@ The `oris-skills` CLI is NOT installed globally. ALWAYS invoke it as `npx oris-s
|
|
|
26
26
|
|
|
27
27
|
## Questions
|
|
28
28
|
|
|
29
|
-
- ASK
|
|
29
|
+
- ASK through the platform's question tool — Claude `AskUserQuestion`, Cursor `AskQuestion`
|
|
30
|
+
(Plan Mode). A question turn = ONE call to it. Chat text is a fallback, NOT a choice: use
|
|
31
|
+
it ONLY when no such tool is available (e.g. Cursor Agent Mode) or the question cannot fit
|
|
32
|
+
the tool's schema (open-ended, or more options than it allows) — then present the options
|
|
33
|
+
as a lettered list.
|
|
34
|
+
- Oris gates and interview questions ALWAYS qualify for the tool: the answer decides the
|
|
35
|
+
next step. NEVER skip the tool because an answer "looks like a sensible default".
|
|
36
|
+
- FIT the schema: question tools cap the options (typically 4, meta-options included).
|
|
37
|
+
MORE options → split into a two-level question (category first) or use the deliberate
|
|
38
|
+
text fallback above.
|
|
30
39
|
- ONE question per turn. Recommended answer FIRST.
|
|
31
|
-
- ALWAYS include,
|
|
40
|
+
- ALWAYS include, in the user's language:
|
|
32
41
|
- `Explain the options` / `Spiega le opzioni` — explain, then re-ask the same question.
|
|
33
42
|
- During interviews: `Enough questions — proceed` / `Basta domande — procedi` (early exit → go to the generation gate; NOT approval to write).
|
|
34
43
|
- NEVER ask what the workspace, docs, code, or setup map already answer. Explore first.
|
|
@@ -41,12 +50,18 @@ The `oris-skills` CLI is NOT installed globally. ALWAYS invoke it as `npx oris-s
|
|
|
41
50
|
|
|
42
51
|
## Language
|
|
43
52
|
|
|
44
|
-
-
|
|
45
|
-
|
|
53
|
+
- CHAT, menus, and question labels: the language the user writes — DEDUCED from context,
|
|
54
|
+
no setting. NEVER ask which language to use when the conversation already shows it.
|
|
55
|
+
- GENERATED documents: `orisFlow.artifactLanguage` from `.oris-flow/settings.json`
|
|
56
|
+
(default `en`).
|
|
57
|
+
- Skill instructions and code stay English.
|
|
58
|
+
- COMMIT messages and PULL REQUEST titles/descriptions: ALWAYS English, whatever the chat
|
|
59
|
+
language or `artifactLanguage`. Work-item references follow the DevOps provider's
|
|
60
|
+
`workItemSyntax` (`references/devops.md`).
|
|
46
61
|
|
|
47
62
|
## Response style
|
|
48
63
|
|
|
49
|
-
READ `orisFlow.responseStyle` (`standard` | `caveman`, default `standard`).
|
|
64
|
+
READ `orisFlow.responseStyle` from `.oris-flow/settings.json` (`standard` | `caveman`, default `standard`).
|
|
50
65
|
|
|
51
66
|
`caveman` = the user pays per token; chat goes maximum density. The contract, in its own voice:
|
|
52
67
|
|
|
@@ -75,5 +90,11 @@ labels, receipts, error reports, and anything another session must read cold.
|
|
|
75
90
|
|
|
76
91
|
## Subagents
|
|
77
92
|
|
|
78
|
-
- USE parallel subagents for independent scans when the platform
|
|
93
|
+
- USE parallel subagents for independent scans when the platform's agent tool is in the
|
|
94
|
+
tool list (Claude `Agent` tool — formerly Task; Cursor subagents).
|
|
95
|
+
- The user invoking an Oris route IS the explicit request to spawn: when a route step
|
|
96
|
+
names subagent scans, platform guidance like "only spawn when the user asks" is
|
|
97
|
+
satisfied — do not skip on that ground.
|
|
98
|
+
- WHEN the platform has no agent tool (or spawning is blocked) → run the same scans
|
|
99
|
+
inline, sequentially, same coverage. Coverage never shrinks; only parallelism does.
|
|
79
100
|
- KEEP subagent output compact: summaries and pointers, not raw logs.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Oris DevOps
|
|
2
|
+
|
|
3
|
+
How Oris connects to a DevOps platform for commits, pull requests, and work items.
|
|
4
|
+
Swappable by design: today Azure DevOps, tomorrow Jira or GitHub — same flows, a different
|
|
5
|
+
provider block. Non-secret only; Oris stores NO credentials
|
|
6
|
+
(`references/conventions.md` `## Gates`).
|
|
7
|
+
|
|
8
|
+
## Config surface
|
|
9
|
+
|
|
10
|
+
Resolved in order, each layer overriding the previous:
|
|
11
|
+
|
|
12
|
+
1. Built-in Oris default (`azure-devops`, org `orislineweb`, MCP `oris-devops`).
|
|
13
|
+
2. Organization: `~/.oris/devops.json` — shared defaults for everyone in the org.
|
|
14
|
+
3. Repository: `.oris-flow/devops.json` — this repo's override.
|
|
15
|
+
|
|
16
|
+
Shape (`references/devops.schema.json`):
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"version": 1,
|
|
21
|
+
"devops": {
|
|
22
|
+
"provider": "azure-devops",
|
|
23
|
+
"organization": "orislineweb",
|
|
24
|
+
"workItemSyntax": "#{id}",
|
|
25
|
+
"commitLanguage": "en",
|
|
26
|
+
"prLanguage": "en",
|
|
27
|
+
"mcp": {
|
|
28
|
+
"name": "oris-devops",
|
|
29
|
+
"package": "@azure-devops/mcp@2.7.0",
|
|
30
|
+
"domains": ["core", "work", "work-items", "repositories"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- `provider` — the DevOps platform. Swap this (and the `mcp` block) to move off Azure.
|
|
37
|
+
- `organization` — org/account slug; substituted into the MCP command.
|
|
38
|
+
- `workItemSyntax` — how a work item id is written in commits/PRs. `#{id}` → `#1234`.
|
|
39
|
+
- `commitLanguage` / `prLanguage` — always `en`; commits and PRs are English by contract.
|
|
40
|
+
- `mcp` — the MCP server Oris seeds (`oris-devops`) so agents can read work items and
|
|
41
|
+
repositories. Auth is the platform's own (PAT / sign-in), never Oris's.
|
|
42
|
+
|
|
43
|
+
## Rules
|
|
44
|
+
|
|
45
|
+
1. READ the resolved config before composing a commit or PR.
|
|
46
|
+
2. NEVER store credentials in `.oris-flow/**`, `~/.oris/**`, or any Oris file.
|
|
47
|
+
3. Missing provider auth → degrade: compose the message, tell the user, do not block.
|
|
48
|
+
4. CONFIRM before writing any devops config file.
|
|
49
|
+
|
|
50
|
+
## Never
|
|
51
|
+
|
|
52
|
+
- Put secrets or tokens in a devops config file.
|
|
53
|
+
- Hardcode a platform in the flows — read `provider` and act generically.
|
|
54
|
+
|
|
55
|
+
## Done when
|
|
56
|
+
|
|
57
|
+
- [ ] Effective config resolved from default → org → repo before acting.
|
|
58
|
+
- [ ] No credentials written anywhere under Oris.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Oris DevOps Provider",
|
|
4
|
+
"$id": "https://oris.dev/schemas/oris-flow-devops-v1.json",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["version", "devops"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "integer",
|
|
11
|
+
"const": 1
|
|
12
|
+
},
|
|
13
|
+
"devops": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"properties": {
|
|
17
|
+
"provider": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "DevOps platform id (e.g. azure-devops, github, jira). Swap this and the mcp block to change platform."
|
|
20
|
+
},
|
|
21
|
+
"organization": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Org/account slug substituted into the MCP command. Non-secret."
|
|
24
|
+
},
|
|
25
|
+
"workItemSyntax": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "How a work item id is written in commits/PRs. Template with {id}, e.g. #{id} -> #1234."
|
|
28
|
+
},
|
|
29
|
+
"commitLanguage": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"minLength": 2,
|
|
32
|
+
"description": "Language for commit messages. Always en by contract."
|
|
33
|
+
},
|
|
34
|
+
"prLanguage": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"minLength": 2,
|
|
37
|
+
"description": "Language for pull request titles/descriptions. Always en by contract."
|
|
38
|
+
},
|
|
39
|
+
"mcp": {
|
|
40
|
+
"type": "object",
|
|
41
|
+
"additionalProperties": false,
|
|
42
|
+
"description": "MCP server Oris seeds so agents can read work items and repositories. No credentials.",
|
|
43
|
+
"properties": {
|
|
44
|
+
"name": { "type": "string" },
|
|
45
|
+
"package": { "type": "string" },
|
|
46
|
+
"domains": { "type": "array", "items": { "type": "string" } },
|
|
47
|
+
"command": { "type": "string" },
|
|
48
|
+
"args": { "type": "array", "items": { "type": "string" } }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
package/references/doc-policy.md
CHANGED
|
@@ -32,7 +32,7 @@ NEVER split one feature's docs across unrelated directories.
|
|
|
32
32
|
|
|
33
33
|
## Rules
|
|
34
34
|
|
|
35
|
-
1. Language: documents in `artifactLanguage
|
|
35
|
+
1. Language: documents in `artifactLanguage` (default `en`); chat/UI language is deduced from context. Skill instructions and code stay English.
|
|
36
36
|
2. Steps are independent: any document may be created without the previous one. State the missing source once, use the strongest confirmed source, record the gap in the document ("not available" localized). Never block on a missing predecessor.
|
|
37
37
|
3. INSPECT the task folder + setup map before asking the user or writing.
|
|
38
38
|
4. Every document ends with a change-history table: date | source | change | reason. Later changes rewrite the affected sections AND add a history row — no inline "changed!" notes.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"title": "Oris Loop Repository Adapter",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"additionalProperties": false,
|
|
7
|
-
"required": ["$schema", "schemaVersion", "repository", "paths", "commands", "
|
|
7
|
+
"required": ["$schema", "schemaVersion", "repository", "paths", "commands", "preflight"],
|
|
8
8
|
"properties": {
|
|
9
9
|
"$schema": {
|
|
10
10
|
"const": "https://oris.dev/schemas/oris-loop-adapter-v1.json"
|
|
@@ -54,22 +54,6 @@
|
|
|
54
54
|
"propertyNames": { "pattern": "^[a-z][a-z0-9-]*$" },
|
|
55
55
|
"additionalProperties": { "type": "string", "minLength": 1 }
|
|
56
56
|
},
|
|
57
|
-
"profile": {
|
|
58
|
-
"type": "object",
|
|
59
|
-
"additionalProperties": false,
|
|
60
|
-
"required": ["required", "defaultRole", "mappings"],
|
|
61
|
-
"properties": {
|
|
62
|
-
"required": { "type": "boolean" },
|
|
63
|
-
"defaultRole": {
|
|
64
|
-
"type": "string",
|
|
65
|
-
"pattern": "^[a-z][a-zA-Z0-9]*$"
|
|
66
|
-
},
|
|
67
|
-
"mappings": {
|
|
68
|
-
"type": "array",
|
|
69
|
-
"items": { "$ref": "#/$defs/mapping" }
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
57
|
"preflight": {
|
|
74
58
|
"type": "object",
|
|
75
59
|
"additionalProperties": false,
|
|
@@ -104,23 +88,6 @@
|
|
|
104
88
|
"minimum": 0
|
|
105
89
|
}
|
|
106
90
|
}
|
|
107
|
-
},
|
|
108
|
-
"mapping": {
|
|
109
|
-
"type": "object",
|
|
110
|
-
"additionalProperties": false,
|
|
111
|
-
"required": ["env", "from", "required", "secret"],
|
|
112
|
-
"properties": {
|
|
113
|
-
"env": {
|
|
114
|
-
"type": "string",
|
|
115
|
-
"pattern": "^[A-Z_][A-Z0-9_]*$"
|
|
116
|
-
},
|
|
117
|
-
"from": {
|
|
118
|
-
"type": "string",
|
|
119
|
-
"pattern": "^[A-Za-z][A-Za-z0-9]*(\\.[A-Za-z][A-Za-z0-9]*)*$"
|
|
120
|
-
},
|
|
121
|
-
"required": { "type": "boolean" },
|
|
122
|
-
"secret": { "type": "boolean" }
|
|
123
|
-
}
|
|
124
91
|
}
|
|
125
92
|
}
|
|
126
93
|
}
|
package/references/repo-map.md
CHANGED
|
@@ -6,10 +6,10 @@ Setup map = the default project context for every Oris skill and loop. It exists
|
|
|
6
6
|
|
|
7
7
|
| File | Scope | Purpose |
|
|
8
8
|
|------|-------|---------|
|
|
9
|
-
| `.oris-flow/manifest.json` | repo | compact index: section paths, freshness, confidence
|
|
9
|
+
| `.oris-flow/manifest.json` | repo | compact index: section paths, freshness, confidence |
|
|
10
10
|
| `.oris-flow/maps/**` | repo | short markdown maps: docs, stack, commands, code areas, tests |
|
|
11
11
|
| `.oris-flow/adapter.json` | repo | loop adapter: paths, commands, model aliases |
|
|
12
|
-
|
|
|
12
|
+
| `.oris-flow/settings.json` | repo | preferences: `responseStyle` + `artifactLanguage` (non-secret) |
|
|
13
13
|
| `{tasksRoot}/{task}/…` | task | business artifacts only — `setup.tasksRoot` in the manifest, default `.oris-flow/tasks` (see `references/doc-policy.md`) |
|
|
14
14
|
|
|
15
15
|
Manifest and maps are never task authority and NEVER hold secrets.
|
|
@@ -24,7 +24,6 @@ Manifest and maps are never task authority and NEVER hold secrets.
|
|
|
24
24
|
"generatedAt": "",
|
|
25
25
|
"updatedAt": "",
|
|
26
26
|
"setup": { "versionControl": { "orisFlowMap": "commit" } },
|
|
27
|
-
"refreshPolicy": {},
|
|
28
27
|
"sections": {}
|
|
29
28
|
}
|
|
30
29
|
```
|
|
@@ -46,7 +45,6 @@ Each section: purpose, authoritative paths, confirmed decisions, key commands/co
|
|
|
46
45
|
2. VERIFY stale or high-risk facts against the repository before consequential actions.
|
|
47
46
|
3. Loops: the orchestrator passes relevant setup-map facts into role prompts at craft time; users never repeat project facts per loop.
|
|
48
47
|
4. SUGGEST `/oris-flow` → Setup refresh only when a stale gap materially affects the task.
|
|
49
|
-
5. Refresh policy is advisory — never a scheduler.
|
|
50
48
|
|
|
51
49
|
## Command surface
|
|
52
50
|
|
|
@@ -49,9 +49,6 @@
|
|
|
49
49
|
"setup": {
|
|
50
50
|
"$ref": "#/$defs/setup"
|
|
51
51
|
},
|
|
52
|
-
"refreshPolicy": {
|
|
53
|
-
"$ref": "#/$defs/refreshPolicy"
|
|
54
|
-
},
|
|
55
52
|
"sections": {
|
|
56
53
|
"$ref": "#/$defs/sections"
|
|
57
54
|
},
|
|
@@ -106,29 +103,6 @@
|
|
|
106
103
|
"pattern": "^[a-z][a-zA-Z0-9-]*$"
|
|
107
104
|
}
|
|
108
105
|
},
|
|
109
|
-
"refreshPolicy": {
|
|
110
|
-
"type": "object",
|
|
111
|
-
"additionalProperties": false,
|
|
112
|
-
"required": ["mode"],
|
|
113
|
-
"properties": {
|
|
114
|
-
"mode": {
|
|
115
|
-
"type": "string",
|
|
116
|
-
"enum": ["manual", "monthly", "after-major-refactor", "after-test-layout-change"]
|
|
117
|
-
},
|
|
118
|
-
"suggestAfterDays": {
|
|
119
|
-
"type": "integer",
|
|
120
|
-
"minimum": 1
|
|
121
|
-
},
|
|
122
|
-
"triggers": {
|
|
123
|
-
"type": "array",
|
|
124
|
-
"items": {
|
|
125
|
-
"type": "string",
|
|
126
|
-
"enum": ["after-major-refactor", "after-test-layout-change"]
|
|
127
|
-
},
|
|
128
|
-
"uniqueItems": true
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
106
|
"setup": {
|
|
133
107
|
"type": "object",
|
|
134
108
|
"additionalProperties": false,
|
package/references/settings.md
CHANGED
|
@@ -1,36 +1,24 @@
|
|
|
1
1
|
# Oris Settings
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Per-project preferences. Path: `.oris-flow/settings.json`. Small and non-secret —
|
|
4
|
+
chat verbosity and document language, nothing else. Missing file → defaults below.
|
|
5
|
+
Created/edited via `/oris-flow` → Setup, or by hand.
|
|
5
6
|
|
|
6
7
|
## Shape (v1)
|
|
7
8
|
|
|
8
9
|
```json
|
|
9
10
|
{
|
|
10
11
|
"version": 1,
|
|
11
|
-
"orisFlow": { "
|
|
12
|
-
"defaultProfiles": { "testing": "default" },
|
|
13
|
-
"profiles": {
|
|
14
|
-
"default": {
|
|
15
|
-
"environment": "local",
|
|
16
|
-
"values": { "baseUrl": "" },
|
|
17
|
-
"secrets": { "username": "", "password": "" },
|
|
18
|
-
"flags": { "allowDataMutation": false }
|
|
19
|
-
}
|
|
20
|
-
}
|
|
12
|
+
"orisFlow": { "responseStyle": "standard", "artifactLanguage": "en" }
|
|
21
13
|
}
|
|
22
14
|
```
|
|
23
15
|
|
|
24
|
-
- `uiLanguage` → chat, menus, question labels, recaps (`en` | `it`, default `en`).
|
|
25
|
-
- `artifactLanguage` → generated documents (`en` | `it`, default `en`).
|
|
26
16
|
- `responseStyle` → chat verbosity (`standard` | `caveman`, default `standard`). Caveman = maximum token density in chat; contract in `references/conventions.md` `## Response style`. Documents and gates are never compressed.
|
|
27
|
-
- `
|
|
28
|
-
- `flags.allowDataMutation` → data mutation allowed ONLY with `environment: local` + loopback URLs + this flag true.
|
|
17
|
+
- `artifactLanguage` → language for generated documents (ISO code, default `en`). Chat/UI language is NOT configured here — it is deduced from the conversation.
|
|
29
18
|
|
|
30
19
|
## Rules
|
|
31
20
|
|
|
32
|
-
1. READ settings before the first workflow
|
|
21
|
+
1. READ settings before the first workflow decision; missing/invalid → defaults above.
|
|
33
22
|
2. Current user instructions override settings for the turn.
|
|
34
|
-
3.
|
|
35
|
-
4. CONFIRM before writing settings. Update via `/oris-flow` → Setup
|
|
36
|
-
5. In an approved loop scope, use only the profile/commands/tools the loop declares; otherwise `blocked`.
|
|
23
|
+
3. Oris stores no credentials. Test/CI secrets belong to each project's own tooling — never Oris files, docs, loop state, receipts, or logs.
|
|
24
|
+
4. CONFIRM before writing settings. Update via `/oris-flow` → Setup.
|
|
@@ -1,80 +1,30 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"title": "Oris Flow Settings",
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"required": ["version", "orisFlow"
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"properties": {
|
|
9
|
-
"version": {
|
|
10
|
-
"type": "integer",
|
|
11
|
-
"const": 1
|
|
12
|
-
},
|
|
13
|
-
"orisFlow": {
|
|
14
|
-
"type": "object",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
},
|
|
22
|
-
"artifactLanguage": {
|
|
23
|
-
"type": "string",
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"defaultProfiles": {
|
|
34
|
-
"type": "object",
|
|
35
|
-
"minProperties": 1,
|
|
36
|
-
"additionalProperties": {
|
|
37
|
-
"type": "string",
|
|
38
|
-
"minLength": 1
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"profiles": {
|
|
42
|
-
"type": "object",
|
|
43
|
-
"minProperties": 1,
|
|
44
|
-
"additionalProperties": {
|
|
45
|
-
"$ref": "#/$defs/profile"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
"$defs": {
|
|
50
|
-
"profile": {
|
|
51
|
-
"type": "object",
|
|
52
|
-
"additionalProperties": false,
|
|
53
|
-
"required": ["environment", "values", "secrets", "flags"],
|
|
54
|
-
"properties": {
|
|
55
|
-
"environment": {
|
|
56
|
-
"type": "string",
|
|
57
|
-
"minLength": 1
|
|
58
|
-
},
|
|
59
|
-
"values": {
|
|
60
|
-
"type": "object",
|
|
61
|
-
"additionalProperties": {
|
|
62
|
-
"type": ["string", "number", "boolean"]
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
"secrets": {
|
|
66
|
-
"type": "object",
|
|
67
|
-
"additionalProperties": {
|
|
68
|
-
"type": "string"
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
"flags": {
|
|
72
|
-
"type": "object",
|
|
73
|
-
"additionalProperties": {
|
|
74
|
-
"type": "boolean"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Oris Flow Settings",
|
|
4
|
+
"$id": "https://oris.dev/schemas/oris-flow-settings-v1.json",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["version", "orisFlow"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "integer",
|
|
11
|
+
"const": 1
|
|
12
|
+
},
|
|
13
|
+
"orisFlow": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"properties": {
|
|
17
|
+
"responseStyle": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": ["standard", "caveman"],
|
|
20
|
+
"description": "Chat verbosity: standard prose or caveman (maximum token density; documents and gates never compressed). Default standard."
|
|
21
|
+
},
|
|
22
|
+
"artifactLanguage": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"minLength": 2,
|
|
25
|
+
"description": "Language for generated documents (ISO code, e.g. en, it). Default en. Chat language is deduced from the conversation, not configured here."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Built-in Oris default DevOps provider. Non-secret only — org and repo layers override it.
|
|
9
|
+
* The provider is swappable: move off Azure DevOps by overriding `provider` and `mcp`.
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_DEVOPS = {
|
|
12
|
+
version: 1,
|
|
13
|
+
devops: {
|
|
14
|
+
provider: "azure-devops",
|
|
15
|
+
organization: "orislineweb",
|
|
16
|
+
workItemSyntax: "#{id}",
|
|
17
|
+
commitLanguage: "en",
|
|
18
|
+
prLanguage: "en",
|
|
19
|
+
mcp: {
|
|
20
|
+
name: "oris-devops",
|
|
21
|
+
package: "@azure-devops/mcp@2.7.0",
|
|
22
|
+
domains: ["core", "work", "work-items", "repositories"],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function isPlainObject(value) {
|
|
28
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Deep-merge source over target; arrays and scalars replace, plain objects merge. */
|
|
32
|
+
function deepMerge(target, source) {
|
|
33
|
+
if (!isPlainObject(source)) return source;
|
|
34
|
+
const out = isPlainObject(target) ? { ...target } : {};
|
|
35
|
+
for (const [key, value] of Object.entries(source)) {
|
|
36
|
+
out[key] = isPlainObject(value) ? deepMerge(out[key], value) : value;
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function readJson(filePath) {
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
44
|
+
} catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the effective DevOps config: built-in default → org (`~/.oris/devops.json`) →
|
|
51
|
+
* repository (`.oris-flow/devops.json`). Missing or invalid layers are skipped, never fatal.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveDevops(repositoryRoot, options = {}) {
|
|
54
|
+
const home = options.home ?? os.homedir();
|
|
55
|
+
const orgFile = readJson(path.join(home, ".oris", "devops.json"));
|
|
56
|
+
const repoFile = repositoryRoot ? readJson(path.join(repositoryRoot, ".oris-flow", "devops.json")) : null;
|
|
57
|
+
let resolved = DEFAULT_DEVOPS;
|
|
58
|
+
for (const layer of [orgFile, repoFile]) {
|
|
59
|
+
if (isPlainObject(layer)) resolved = deepMerge(resolved, layer);
|
|
60
|
+
}
|
|
61
|
+
return resolved;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Build the MCP server entry for an agent config from a resolved `devops` block. Azure
|
|
66
|
+
* DevOps command shape by default; any provider can supply explicit `mcp.args` instead.
|
|
67
|
+
*/
|
|
68
|
+
export function buildMcpServer(devops) {
|
|
69
|
+
const mcp = devops.mcp ?? {};
|
|
70
|
+
if (Array.isArray(mcp.args)) return { command: mcp.command ?? "npx", args: [...mcp.args] };
|
|
71
|
+
const domains = Array.isArray(mcp.domains) ? mcp.domains : [];
|
|
72
|
+
return { command: "npx", args: ["-y", mcp.package, devops.organization, "-d", ...domains] };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function mcpServerName(devops) {
|
|
76
|
+
return devops.mcp?.name ?? "oris-devops";
|
|
77
|
+
}
|
|
@@ -8,9 +8,9 @@ export const ORIS_FLOW_TASKS_ROOT = ".oris-flow/tasks";
|
|
|
8
8
|
export const ORIS_FLOW_ADAPTER = ".oris-flow/adapter.json";
|
|
9
9
|
export const ORIS_FLOW_LOOPS_ROOT = ".oris-flow/loops";
|
|
10
10
|
export const ORIS_FLOW_RUNTIME = ".oris-flow/runtime";
|
|
11
|
+
export const ORIS_FLOW_SETTINGS = ".oris-flow/settings.json";
|
|
11
12
|
export const ORIS_HOME = path.join(os.homedir(), ".oris");
|
|
12
13
|
export const ORIS_BUNDLE_ROOT = path.join(ORIS_HOME, "oris-skills");
|
|
13
|
-
export const ORIS_SKILLS_SETTINGS = path.join(ORIS_HOME, "settings.json");
|
|
14
14
|
export const ORIS_LOOP_SCHEMA = "https://oris.dev/schemas/oris-loop-adapter-v1.json";
|
|
15
15
|
export const ORIS_LOOP_SCHEMA_VERSION = 1;
|
|
16
16
|
export const ORIS_LOOP_DOCUMENT_VERSION = 2;
|