induscode 0.1.0__py3-none-any.whl

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.
Files changed (167) hide show
  1. induscode/__init__.py +56 -0
  2. induscode/addons/__init__.py +176 -0
  3. induscode/addons/contract.py +923 -0
  4. induscode/addons/dispatch/__init__.py +43 -0
  5. induscode/addons/dispatch/event_dispatcher.py +348 -0
  6. induscode/addons/dispatch/tool_interceptor.py +349 -0
  7. induscode/addons/host.py +469 -0
  8. induscode/addons/loader.py +314 -0
  9. induscode/addons/manifest.py +232 -0
  10. induscode/addons/surface.py +199 -0
  11. induscode/boot/__init__.py +108 -0
  12. induscode/boot/auth_vault.py +323 -0
  13. induscode/boot/boot.py +210 -0
  14. induscode/boot/contract.py +223 -0
  15. induscode/boot/invocation.py +117 -0
  16. induscode/boot/runners/__init__.py +42 -0
  17. induscode/boot/runners/link_runner.py +82 -0
  18. induscode/boot/runners/oneshot_runner.py +85 -0
  19. induscode/boot/runners/registry.py +46 -0
  20. induscode/boot/runners/repl_runner.py +340 -0
  21. induscode/boot/runners/session.py +549 -0
  22. induscode/boot/stages.py +198 -0
  23. induscode/boot/upgrade/__init__.py +36 -0
  24. induscode/boot/upgrade/apply.py +125 -0
  25. induscode/boot/upgrade/upgrades.py +136 -0
  26. induscode/briefing/__init__.py +115 -0
  27. induscode/briefing/compose.py +414 -0
  28. induscode/briefing/contract.py +528 -0
  29. induscode/briefing/macros.py +721 -0
  30. induscode/briefing/skills.py +417 -0
  31. induscode/capability_deck/__init__.py +233 -0
  32. induscode/capability_deck/bridge_ledger/__init__.py +66 -0
  33. induscode/capability_deck/bridge_ledger/key.py +181 -0
  34. induscode/capability_deck/bridge_ledger/ledger.py +276 -0
  35. induscode/capability_deck/bridge_ledger/network.py +336 -0
  36. induscode/capability_deck/builtin_bridge.py +358 -0
  37. induscode/capability_deck/cards/__init__.py +116 -0
  38. induscode/capability_deck/cards/bg_process.py +482 -0
  39. induscode/capability_deck/cards/memory.py +226 -0
  40. induscode/capability_deck/cards/saas.py +280 -0
  41. induscode/capability_deck/cards/task.py +256 -0
  42. induscode/capability_deck/cards/todo.py +312 -0
  43. induscode/capability_deck/contract.py +450 -0
  44. induscode/capability_deck/manifest.py +126 -0
  45. induscode/capability_deck/provision.py +217 -0
  46. induscode/channels/__init__.py +146 -0
  47. induscode/channels/contract.py +585 -0
  48. induscode/channels/framer.py +132 -0
  49. induscode/channels/link/__init__.py +50 -0
  50. induscode/channels/link/dialog.py +246 -0
  51. induscode/channels/link/driver.py +308 -0
  52. induscode/channels/link/server.py +217 -0
  53. induscode/channels/oneshot.py +178 -0
  54. induscode/channels/ops.py +140 -0
  55. induscode/channels/session_ops.py +172 -0
  56. induscode/conductor/__init__.py +240 -0
  57. induscode/conductor/catalog.py +309 -0
  58. induscode/conductor/conductor.py +1084 -0
  59. induscode/conductor/contract.py +1035 -0
  60. induscode/conductor/matcher.py +291 -0
  61. induscode/conductor/serialize.py +575 -0
  62. induscode/conductor/signal_hub.py +382 -0
  63. induscode/conductor/skill_parse.py +294 -0
  64. induscode/conductor/transcript_store.py +449 -0
  65. induscode/console/__init__.py +236 -0
  66. induscode/console/app.py +1677 -0
  67. induscode/console/components/__init__.py +62 -0
  68. induscode/console/components/banner.py +499 -0
  69. induscode/console/components/banner_sweep.py +188 -0
  70. induscode/console/components/emblem.py +181 -0
  71. induscode/console/components/status_bar.py +102 -0
  72. induscode/console/contract.py +836 -0
  73. induscode/console/input/__init__.py +107 -0
  74. induscode/console/input/chord.py +197 -0
  75. induscode/console/input/dir_reader.py +113 -0
  76. induscode/console/input/intents.py +258 -0
  77. induscode/console/input/providers.py +469 -0
  78. induscode/console/mount.py +137 -0
  79. induscode/console/overlays/__init__.py +94 -0
  80. induscode/console/overlays/auth.py +503 -0
  81. induscode/console/overlays/pickers.py +526 -0
  82. induscode/console/overlays/router.py +129 -0
  83. induscode/console/overlays/sessions.py +232 -0
  84. induscode/console/reducer.py +145 -0
  85. induscode/console/resume_picker.py +156 -0
  86. induscode/console/slash_commands/__init__.py +78 -0
  87. induscode/console/slash_commands/builtins.py +254 -0
  88. induscode/console/slash_commands/dynamic.py +217 -0
  89. induscode/console/slash_commands/integrations.py +949 -0
  90. induscode/console/slash_commands/transcript.py +404 -0
  91. induscode/console/slash_commands/workbench.py +430 -0
  92. induscode/console/startup.py +434 -0
  93. induscode/console/theme/__init__.py +44 -0
  94. induscode/console/theme/adapter.py +168 -0
  95. induscode/console/theme/palette.py +128 -0
  96. induscode/console/theme/resolve.py +123 -0
  97. induscode/console/theme/tokens.py +185 -0
  98. induscode/console_slash/__init__.py +111 -0
  99. induscode/console_slash/contract.py +185 -0
  100. induscode/console_slash/registry.py +140 -0
  101. induscode/console_slash/resolve.py +194 -0
  102. induscode/console_slash/shared.py +172 -0
  103. induscode/entry.py +108 -0
  104. induscode/insight/__init__.py +153 -0
  105. induscode/insight/collector.py +73 -0
  106. induscode/insight/replay.py +305 -0
  107. induscode/insight/wrapper.py +1115 -0
  108. induscode/kit/__init__.py +82 -0
  109. induscode/kit/clipboard_image.py +215 -0
  110. induscode/kit/external_editor.py +120 -0
  111. induscode/kit/image.py +188 -0
  112. induscode/kit/shell.py +89 -0
  113. induscode/kit/tool_fetch.py +288 -0
  114. induscode/launch/__init__.py +224 -0
  115. induscode/launch/catalog.py +310 -0
  116. induscode/launch/contract.py +569 -0
  117. induscode/launch/credentials.py +852 -0
  118. induscode/launch/invocation/__init__.py +39 -0
  119. induscode/launch/invocation/attachments.py +281 -0
  120. induscode/launch/invocation/flags.py +210 -0
  121. induscode/launch/invocation/read.py +369 -0
  122. induscode/launch/invocation/usage.py +110 -0
  123. induscode/launch/oauth.py +808 -0
  124. induscode/launch/packages.py +299 -0
  125. induscode/launch/pickers.py +291 -0
  126. induscode/py.typed +0 -0
  127. induscode/runtime_bridge/__init__.py +166 -0
  128. induscode/runtime_bridge/bridges/__init__.py +66 -0
  129. induscode/runtime_bridge/bridges/_drive.py +268 -0
  130. induscode/runtime_bridge/bridges/builtins.py +177 -0
  131. induscode/runtime_bridge/bridges/claude_cli.py +198 -0
  132. induscode/runtime_bridge/bridges/codex_cli.py +203 -0
  133. induscode/runtime_bridge/bridges/indusagi_cli.py +217 -0
  134. induscode/runtime_bridge/broker.py +397 -0
  135. induscode/runtime_bridge/contract.py +734 -0
  136. induscode/runtime_bridge/sink.py +351 -0
  137. induscode/sessions/__init__.py +25 -0
  138. induscode/sessions/contract.py +119 -0
  139. induscode/sessions/library.py +350 -0
  140. induscode/settings/__init__.py +47 -0
  141. induscode/settings/contract.py +313 -0
  142. induscode/settings/manager.py +268 -0
  143. induscode/transcript_export/__init__.py +109 -0
  144. induscode/transcript_export/contract.py +522 -0
  145. induscode/transcript_export/publish.py +455 -0
  146. induscode/transcript_export/sgr.py +566 -0
  147. induscode/transcript_export/template.py +319 -0
  148. induscode/transcript_export/theme_bridge.py +325 -0
  149. induscode/window_budget/__init__.py +76 -0
  150. induscode/window_budget/budget/__init__.py +26 -0
  151. induscode/window_budget/budget/estimate.py +273 -0
  152. induscode/window_budget/budget/gate.py +60 -0
  153. induscode/window_budget/budget/slice.py +145 -0
  154. induscode/window_budget/condenser.py +170 -0
  155. induscode/window_budget/contract.py +329 -0
  156. induscode/window_budget/summarize/__init__.py +33 -0
  157. induscode/window_budget/summarize/condense.py +212 -0
  158. induscode/window_budget/summarize/prompt.py +241 -0
  159. induscode/workspace/__init__.py +30 -0
  160. induscode/workspace/brand.py +96 -0
  161. induscode/workspace/locator.py +269 -0
  162. induscode-0.1.0.dist-info/METADATA +97 -0
  163. induscode-0.1.0.dist-info/RECORD +167 -0
  164. induscode-0.1.0.dist-info/WHEEL +4 -0
  165. induscode-0.1.0.dist-info/entry_points.txt +3 -0
  166. induscode-0.1.0.dist-info/licenses/CREDITS.md +22 -0
  167. induscode-0.1.0.dist-info/licenses/NOTICE +7 -0
@@ -0,0 +1,269 @@
1
+ """Workspace Locator — turns the active :class:`~.brand.Brand` plus the
2
+ environment into a single, fully-resolved :class:`Workspace` record of
3
+ absolute paths.
4
+
5
+ Replaces a family of free ``get_<thing>_path()`` getters with one keyed map:
6
+ every member of :class:`Workspace` is described once as a relative location
7
+ inside the profile directory (:data:`LAYOUT`), and the record is built by
8
+ folding that map against a resolved profile root. There is no per-path
9
+ function and no string literal duplicated across the codebase — the layout is
10
+ data.
11
+
12
+ Resolution is pure: it reads the home directory and the process env (both
13
+ overridable for tests), and never touches the filesystem. The optional
14
+ :func:`ensure_dirs` helper is the only function that writes, and it only ever
15
+ ``mkdir -p``\\ s directories that belong to the resolved workspace.
16
+
17
+ Composition with the framework
18
+ ------------------------------
19
+ This module is a thin layer over the ``indusagi`` framework's location plane
20
+ (:mod:`indusagi._internal.env` / :mod:`indusagi.shell_app.locate`) rather than
21
+ a re-derivation of it. Profile-root precedence:
22
+
23
+ 1. ``$INDUSAGI_CODING_AGENT_DIR`` (:attr:`Brand.env_profile_dir`) — the
24
+ agent-specific override, ``~``-expanded and resolved against ``cwd`` when
25
+ relative (TS semantics, kept verbatim);
26
+ 2. ``$INDUSAGI_HOME`` — the framework's state-directory override (its name is
27
+ composed via :func:`indusagi._internal.env.env_name`, never hard-coded);
28
+ its value *is* the profile directory, per the framework env registry.
29
+ One deliberate deviation from :func:`indusagi._internal.env.indusagi_home`:
30
+ ``~`` expands against the *injectable* home (not the live OS home) so test
31
+ sandboxes stay hermetic, and a relative value resolves against ``cwd``;
32
+ 3. ``<home>/.pindusagi`` — the framework's flat root
33
+ (:attr:`Brand.profile_dir_name`; the TS ``~/.indusagi/agent`` nesting is
34
+ dropped — nothing else shares the directory).
35
+
36
+ Port note — ``runtime-detect.ts`` dropped
37
+ -----------------------------------------
38
+ The TS workspace shipped a third module that probed whether the process was a
39
+ Bun-compiled single-file binary versus a plain package install, to find the
40
+ package root for bundled assets (themes, export templates). Python has no
41
+ compiled-binary deployment mode: the package is always an installed (or
42
+ editable) wheel, and bundled assets resolve via ``importlib.resources``
43
+ against the package itself. The detection axis does not exist, so the module
44
+ is not ported.
45
+ """
46
+
47
+ from __future__ import annotations
48
+
49
+ import os
50
+ from dataclasses import dataclass, fields
51
+ from pathlib import Path
52
+ from types import MappingProxyType
53
+ from typing import Final, Mapping
54
+
55
+ from indusagi._internal import env as _fw_env
56
+
57
+ from .brand import BRAND, Brand
58
+
59
+ __all__ = [
60
+ "DIRECTORY_KEYS",
61
+ "ENV_FRAMEWORK_HOME",
62
+ "LAYOUT",
63
+ "Workspace",
64
+ "WorkspaceOverrides",
65
+ "create_workspace",
66
+ "ensure_dirs",
67
+ ]
68
+
69
+ #: The framework's state-directory override variable ("INDUSAGI_HOME"),
70
+ #: composed through the framework env registry so the name can never drift.
71
+ ENV_FRAMEWORK_HOME: Final[str] = _fw_env.env_name("home")
72
+
73
+
74
+ # ---------------------------------------------------------------------------
75
+ # Shape
76
+ # ---------------------------------------------------------------------------
77
+
78
+
79
+ @dataclass(frozen=True, slots=True)
80
+ class Workspace:
81
+ """Every filesystem location the app uses, fully resolved.
82
+
83
+ Field names are the mechanical snake_case renames of the 15-key TS
84
+ ``Workspace`` contract (``boot/contract.ts``); the on-disk basenames in
85
+ :data:`LAYOUT` are kept verbatim from ``workspace/locator.ts``.
86
+ """
87
+
88
+ # Root profile directory, e.g. ``~/.pindusagi``.
89
+ profile_dir: Path
90
+ # Merged-settings file (``settings.json``).
91
+ settings_path: Path
92
+ # Consolidated credential store (``auth.json``).
93
+ auth_path: Path
94
+ # Per-cwd transcript directory root (``sessions/``).
95
+ sessions_dir: Path
96
+ # Custom model-catalog overrides (``models.json``).
97
+ models_path: Path
98
+ # Provisioned native helper binaries (``bin/``, holds fd / rg).
99
+ tools_dir: Path
100
+ # Alias for the managed-binary directory; equals ``tools_dir``.
101
+ bin_dir: Path
102
+ # User-authored prompt/command templates (``prompts/``).
103
+ prompts_dir: Path
104
+ # User-installed color themes (``themes/``).
105
+ themes_dir: Path
106
+ # Bundled HTML transcript-export template directory.
107
+ export_template_dir: Path
108
+ # Verbose diagnostic log file path.
109
+ debug_log_path: Path
110
+ # External MCP server configuration (``mcp-servers.json``).
111
+ mcp_config_path: Path
112
+ # Memory-feature configuration (``memory.json``).
113
+ memory_config_path: Path
114
+ # Composio-integration configuration (``composio.json``).
115
+ composio_config_path: Path
116
+ # On-disk memory database (``memory.db``).
117
+ memory_db_path: Path
118
+
119
+
120
+ @dataclass(frozen=True, slots=True)
121
+ class WorkspaceOverrides:
122
+ """Inputs that normally come from the OS but may be pinned for testing or
123
+ embedding. All optional; each defaults to its live process value.
124
+ """
125
+
126
+ # User home directory; defaults to ``Path.home()``.
127
+ home: str | os.PathLike[str] | None = None
128
+ # Working directory the resolution is anchored to; defaults to ``Path.cwd()``.
129
+ cwd: str | os.PathLike[str] | None = None
130
+ # Environment to read the profile-dir overrides from; defaults to ``os.environ``.
131
+ env: Mapping[str, str] | None = None
132
+ # Brand whose names drive the layout; defaults to :data:`~.brand.BRAND`.
133
+ brand: Brand = BRAND
134
+
135
+
136
+ # ---------------------------------------------------------------------------
137
+ # Layout map
138
+ # ---------------------------------------------------------------------------
139
+
140
+ #: Where each :class:`Workspace` member lives, as path segments relative to
141
+ #: the resolved profile directory. The entire on-disk layout expressed as
142
+ #: data, ported verbatim from the TS ``LAYOUT`` (15 keys; ``profile_dir``
143
+ #: maps to the empty segment list — it *is* the root). ``bin_dir`` and
144
+ #: ``tools_dir`` deliberately share the same location: the managed
145
+ #: native-helper directory has one home, surfaced under both names.
146
+ LAYOUT: Final[Mapping[str, tuple[str, ...]]] = MappingProxyType(
147
+ {
148
+ "profile_dir": (),
149
+ "settings_path": ("settings.json",),
150
+ "auth_path": ("auth.json",),
151
+ "sessions_dir": ("sessions",),
152
+ "models_path": ("models.json",),
153
+ "tools_dir": ("bin",),
154
+ "bin_dir": ("bin",),
155
+ "prompts_dir": ("prompts",),
156
+ "themes_dir": ("themes",),
157
+ "export_template_dir": ("export-template",),
158
+ "debug_log_path": ("debug.log",),
159
+ "mcp_config_path": ("mcp-servers.json",),
160
+ "memory_config_path": ("memory.json",),
161
+ "composio_config_path": ("composio.json",),
162
+ "memory_db_path": ("memory.db",),
163
+ }
164
+ )
165
+
166
+ #: Members of :class:`Workspace` that name directories rather than files.
167
+ #: Used by :func:`ensure_dirs` to decide what to materialise.
168
+ DIRECTORY_KEYS: Final[tuple[str, ...]] = (
169
+ "profile_dir",
170
+ "sessions_dir",
171
+ "tools_dir",
172
+ "bin_dir",
173
+ "prompts_dir",
174
+ "themes_dir",
175
+ "export_template_dir",
176
+ )
177
+
178
+
179
+ # ---------------------------------------------------------------------------
180
+ # Resolution
181
+ # ---------------------------------------------------------------------------
182
+
183
+
184
+ def _expand_home(raw_path: str, home: Path, cwd: Path) -> Path:
185
+ """Expand a leading ``~`` to the (injectable) home directory and resolve
186
+ to an absolute path against ``cwd``. A bare ``~`` or ``~/...`` is
187
+ home-anchored; already-absolute paths pass through unchanged; everything
188
+ else is normalised against ``cwd`` (no symlink resolution, matching the
189
+ TS ``path.resolve`` semantics).
190
+ """
191
+ if raw_path == "~":
192
+ return home
193
+ if raw_path.startswith(("~/", "~\\")):
194
+ return home / raw_path[2:]
195
+ candidate = Path(raw_path)
196
+ if candidate.is_absolute():
197
+ return candidate
198
+ return Path(os.path.normpath(cwd / candidate))
199
+
200
+
201
+ def _resolve_profile_root(brand: Brand, home: Path, cwd: Path, env: Mapping[str, str]) -> Path:
202
+ """Compute the absolute profile-directory root.
203
+
204
+ Precedence: agent-specific :attr:`Brand.env_profile_dir` override →
205
+ framework :data:`ENV_FRAMEWORK_HOME` override → ``<home>/<profile_dir_name>``
206
+ (the framework's flat ``~/.pindusagi`` default).
207
+ """
208
+ override = (env.get(brand.env_profile_dir) or "").strip()
209
+ if override:
210
+ return _expand_home(override, home, cwd)
211
+
212
+ framework_home = (env.get(ENV_FRAMEWORK_HOME) or "").strip()
213
+ if framework_home:
214
+ # Framework env-registry semantics: the value *is* the state dir.
215
+ return _expand_home(framework_home, home, cwd)
216
+
217
+ return home / brand.profile_dir_name
218
+
219
+
220
+ def create_workspace(overrides: WorkspaceOverrides | None = None) -> Workspace:
221
+ """Build the fully-resolved :class:`Workspace` for the active brand and
222
+ environment.
223
+
224
+ Pure path computation: resolves the profile root, then folds the
225
+ :data:`LAYOUT` map into a frozen record by joining each member's segments
226
+ onto that root. No filesystem access — call :func:`ensure_dirs` separately
227
+ if the directories need to exist.
228
+ """
229
+ resolved = overrides if overrides is not None else WorkspaceOverrides()
230
+ brand = resolved.brand
231
+ home = Path(resolved.home) if resolved.home is not None else Path.home()
232
+ cwd = Path(resolved.cwd) if resolved.cwd is not None else Path.cwd()
233
+ env: Mapping[str, str] = resolved.env if resolved.env is not None else os.environ
234
+
235
+ profile_root = _resolve_profile_root(brand, home, cwd, env)
236
+
237
+ members = {
238
+ key: profile_root if not segments else profile_root.joinpath(*segments)
239
+ for key, segments in LAYOUT.items()
240
+ }
241
+ return Workspace(**members)
242
+
243
+
244
+ # ---------------------------------------------------------------------------
245
+ # Materialisation
246
+ # ---------------------------------------------------------------------------
247
+
248
+
249
+ def ensure_dirs(workspace: Workspace) -> Workspace:
250
+ """Create every directory the workspace expects, idempotently.
251
+
252
+ Walks the :data:`DIRECTORY_KEYS` subset of the resolved :class:`Workspace`
253
+ and ``mkdir -p``\\ s each one. Files are never created here — only their
254
+ containing directories — so callers can write ``settings.json`` et al.
255
+ afterwards without a missing-parent error. Returns the same workspace for
256
+ chaining.
257
+ """
258
+ for key in DIRECTORY_KEYS:
259
+ directory: Path = getattr(workspace, key)
260
+ directory.mkdir(parents=True, exist_ok=True)
261
+ return workspace
262
+
263
+
264
+ # The LAYOUT map and the Workspace dataclass must always describe the same
265
+ # member set; assert it once at import so a drift is an immediate, loud error
266
+ # (the Python analogue of the TS `Record<keyof Workspace, ...>` constraint).
267
+ assert set(LAYOUT) == {field.name for field in fields(Workspace)}, (
268
+ "workspace LAYOUT keys must match Workspace fields"
269
+ )
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.4
2
+ Name: induscode
3
+ Version: 0.1.0
4
+ Summary: Indusagi coding agent — terminal-first AI coding agent on the indusagi framework (Python rebuild)
5
+ Project-URL: Homepage, https://github.com/varunisrani/indusagi-ts
6
+ Project-URL: Repository, https://github.com/varunisrani/indusagi-ts
7
+ Project-URL: Issues, https://github.com/varunisrani/indusagi-ts/issues
8
+ Author: Varun Israni
9
+ Author-email: IndusAGI Team <team@indusagi.ai>
10
+ License-Expression: MIT
11
+ License-File: CREDITS.md
12
+ License-File: NOTICE
13
+ Keywords: agent,ai,cli,coding-agent,llm,mcp,tui
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Code Generators
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: indusagi[mcp,tui]>=0.1.0
26
+ Requires-Dist: markdown-it-py>=3.0
27
+ Requires-Dist: pygments>=2.18
28
+ Requires-Dist: python-ulid>=2.7
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
31
+ Requires-Dist: pytest>=8; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # induscode (Python rebuild)
35
+
36
+ Terminal-first AI coding agent on the [indusagi framework](../indusagi-python-rebuild)
37
+ — the Python port of the TypeScript `indusagi-coding-agent` (lineage v0.1.62).
38
+ Console scripts: **`pindus`** (primary) and **`induscode`** (alias).
39
+
40
+ Port plan: `../indus-code-rebuild/PYTHON_PORT_PLAN/PLAN.md` (milestones M0–M6).
41
+ Current status: **all milestones built** — conductor turn loop, runtime bridge,
42
+ capability deck, addons, headless CLI (launch/boot/channels/sessions), Textual
43
+ console with 26 slash commands, transcript export, and packaging. **649 tests
44
+ green**; lineage scan clean; wheel verified in a fresh venv.
45
+
46
+ ## Install (from wheels)
47
+
48
+ The `indusagi` framework is a local dependency (not on PyPI), so install its
49
+ wheel first — with the `[mcp,tui]` extras, which the agent requires — then the
50
+ `induscode` wheel:
51
+
52
+ ```bash
53
+ python3.13 -m venv agent-venv
54
+ agent-venv/bin/pip install '../indusagi-python-rebuild/dist/indusagi-0.1.0-py3-none-any.whl[mcp,tui]'
55
+ agent-venv/bin/pip install dist/induscode-0.1.0-py3-none-any.whl
56
+ ```
57
+
58
+ Build the wheels with `python -m build` in each project if `dist/` is missing
59
+ or stale.
60
+
61
+ ## Run
62
+
63
+ ```bash
64
+ pindus # interactive Textual console
65
+ pindus -p "explain this repo" # one-shot: print the result and exit
66
+ pindus -p --json "explain this repo" # headless NDJSON line protocol
67
+ pindus --list-models # provider/model catalog
68
+ pindus signin # store credentials (OAuth or API key)
69
+ pindus signin --list # show stored accounts
70
+ pindus --help # full flag table (@file attachments, --, etc.)
71
+ ```
72
+
73
+ State lives in **`~/.pindusagi`** (shared with the framework; the
74
+ `INDUSAGI_CODING_AGENT_DIR` then `INDUSAGI_HOME` environment variables
75
+ override). Credentials are stored in the agent's multi-account vault
76
+ (`auth.json`, mode 0600).
77
+
78
+ ## Dev setup
79
+
80
+ ```bash
81
+ python3.13 -m venv .venv
82
+ .venv/bin/pip install -e ../indusagi-python-rebuild -e ".[dev]"
83
+ ```
84
+
85
+ ## Gates
86
+
87
+ ```bash
88
+ .venv/bin/pytest -q # test suite — 649 tests, never weakened
89
+ .venv/bin/python scripts/lineage_scan.py # clean-room lineage guard
90
+ .venv/bin/pindus --version # smoke: prints "induscode 0.1.0"
91
+ .venv/bin/python -m build # sdist + wheel into dist/
92
+ ```
93
+
94
+ The packaging gate additionally installs both wheels into a throwaway venv and
95
+ runs `--version`, `--help`, `--list-models`, and the subsystem imports.
96
+
97
+ MIT © Varun Israni — see `NOTICE` and `CREDITS.md`.
@@ -0,0 +1,167 @@
1
+ induscode/__init__.py,sha256=N1-PAF8qgjNmPiXr7yjeAJF5LaNIhISLDxLPKXpN2wo,2105
2
+ induscode/entry.py,sha256=1MI-M3U0gdfLYmgwQlrTck6HREID6kFXy_R-3M_BEyg,3782
3
+ induscode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ induscode/addons/__init__.py,sha256=GsGgkF5pQY6wdaYQeLHgUP2xiE_WOeJhwYLshcbhh3A,4762
5
+ induscode/addons/contract.py,sha256=hC-Ck8WMcwX_ir6t0iUvYN6Axq_BeZT1nru54ExTBeU,37364
6
+ induscode/addons/host.py,sha256=gFp-0NQWBWFe4iIN5qvX9O7TLXjrU14Bo5XDPvGYapI,19603
7
+ induscode/addons/loader.py,sha256=DIfV_T-Zyeg4O1L_oGlsLuKxiydYveEO1Pb22WpVsCI,13204
8
+ induscode/addons/manifest.py,sha256=WjYTGVXy8uvHk-4J7p5CwJmcTGZD4smEPbXqFZiOj8g,8987
9
+ induscode/addons/surface.py,sha256=6Gqla4UeXYFzy6_YMdm1Hphi4XivPuI_-kE_v3kjIK0,7565
10
+ induscode/addons/dispatch/__init__.py,sha256=GswVDiLDUNm1Yex_3yBxNO31prKikTap916CX5hTRrg,1568
11
+ induscode/addons/dispatch/event_dispatcher.py,sha256=J8g-6OghQa4ehvhX3uF1YnmrhFElTBHi35phMhPSjY8,14515
12
+ induscode/addons/dispatch/tool_interceptor.py,sha256=1roW6e0ZdOcXlmpKJWI2LfXenP3WV67zxNtFGatv3j4,13999
13
+ induscode/boot/__init__.py,sha256=poejW8LWl8lafZiwYrkvUYVeYX6ThGlxeFxKwA9c-cA,2554
14
+ induscode/boot/auth_vault.py,sha256=9MAW8RS7ju19Wn3R8j7ctlISGrfUzHRUslAD2hEgHDk,12878
15
+ induscode/boot/boot.py,sha256=dVAXtr0glroTl0tQ5I9OZzRdxKbTfgGiUkz6Q0znqAs,7921
16
+ induscode/boot/contract.py,sha256=0PX1v-9sATNhINm7HGIATvPOztVbaDbLrI7KJ8Dl0FU,9550
17
+ induscode/boot/invocation.py,sha256=1KoHJTCjOa9zUpyiAdYJL12PO12-Cm2k9_IvkRNRIIA,4587
18
+ induscode/boot/stages.py,sha256=0w03gsit6lzyvhsvclEUEsLN7vTDi4nTtu7BnhVVGVo,7762
19
+ induscode/boot/runners/__init__.py,sha256=GWK4d04de7osfhoY-a1vmx2XZFIwvG3YdVI8PvvEFJs,1220
20
+ induscode/boot/runners/link_runner.py,sha256=1IXHoWYRrTgzxW-6f71uUnk3Humtrk6RN4dvgj7dWyA,2710
21
+ induscode/boot/runners/oneshot_runner.py,sha256=4fIpswaTs5-IUCj-NXy7bwqFVCbcKO7yoAHXuqC2k60,2703
22
+ induscode/boot/runners/registry.py,sha256=SMklF_JtkPj7b2DMro6ochhjG4xw2thMl6JT9JBdNc4,1762
23
+ induscode/boot/runners/repl_runner.py,sha256=IJ7ej1nykb85t-6M3TxlcQJhgs1akVboCJCBmK12Mgc,14316
24
+ induscode/boot/runners/session.py,sha256=ZslfgBV4weplMQUCnwaotNkpFFCXM3oTEIGGFzdf9ZE,21820
25
+ induscode/boot/upgrade/__init__.py,sha256=ioMMLEAH-ON1spZq-oHPLTfkDG0Fr2wVw5mko8JY_bo,1099
26
+ induscode/boot/upgrade/apply.py,sha256=U7DUuAXJn68gylDUR9VIfcrlvBLw00N-_9uYyJ9781k,5074
27
+ induscode/boot/upgrade/upgrades.py,sha256=8UsYZykDbJluh62j6D85jKaQDu0x4GKXM1h8kQZkKeA,5536
28
+ induscode/briefing/__init__.py,sha256=CgSPJOmuyoD4d8HAUmeZKf89u3utppCV2YjNzxfr3eM,2892
29
+ induscode/briefing/compose.py,sha256=oSO9MratfdW7dMz9Z0ikbmORzapW5ilpg8FIiyC3a9E,16072
30
+ induscode/briefing/contract.py,sha256=FEqN3hRtscfxgwnl87RluqXZTbJFlNqSW5bIckGAEww,21935
31
+ induscode/briefing/macros.py,sha256=fuAJQ1Ef6XB5DQcAuHekLkalYwr4N8y9EAJRuj0gMlc,25965
32
+ induscode/briefing/skills.py,sha256=UzwcXA1a3JZiU4344JihkxXiZuiD3z9PVcvVLRX5yrY,15552
33
+ induscode/capability_deck/__init__.py,sha256=L1r4LIfSs97DehZqJ3b1tEDq438lCOr4Rvh6LxUvOJY,5875
34
+ induscode/capability_deck/builtin_bridge.py,sha256=sB3by2LKqRjdzkmBMQDT_GCZ01EVZrrD9CPLr9cHI3E,13960
35
+ induscode/capability_deck/contract.py,sha256=UiXgz9QQ1mvV_cL2oqMewaX1R48Qp37WwcfJfw9g-dk,19050
36
+ induscode/capability_deck/manifest.py,sha256=JtslKGGxFFibtkSt6iXSUGbU4tNdQWy8dwtDbGy-6CU,4986
37
+ induscode/capability_deck/provision.py,sha256=gkKNVOrl8JnL9jSEtfHuHF7KXaZWjeXOx5I_g4uu5rk,9140
38
+ induscode/capability_deck/bridge_ledger/__init__.py,sha256=wkdoR8K3sbL51mRA4DhsPTdkXhAQtpKaLgplguRlJgE,2214
39
+ induscode/capability_deck/bridge_ledger/key.py,sha256=Vj2B9dZv1vD_SEJVvh--lsMrCs5NrJUs7S5j3aShozI,8300
40
+ induscode/capability_deck/bridge_ledger/ledger.py,sha256=ZnYm63zqIh0Ej_g4x1ES7cA6lvYeUyZ3eDq9Vu_2sqw,10182
41
+ induscode/capability_deck/bridge_ledger/network.py,sha256=nPOODkAlimRJbHn36Q1OhgO76H_vJcGfYtpGqCzjwI0,12810
42
+ induscode/capability_deck/cards/__init__.py,sha256=Rmu5cmCZ62Jip_aTSed0SO7Aalbua4uycVP55azz4-M,3119
43
+ induscode/capability_deck/cards/bg_process.py,sha256=QpjXc87vCA2MqNIjGbDGPfeaihDZwO-P5d09grfsf-Y,17559
44
+ induscode/capability_deck/cards/memory.py,sha256=1XsnCf79EA_0ZNiwtm-GUX4CnhYkfWLDaOWd1ssnUtM,7522
45
+ induscode/capability_deck/cards/saas.py,sha256=6oLw48loUWfKZVXS--1N0RJb5VN-OcpfVacUtskDxDo,9600
46
+ induscode/capability_deck/cards/task.py,sha256=Uo4RNGodVa2-vRRSKLveQNIoE8i4aHoRzi-rzXA_tz4,9197
47
+ induscode/capability_deck/cards/todo.py,sha256=qxWfz294RTnoFnUo3-YDQJnMuyVBdPqb3Nm_zIoJvjg,10830
48
+ induscode/channels/__init__.py,sha256=pOYMJvEmaUSsjfCwSRewgmXk904f23B64ldmJl7oMPY,3528
49
+ induscode/channels/contract.py,sha256=Ocamz-LOjZmm-EeHwTZzGIPVgLrxiMjRCIZwK2iIV0w,22355
50
+ induscode/channels/framer.py,sha256=5QziqZp7_vqU6AEjnQtNLUuI0nwE-WKHoOwlLt0huEc,5485
51
+ induscode/channels/oneshot.py,sha256=zAkmBVN3RJGg4LXU4_a5lush-7mOym51QZ-Exrv7-z0,6724
52
+ induscode/channels/ops.py,sha256=ouqMyOziUdctvYubHDlvRwAHIDXME6Yq6Vpf47foTwM,5146
53
+ induscode/channels/session_ops.py,sha256=WOFgFL2EI-uxiW_JTgfT02tCXKGPCFN7Qceomfob-lY,7275
54
+ induscode/channels/link/__init__.py,sha256=sWGbxBPj8yFKs1LQ3pluSK_4lKW-Q0OcymS2hMB0pTQ,1351
55
+ induscode/channels/link/dialog.py,sha256=bojTlI4-Td2Mi635tQQULCpFzq1AcIYx3TUP-wYrCsI,9415
56
+ induscode/channels/link/driver.py,sha256=9XJ8qkFZmuYaB9moJxW1Deo9ulJ3hzECJKDIX05UtEQ,10904
57
+ induscode/channels/link/server.py,sha256=DoBleHvdTjiv5uJwlVYFpso_UwKO3euZvD2gND0YQ4A,8613
58
+ induscode/conductor/__init__.py,sha256=EArqr38M5nJB_-IcD5Tz29D4CzzCIc4AHlRcuAWBoCU,6322
59
+ induscode/conductor/catalog.py,sha256=hmQ7WS_mD6BZQ8v38BH5edcbz2DxIbFfRsB8vy9dOBk,11799
60
+ induscode/conductor/conductor.py,sha256=DN4EgSyQJMpYoy7gMipCUSi1rJpreJGnX4IXMNI-Xjc,42852
61
+ induscode/conductor/contract.py,sha256=fq7u3cFOPkVbtFfsPxUVlL0D6ABpLU2RVpegRgJR1qg,37913
62
+ induscode/conductor/matcher.py,sha256=c4cP94GTw2Xe2iv1-RXKhyiG73pB4vzUC3L3QrBYRXw,11062
63
+ induscode/conductor/serialize.py,sha256=tfR6qqP9CJk8j9QnJQ_43THKmf9TyTefqEkCK0F5TVM,23762
64
+ induscode/conductor/signal_hub.py,sha256=ibqC1yXd3LvVLasXBbpR5p6qFQnuHv9_oLuvNLsPq60,15936
65
+ induscode/conductor/skill_parse.py,sha256=BunMxUYYtOSngtPM8RvGWsUvH9A7RrqxrmLsnO4fIQM,10422
66
+ induscode/conductor/transcript_store.py,sha256=dIFRmR7rbGRf4jz2Z0RsulLUqqwB88fujRHRkHm8Las,17011
67
+ induscode/console/__init__.py,sha256=rvMz1uR9hOJcHv8mbY6iB9z9MgHTEp7viTW7gd2KY0o,6457
68
+ induscode/console/app.py,sha256=arRZIsLrqEDNXzJ2Y0e_41esMUCdeSH-9clEWbpgQjM,70080
69
+ induscode/console/contract.py,sha256=60nIT9CHAlN9iVg7yv2uERQIAyKrQRpUwjgFt-ppuec,28007
70
+ induscode/console/mount.py,sha256=3Q3OXJqzATTgxGV66VE4IUjPhJcsObOWEhmSG5uC_Bk,5860
71
+ induscode/console/reducer.py,sha256=mzpw9sPBFA359r7e1LItFkp6nKcuAXe176hCSVu-o4I,5848
72
+ induscode/console/resume_picker.py,sha256=_CBLlawSNsziXQ0MvkGJyqz5b0jSsh__UbiR8qb_9wo,6150
73
+ induscode/console/startup.py,sha256=u5-yb6jeOFNoGIkCm4KPHNKLh5tWGAF7-nttjhSI5Vo,16270
74
+ induscode/console/components/__init__.py,sha256=2IakwdMbgFeJbRq1QrCwn3sbUMLdVk7CRaC4nzzsUJk,2258
75
+ induscode/console/components/banner.py,sha256=nEqqfbYnoldr7-KrI2XiJ27um1mqvwRbCXIJJuajczg,20686
76
+ induscode/console/components/banner_sweep.py,sha256=8cKpSN3MOilerk-CI9ROFXf1kvlNdRki553vdXOfMkI,6833
77
+ induscode/console/components/emblem.py,sha256=xFfpntLIU6aeGXcEoZ0tMjBLXuZqxvWNHrLGQdybZTs,6896
78
+ induscode/console/components/status_bar.py,sha256=oErxQGAFzRyhb8Wwj8jAmjm_sjP7JEqhuRhb1GuOQlY,3703
79
+ induscode/console/input/__init__.py,sha256=mx82EgYTgG3f8rC9GcMcSwjJbJFGfGv5ayFdbQ7YGdI,3133
80
+ induscode/console/input/chord.py,sha256=3n9o-lz2icfQ-lRR8BtBJN_b-Urur_BfHKR9mqMLidg,7424
81
+ induscode/console/input/dir_reader.py,sha256=rzxoGsqE2NHIEzQPP97Gc9Un1r6bPsc1HQlPxrUF4ec,4245
82
+ induscode/console/input/intents.py,sha256=2avq1MGRaAcwC1DdIG5aYsmFkstRB26uEXFdu88SNxQ,10736
83
+ induscode/console/input/providers.py,sha256=n9kDhP46f4MEQ5NGalGMmMziXotbPcJ8vlZFSTrRVf4,17949
84
+ induscode/console/overlays/__init__.py,sha256=cN0DeXUvi1sQgd97WVn3Ww5jhCwTbcmE12NLXHZ02ZY,2552
85
+ induscode/console/overlays/auth.py,sha256=czKIrJl3_vRFCRECfeSbufMS8VkVkkhcLnai8AQ3B94,18249
86
+ induscode/console/overlays/pickers.py,sha256=h38x_jBiJcrmC6uNXr6xaYvBq3f7tFyio483PzrICE8,19512
87
+ induscode/console/overlays/router.py,sha256=7wnx5db88KuiUKW0fIJ535gQdDgTmPG2rOoDEFk0cSc,4772
88
+ induscode/console/overlays/sessions.py,sha256=o5mJnQ9p2sjJhiApcLC4k23eBv_S884QVCAglhCNXGs,8009
89
+ induscode/console/slash_commands/__init__.py,sha256=9smo2QpwjmOtqbCDEslFMGhFFJjSEoyrwmtWL6fWjvE,3105
90
+ induscode/console/slash_commands/builtins.py,sha256=GsnaAKXmOGek8Akg3Y1RKpzDWBHPgnaqMcNpRpfR8HA,9758
91
+ induscode/console/slash_commands/dynamic.py,sha256=d1SFkSXux32G7ea6Nep0DLZX65s7b-Cu9BbKW8sg43w,7862
92
+ induscode/console/slash_commands/integrations.py,sha256=PWhIjAQ19lLe_p6kYF_25QTwZAD4SgANLH-M6foPFB0,36813
93
+ induscode/console/slash_commands/transcript.py,sha256=qbd83kr2XX_IdxlIDg57nVBl5LgSgDqc9kbzVwtO940,14459
94
+ induscode/console/slash_commands/workbench.py,sha256=WThfannGvF7WMDKdP88ZZmPYR0zzKHM8L6N319FfT-A,15551
95
+ induscode/console/theme/__init__.py,sha256=FtcsoaR1nBoBT2M0b9-RHW_ah8SFetfymLWC55U4CDA,1492
96
+ induscode/console/theme/adapter.py,sha256=dkl4GcB76MPqnOl7w3zazqKpqSdcN7llsUy14XGLBzs,7794
97
+ induscode/console/theme/palette.py,sha256=wAxd1wDZGzq2T9BasPwoQNapcWEeNbknigKnHk_m6mo,4781
98
+ induscode/console/theme/resolve.py,sha256=FovRznwe4V-HgEyOEf4tAE_qu-zdirVy9Q753JXANlY,4755
99
+ induscode/console/theme/tokens.py,sha256=Y-3fQnFRdSesDH9vytN1gPGO3sLDvNHscGxMDcvzNk0,7919
100
+ induscode/console_slash/__init__.py,sha256=5qwCbxQI9KTqiAgpGZd-jwpZXlZeP2XYUqeSoVT6Nmo,3020
101
+ induscode/console_slash/contract.py,sha256=Z9nct6EjHYnKCem47awI5qPb4mPVEkKJHGAE1NrYNG8,7039
102
+ induscode/console_slash/registry.py,sha256=rj9T9z_yNIrWlayYR54wBLqYxuiIgx4HY5ICtHj12aM,5702
103
+ induscode/console_slash/resolve.py,sha256=QfmTVkAIZyG6x0Db4jjVSbjwLc7WOGxhVXEdRAQcsGI,7434
104
+ induscode/console_slash/shared.py,sha256=HXbRQfQbfIGnpXNgUvAupReZ8M5eynB9Z0_VNegrbSQ,6015
105
+ induscode/insight/__init__.py,sha256=qUO8GQIQn_P2EMGZD07FthiQxedG0XD5rhXrw4OVXTs,3852
106
+ induscode/insight/collector.py,sha256=JBNJjbVJwUnqqcQJztIHexZOUtMwVFpWb6Kf53J2eUc,2681
107
+ induscode/insight/replay.py,sha256=67IVZFD_HhZX1lQkSYCyY-MOwZEXEnVQrDrnujEE1yc,11316
108
+ induscode/insight/wrapper.py,sha256=RC-GOOPhgMaTHF8IwntJkHrmRiPx79vkX3DQt-8tMa0,42114
109
+ induscode/kit/__init__.py,sha256=209KRaLJdUEErHzZ6nx9wKpvyhKF9ArYs6YjBzO5UrE,2593
110
+ induscode/kit/clipboard_image.py,sha256=kzWq2lM6Go4KfPKTjIphSX6vM7UtYKI-2XwZGvy9JgI,7827
111
+ induscode/kit/external_editor.py,sha256=Hhuj9xeW5uK4c2p1MEAPsYRGzVNrxdrgxkB9CDKw2y0,4494
112
+ induscode/kit/image.py,sha256=p6GVPrxEmq0R1kPhWlHkOV2uEbt_aRYK76k__h1b2bg,7594
113
+ induscode/kit/shell.py,sha256=DtJeW4ZhBsFJuvNGXse-LS5Jcu_UBkZ1WszyMiM_8Ns,3560
114
+ induscode/kit/tool_fetch.py,sha256=c17GKoOszEYsfsVYM9ce0kJCSXsjJJXd4kcP9O4Hm-o,10952
115
+ induscode/launch/__init__.py,sha256=k6aB9EwzrqQTftaAfOoxIraKFrMIoN-dGeC72HnAa-A,5444
116
+ induscode/launch/catalog.py,sha256=9GjFusFpvMKk6Qv9jLNPhiqrv7uvUwqb6yNRpwPHpNk,10796
117
+ induscode/launch/contract.py,sha256=6yccXVxr4tm3eZuGuxdSuai7p5NRX5jbxVvPfZgTlBQ,22378
118
+ induscode/launch/credentials.py,sha256=Xk5eFU6ESFQLyTt-FJBSShWm8Z0fAsMcDgFpkJ3jObw,30913
119
+ induscode/launch/oauth.py,sha256=P-2Oulu3Cb1G8h8p7TlWgPFH3U38fJEFU9wnyRG4Lpk,32241
120
+ induscode/launch/packages.py,sha256=JEJ3u6YIuLCRRtTDic_4rGAL0FLpux70xf91WKNMXxg,11074
121
+ induscode/launch/pickers.py,sha256=xHExyLVudzp6XD4dCxZue6UkRIvfJU4U3_eRlxK3UBA,10747
122
+ induscode/launch/invocation/__init__.py,sha256=cRxiSBp6J5xPUFQ2ZbSccTZSsKUZsFqKNhOxUIlt69c,1399
123
+ induscode/launch/invocation/attachments.py,sha256=TQPcDxIxjMFY8RVDJYMS5Y6rSNyZIu2yCcTGRAnZFao,9400
124
+ induscode/launch/invocation/flags.py,sha256=wfZJt94WkYISmxhu6ZEuYaSrFLGRceojKoP-1MtJ1P4,7170
125
+ induscode/launch/invocation/read.py,sha256=giI6lpYT5BeZP46F7CYUnXgBi7c_NBrLXoPdMxh4LqE,13374
126
+ induscode/launch/invocation/usage.py,sha256=jdtHD7mbYEivSDc83LNuM-b2gMyePmiHh1njp4-meBE,4025
127
+ induscode/runtime_bridge/__init__.py,sha256=d_Z9Twvjtx6WUsSieLR9bL4cxhnRWAo-E9vVvScqSQM,4185
128
+ induscode/runtime_bridge/broker.py,sha256=R9FbtmOxcHs1as65r9r9afUUcPyznKKfgWzeYvlDrJk,15879
129
+ induscode/runtime_bridge/contract.py,sha256=F25sTx_Bzh0Jpfy2rd-khTl6B7bSNmzmK6fjif3SEyk,29731
130
+ induscode/runtime_bridge/sink.py,sha256=6yOm2FGRMKWqgjqRwnTgJyFFWI7iOtPGpH16bOqfkeY,14091
131
+ induscode/runtime_bridge/bridges/__init__.py,sha256=Mi2oDu8_PguBXX2GkvHxr7U7TyONXzxM3W-oetyztLM,1847
132
+ induscode/runtime_bridge/bridges/_drive.py,sha256=qKuytV87tdvY-evcHs8MHDw6ktHXBVt1cXZoIthQCOo,9820
133
+ induscode/runtime_bridge/bridges/builtins.py,sha256=B8SSEesTFJ-z5E8QbmJHN8Q4F4NC5gGu11-RLoqjsWU,6900
134
+ induscode/runtime_bridge/bridges/claude_cli.py,sha256=Z8HKfe_OOUiU31vF-LETnj-iNOLjG27goXPDbFow9_k,7391
135
+ induscode/runtime_bridge/bridges/codex_cli.py,sha256=W7fkJ-ulIBRCc7XLUP0LnuevdMhePf1YOR_41DLmTyc,6965
136
+ induscode/runtime_bridge/bridges/indusagi_cli.py,sha256=Rwsi6H5vpa7iqQ1REaYT4ioA-BsE-C0j8u7-ef08AkQ,7774
137
+ induscode/sessions/__init__.py,sha256=Emp6MDQrjMuYDTm2QZvUzFvxBY-lrKOg8bvPjlpMJYY,930
138
+ induscode/sessions/contract.py,sha256=AvSkTRO3UCyBRiHqQUkfEvO6GAznByixQ2VWGdzon-8,4565
139
+ induscode/sessions/library.py,sha256=zXqXJqrkCWB7LDhkmgU6sHgY0Jm2lB0oyIxwyzJeKAs,13941
140
+ induscode/settings/__init__.py,sha256=fjmKigTv28b6qsUl8hfkWz-iuNo7mtL6jqlPklyUGu4,1240
141
+ induscode/settings/contract.py,sha256=g7bX6x8D0ep0Be0DmZbGlUgjCFotE6hjPt8aLdVI2Ck,13008
142
+ induscode/settings/manager.py,sha256=aTVB3MpOSlQni7wyBmC5BQXXA0vN7r7nhu2trD9QF5Q,10523
143
+ induscode/transcript_export/__init__.py,sha256=yH7Mco0dQAvXbyYhCT5JLxDUrDgj9LRBbcHfaXkW_O4,2902
144
+ induscode/transcript_export/contract.py,sha256=frEMl0k_WWSrRXMFGwcyWI-5VQP5hVl_ybjehP_ly5M,19577
145
+ induscode/transcript_export/publish.py,sha256=SXHdQELgnp1iNgTHarOoVMmsxc0Y8sdrtpNbUVkaj7k,17686
146
+ induscode/transcript_export/sgr.py,sha256=rn06mJnhvulv9yOChWCEeQd08v0cIKp5ixkRF2kfKd8,20071
147
+ induscode/transcript_export/template.py,sha256=o1gQIys2MHiaP3i_mO_ehcq_2ZPCZ8G-vD_lA7r-rN4,10676
148
+ induscode/transcript_export/theme_bridge.py,sha256=jzSeEwVmX4WHQb1Gwxr80Ti0Xh3jnGUCChvWcZSJQ-c,12031
149
+ induscode/window_budget/__init__.py,sha256=Ik9jCAEkY9hwH_-9oTjFRqntDlqDKozASIybx_NgAic,2022
150
+ induscode/window_budget/condenser.py,sha256=Ag7Z4pyQA2MDrV4xjz0qPg5fRhETTxbmbrVBHsB8gr0,7504
151
+ induscode/window_budget/contract.py,sha256=4z21d6fT6zMQS34PhDNJaG2RqpGTkzdGwk6orA9SWPE,13648
152
+ induscode/window_budget/budget/__init__.py,sha256=7zMpg_kWRgvZyVEfqpCEWzQSSLSLdVjKIUDH-8UwCMM,870
153
+ induscode/window_budget/budget/estimate.py,sha256=OHtc5whXpnuEYiddLH5Mf09JsfXcJabuyaq0Jw2kJWU,11159
154
+ induscode/window_budget/budget/gate.py,sha256=gpzDCJPW457GXsacOls92-cLijqgcn-7Gmr3Une-D0o,2290
155
+ induscode/window_budget/budget/slice.py,sha256=QyHetJE9Yr8ss_35hHpK0cA_-QVIR84c9bSYYmHd0CY,5939
156
+ induscode/window_budget/summarize/__init__.py,sha256=-ijTEzLCJEbCYAGAWcg3OikbAw_1y8EdXxd7scKk7qU,896
157
+ induscode/window_budget/summarize/condense.py,sha256=wuLVdOn5Ex8cNSoHa4rJhgJtjwukrcOE1sUrosSZLZc,8253
158
+ induscode/window_budget/summarize/prompt.py,sha256=kOZt7bMSyT77qyl7OMDMjGXPLK6XnUQ-1fZuUiL2JEk,9727
159
+ induscode/workspace/__init__.py,sha256=qVgaSIwo4veqtU4-sIz3KPOIcmS3gxtrI2Sx0Qy0eDc,703
160
+ induscode/workspace/brand.py,sha256=vFIcr7ffHTkvRVIdHz8En4f5QDmb13_an6SQOIT9I4U,3869
161
+ induscode/workspace/locator.py,sha256=yqQLG_cA6pbnFUhqGWTlzhkfjkWFnZHXwmy85rJ-tIo,10905
162
+ induscode-0.1.0.dist-info/METADATA,sha256=lIeBrurab--aRZ4Dvq__aEP13EUoTMj_QYrflgD4dvU,3941
163
+ induscode-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
164
+ induscode-0.1.0.dist-info/entry_points.txt,sha256=7-bgIhNbDyS0OVaJmu0a-vimq7SFKGSSF0sY7jzEBas,79
165
+ induscode-0.1.0.dist-info/licenses/CREDITS.md,sha256=e5pVUNsQyXkHVNI_icg3LvaXdhLyu8Hmikfdg80OjgQ,1115
166
+ induscode-0.1.0.dist-info/licenses/NOTICE,sha256=YXK3ziYV1gVLlipo2e9q8Vl6wlrDssRykpa9-0o3Tuc,286
167
+ induscode-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ induscode = induscode.entry:run
3
+ pindus = induscode.entry:run
@@ -0,0 +1,22 @@
1
+ # Credits
2
+
3
+ The **indusagi coding agent (Python rebuild, `induscode`)** is an independent implementation,
4
+ designed and written from scratch against a behavioral specification and the public API of the
5
+ `indusagi` framework — not by copying source from any prior codebase. It reuses no third-party
6
+ application source code.
7
+
8
+ ## indusagi framework
9
+
10
+ The agent runs entirely on the **indusagi** framework (Python rebuild, installed from
11
+ `../indusagi-python-rebuild`), which provides the LLM API abstraction, agent core, Textual-based
12
+ terminal-UI primitives, MCP client, and observability. The framework is itself an independent
13
+ implementation and ships its own `CREDITS.md` / `NOTICE`.
14
+
15
+ ## Third-party runtime dependencies
16
+
17
+ Standard open-source libraries used at runtime, each under its own license:
18
+ `markdown-it-py` (transcript-export markdown rendering), `pygments` (transcript-export syntax
19
+ highlighting), `python-ulid` (bridge-ledger keys), plus the framework's `[mcp,tui]` extras
20
+ (`mcp`, `textual`). Dev/test: `pytest`, `pytest-asyncio`, `build`.
21
+
22
+ See `NOTICE` for the notice that must travel with redistributions.
@@ -0,0 +1,7 @@
1
+ induscode — indusagi coding agent (Python rebuild)
2
+ Copyright (c) 2026 indusagi
3
+
4
+ This product is an independent implementation, designed and written from scratch.
5
+ It reuses no third-party application source code.
6
+
7
+ This agent runs on the indusagi framework, which ships its own NOTICE.